Growing up with C++, I’ve always expected software to have a strong domain model. If I had grown up with ADO Recordsets or ADO.NET DataSets, perhaps I’d have a different perspective on software, but my initial reaction to the Recordset was bewilderment at an object chocked full of data and no behaviors. I can see both sides of the coin now, and I think both approaches have their advantages in different scenarios. I still prefer the domain model. I do wonder how these models will evolve over the next few years as technologies like DLINQ arrive and continue the push towards abstracting away the database as a minor detail.
Here is some code that works wonderfully well.
Well, the code works wonderfully well as long as SomeOtherObject is in the same process. As soon as SomeOtherObject becomes a proxy to a remote object, end-users feel the pain of an O(N2) operation carried out by traversing protocol stacks, security boundaries, and network routers. Thus, the SOA tenet arose that boundaries are explicit, and location transparency is a pipedream.
If boundaries are explicit, perhaps database boundaries should be explicit as well. Even though database servers are typically on our side of the firewall, if SomeObject.UpdateValue() is a database roundtrip, the application performance is in a world of hurt.
I’m wondering how to avoid this problem before an application gets into load testing. Static code analysis? Perhaps require the method to be invoked with a different operator? (SomeObject->UpdateValue())? I think -> is a nice indication that the call could possible travel out of process….
Perhaps I'm thinking crazy, or perhaps some dark part of me misses C++ syntax.
Saturday was a beautiful, sunny day in Washington D.C. Unfortunately, I spent the morning working in the infamous Watergate building, but did get a chance to navigate through the pedestrian traffic at noon and meet Sir Wally McClure for lunch.
Wally is a genuinely funny, smart, and friendly guy. His personality shines through during his ASP.NET Podcast, and makes the show an enjoyable listen. Wally asked me to do a quick interview, and I obliged. He posted the show late Sunday evening. I’ve been dubbed the godfather of the “world needs more Wally” meme that is all the rage.
Let’s say I want the user to select their favorite theme for my application. I can make a list of available themes in a DropDownList control.
I know I must set the Theme property before or during the page’s PreInit event.
What’s wrong with the following code?
The above code throws a null reference exception. PreInit fires before the page instantiates its controls, so _themeList is null (Nothing). I can’t use the _themeList control, but I can go directly to the Request.Form collection. The DropDownList (an HTML select) will post its new value into the form collection.
What could go wrong with this code?
Hint: this code will work for many webforms, but not if you are using a master page.
The problem with asking for “_themeList” is that “_themeList” is a server side ID. The browser will submit the form with a unique client side ID. If the DropDownList ends up inside an INamingContainer, the UniqueID property is not the same as the ID property (see my FindControl article for more on INamingContainer). If the DropDownList is on a master page, the UniqueID might look like “ctl00$_themeList”. If the DropDownList is inside a ContentPlaceHolder control, the UniqueID might look like "ctl00$ContentPlaceHolder1$_themeList" .
There are many ways to solve the problem. One solution might be a brute force search of the form collection for a key ending with “_themeList”. Another approach is to stash the list's UniqueID into a hidden form field.
I’m sure you can think of some other elegant ways to solve the problem. The trick, as always, is finding out what the problem really is.
One aspect of the default ASP.NET 2.0 project model I really like is how the code-beside file and the declarative markup file compile at the same time.
The compilation model produces a comfortable coupling between the declarative markup and the class in the code-beside file. This is ‘vertical coupling’. The ASP.NET runtime can generate strongly typed properties for the code-beside class via the magic of partial classes.
Web Application Projects for Visual Studio 2005 delivers the ASP.NET 1.1 code-behind model for ASP.NET 2.0. Many applications will have an easier migration path to 2.0 with WAP.
One problem I watch for with the old compilation model is unwanted coupling between types in the code-behind files. This is ‘horizontal coupling’. Instead of using a layer of indirection, like an interface, base class, delegate, or event, types in the code-behind files can reference each other directly and produce brittle code.
Horizontal coupling is bad. Vertical coupling is good.
I have three sessions to present at VSLive! Toronto (April 24 – April 27 - Toronto Congress Center). I hope to see you there.
I keep meaning to upload the source code to ShowMeLife. ShowMeLife is an application I’ve used in a couple user group talks to demonstrate Visual Studio 2005 features, like debugging visualizers. A few people have asked for the source.
ShowMeLife is a Windows application that runs in full screen mode. The app displays images from Flickr. I can type in the tags I want the images to have, and the app looks for the photos using flickr.photos.search.
You’ll need a Flickr API key to run the app. The API key goes into the app.config file.
I wrote Flickr as a quick and dirty way to look around the world. Whenever I read stories about Sydney, or Venice, or mardi gras (or any place / event), I like to watch a slideshow of Flickr photos and see what other people are doing in the world.
Lately, I’ve been spending my evenings with Windows Workflow. Hello, Workflow is a new, feature length introduction to WinWF.
The primary building block in Windows Workflow is the activity. All activities in WinWF derive from an Activity base class. Activities compose the steps, or tasks in a workflow. We can arrange activities into a hierarchy and feed the activities to the workflow engine as instructions to execute. The activities can direct workflows involving both software and humans.