I’m not sure where the term “connascence of algorithm” originated from. The first place I saw the phrase was in the 1996 edition of “What Every Programmer Should Know About Object-Oriented Design”. The book contains a great deal of practical advice, although its terminology and notations are well out of fashion 10 years later.
Two components share a connascence of algorithm when they both rely on a specific algorithm to work properly. If I change the algorithm in one component, the other component will need to adjust. In today’s terms, we’d say the components are tightly coupled in a bad way. The examples that spring to mind are all about relying on how a particular piece of software will order its results. (These examples might not fit the author’s precise definition, but are examples of coupling too closely with what is happening behind the curtain of encapsulation).
Relying on the implicit ordering of rows returned by a SQL SELECT statement is dangerous. The ordering will depend on the execution plan the database server generates to fulfill the query, and thus depend on the current indexes and possibly the server’s runtime environment. Appending an ORDER BY clause solves the problem by giving the database explicit instructions on how to order the records.
Here is a piece of code that believes the GetFiles method will always order file information in alphabetical order:
The code might work for me most of the time, even though the documentation for GetFiles makes no mention or guarantee on how it will order the FileInfo array. If I were to place a wager on the implementation of the GetFiles method, I’d wager it uses the Win32 FindFirstFile / FindNextFile APIs. The Win32 documentation for FindNextFile specifically mentions:
The order in which this function returns the file names is dependent on the file system type. With the NTFS file system and CDFS file systems, the names are returned in alphabetical order. With FAT file systems, the names are returned in the order the files were written to the disk, which may or may not be in alphabetical order.
Indeed, if I try GetFiles on an SD Card with a FAT filesystem, then the resulting FileInfo array contains files in the order they were written to the card. Because of this (and remember there is also a new transactional file system on the horizon), I’d never rely on the ordering of objects returned by GetFiles.
Finally, it’s interesting that Microsoft decided to introduce some randomization in reflection methods like GetFields:
The GetFields method does not return fields in a particular order, such as alphabetical or declaration order. Your code must not depend on the order in which fields are returned, because that order can vary.
I wonder what sort of dangerous code (and how much dangerous code) Microsoft was seeing to go to this amount of trouble.
Windows Workflow is a part of the next-generation APIs from Microsoft collectively known as WinFX. WinFX also includes Windows Communication Foundation and Windows Presentation Foundation. From 50,000 feet away, WinWF consists of a visual workflow designer that plugs into Visual Studio, and a runtime to execute workflow instances.
Here are some WinWF blogs I read:
Paul Andrew (technical PM)
Jon Flanders (a great collection of Biztalk and Workflow posts)
Dharma Shukla (architect)
Bayer White
Thomas Restrepro (covers a variety, including Biztalk and WinWF)
Moustafa Khalil (PM)
Dennis Pilarinos (PM)
WinWF also has a dedicated site: windowsworkflow.net, which downloads, samples, custom activities, and more.
Of course I like the following two articles:
Hello, Workflow
Authoring Workflows
If you know of some other WinWF resources, please share!
Web site projects in Visual Studio 2005 give us exactly one code-beside file per web form. We specify the name of the file with the CodeFile attribute in the form’s @ Page directive. There can be no other file – a web form and its code-beside file maintain a monogamous relationship.
But wait! Partial classes in C# and Visual Basic say I can:
“…split the definition of a class or a struct, or an interface over two or more source files. Each source file contains a section of the class definition, and all parts are combined when the application is compiled.”
True, true, but there is no capability to specify multiple files with the CodeFile attribute, and the CodeFile attribute is the only piece of information the ASP.NET runtime has available to know what else it needs to compile with the web form (each web form can compile into a distinct assembly). I can’t drop a partial class definition for the web form into App_Code, either, because App_Code compiles into a separate assembly, and partial class definitions cannot span multiple assemblies.
Let’s approach the problem from a different angle: why would we want a web form’s code-behind to span multiple files? Is the class hard to manage because it has too much code inside? That scenario sounds like an architectural problem that can’t be solved with the partial keyword. Do we want to cleanly separate event handlers from virtual overrides? Perhaps a #region would do a better job.
Web Application Projects are a different matter. WAP allows multiple partial class definitions. In fact, WAP itself will create two source code files for each web form. One file is for human generated code, and the other file is for designer generated code. This scenario is an ideal candidate for partial classes. With WAP, Visual Studio compiles all of the .cs/.vb code-behind files at once, and into a single assembly. WAP allows the compiler to merge partial class definitions.
Blame the Romans: A Play in Two Acts
By S. Allen
Act I
[It is late in the afternoon on December 21, 2005. Two software developers, Ron and Barbara, pair program in front of a dual LCD display].
Barbara: Your fiscal year calculations are still *%#@ed!.
Ron: No, no, look. It says that March 2004 is in the fourth fiscal quarter of two thousand three. That’s right!
Barbara: I thought the finance guy said March 2004 is in the fourth fiscal quarter of two thousand and four.
Ron: Wait, when you say 2004, do you mean the fiscal year starting in 2003 and ending in 2004?
[Barbara places her index fingers on her temples, and begins to rub slowly. During these pair programming sessions, she secretly yearns to massage Ron’s temples, too. Instead of using her fingers, though, she’d prefer to use the sharp end of an Eskimo harpoon.]
Barbara: In any case, I thought they decided to display the calendar quarter, and the fiscal year.
Ron: That wouldn’t make any sense! We’ve changed this code 1000 times now! Fiscal years with calendar quarters! Fiscal quarters with calendar years! Let’s go ask the finance guys again!
Barbara: We can’t. They all left early for the office holiday party.
Ron: No! You mean we are stuck here changing this and finance is out boozing it up?
Barbara: Yep.
Ron: I’d like to meet the person who started this fiscal year thing and club him with a calculator. Do you realize how much confusion a fiscal year creates?
[Barbara still has her eyes closed, and doesn’t answer. Her mind’s eye pictures an enormous calculator falling from above, and crushing Ron’s skull. She smiles].
Ron: What are you so happy about?
[Lights fade. Curtain closes].
Act II
[It is late in the afternoon of December 21, 312 AD. Two bookkeepers, Docilus and Silius, are hunched over a table covered with wax tablets and scrolls.]
Silius: Once again, Docilus, we are finishing the yearend books while the orgies of Saturnalia rage around us.
Docilus: It is a burden we carry at the same time every year, my friend. The empire’s books must be in balance.
Silius: Indeed, but so must our spirits! My spirit is running a deficit in food, wine, and debauchery!
[Silius clears the table in front of him with a sweeping gesture, and stands.]
Silius: I have an idea, my friend!
Docilus: Do tell!
Silius: Imagine if the year didn’t end in December, but in March. Then we could also be in the streets and vomiting on the sandals of our fellow countrymen.
Docilus: This is no idea you carry in your head, my friend. It is a delusion.
Silius: No, no, Docilus. We must tally numbers for a total of 365 days, but which 365 days? I say we make a fiscal year, which runs from April to March.
Docilus: Brilliant! When do we start?
Silius: You know the old latin saying: “carpe diem”. These books can wait for 3 more months!
Docilus: Let’s party!
[Docilus rises from the table, and the two bookkeepers exit stage left. The sounds of merriment begin to echo from all directions. The abacus slips off the table leg, and breaks in two as it hits the ground.]
[Blackout.]
[Curtain falls.]
I’m a heavy user of RDP (Remote Desktop, a.k.a. Terminal Services). I don’t remember how I ever got any work done before this technology existed. What follows are some miscellaneous tips.
To login to the console session on a Windows 2003 machine, start the Remote Desktop application from the command line with /console. You can also shadow a console session, so a person physically at the machine can interact with the session, too. See: How to Connect to and Shadow the Console Session with Windows Server 2003 Terminal Services. There is also an interesting but Rube Goldbergian trick I’ve never tried: How To Shadow a Remote Desktop Session in Windows XP Professional.
If you save connection settings in an .rdp file, you can add “connect to console:i:1” to make the console session preference permanent. This page extensively documents other .rdp file parameters.
When RDP misbehaves, qwinsta and rwinsta are available for remote management of sessions. Scott Forsyth has a nice write-up on how to use these tools: Managing Terminal Services Sessions Remotely.
When I connect to a Windows XP machine using RDP, the system replaces the “Turn Off Computer” button in the start menu with “Disconnect”. If I want to remotely power down the machine or reboot, I turn to the command line utility TSSHUTDN.
To connect to a Windows machine from a *nix machine I’ve used rdesktop successfully.
When paranoid, I change the default listening port for RDP on some of my machines.
Finally, some shortcut keys I commonly use:
ALT + PAGE UP replaces ALT+TAB to “tab” through running applications in the RDP window.
CTRL + ALT + + (numeric keypad plus) takes a screen print of the remote desktop (just like using PrintScrn on a local computer).
CTRL + ALT + - (numeric keypad minus) takes a screen print of the active window inside the RDP window (just like using ALT+PrintScrn on the desktop).
Any tips you want to share?
… because it kept growing and growing. I was determined to finish this off tonight before falling asleep (always dangerous).
Master Pages: Tips, Tricks, and Traps is an article covering all the inconspicuous points of developing and designing with master pages. Everything from URL rebasing, the munging of client side identifiers, using FindControl, nesting, and even tips for cross page posting.
As always, I appreciate any feedback. I’m particularly interested to know if the reader finds the intermingling of Visual Basic and C# samples to be useful, or just a terrible idea.
Now to sleep, perchance to dream...
I’m working on an article full of tips and tricks for master pages. The article will be online soon, but I wanted to throw out one tip as a preview and get some feedback.
A master page typically includes the single HTML <head> tag for a page. This approach gives every content page a <head>, but presents problems when a content page wants to add additional tags inside head, like <meta> and <link>, for example. The tags might be specific to the content page, and we wouldn’t want to include them in the .master for every page.
As long as the <head> tag has a runat=”server” attribute defined, a content page can programmatically add to <head>. The recommended ASP.NET approach to add a <link> tag, for example, is to use the following code:
For more Header examples, see Sue’s edreams.org post.
Milan thinks the Header API is lacking functionality, and I’d agree. My frustration level rises whenever I have to modify the <head> tag programmatically, so for kicks, I tried putting a ContentPlaceHolder inside of the <head> tag:
Then in a web form I used a Content control to add additional scripts and metadata inside of <head>:
Lo and behold, this works and feels natural. No more Header.Controls.BlecktyBlah!
Except, there is a catch....
The validation engine in the Visual Studio 2005 IDE doesn’t believe a ContentPlaceHolder control belongs inside of <head>, so it raises a validation error. This is just a validation error, so the application still compiles, and still executes, but it’s an irritating validation error nonetheless, and one we can’t get rid of unless we disable all HTML validation. Ugh.
Update: The rest of this post was a late night ramble full of rubbish that didn't produce the intended result.
Move along now, nothing to see here.
To appease the deities of validation, I can resort to a hack. I can move the master's ContentPlaceHolder for <head> related goo inside of the <form> tag. This avoids validation error flags, and feels justifiable because all the webforms look more maintainable. The master page only needs to swap the ContentPlaceHolder into the Header controls collection during the page lifecycle.
In other words, with a master page like this:
All we need is some code behind the master page, or in a master page base class like so:
The .aspx webforms can add to <head> declaratively, using a Content control.
What do you think? Good? Bad? Dirty?