ISWIX, LLC View Christopher Painter's profile on LinkedIn profile for Christopher Painter at Stack Overflow, Q&A for professional and enthusiast programmers

Friday, May 23, 2008

How DTF is going to help me become a better .NET Developer

I've been doing .NET for a couple years now, but I mostly use it for small tools/automation development. Things like the occasional MSBuild or NAnt task here and there, a SOAP web service that encapsulates a REST web service, or perhaps a custom action that consumes a SOAP web service. The only application work I've ever done in C# was a client/server program that configured a existing system. The application used the ADO.NET 2.0 Factory model, had a framework consisting of a base UI and several application services. I did it pretty cleanly but at the end of the day it was just a bunch of look a like modules using DataGrids. Big deal

So here I am playing with DTF and I'm going back to various CAs that I've written over the years and seeing how they could be done better in C# The first story that I decided to look at is dynamically updating ListBoxes at install time.

I started with a simple statement like this:

session.Database.OpenView("INSERT INTO `ListBox` (`Property`, `Order`, `Value`, `Text`) VALUES ('TESTPROP', 1, '1', 'One') TEMPORARY").Execute();

This is problematic because if you get any of the SQL statement wrong everything will blow up. Trust me, trying to do this in VBScript really sucks big time. There is a reason Script CAs are said to be evil and it’s not just because of virus scanners.

So then I noticed that the DTF Database object has a TableCollection of TableInfo objects that each have built in SqlStatements strings. So I tweaked it up a little:

Database db = session.Database;
string sqlInsertTemp = db.Tables["ListBox"].SqlInsertString + " TEMPORARY";
View view = db.OpenView(sqlInsertTemp );
view.Execute( new Record( new object[] { "TESTPROP", 1, "1", "One" } ));

This is a little bit better but it doesn’t solve a more fundamental problem. I’m trying to manage a list of items, why should I have to care about how to get the data stored in MSI? It started to become obvious a bit of abstraction was needed. The result is creating and invoking a custom class that looks more like this:

ListBox listBox = new ListBox(session.Database, "TESTPROP");
foreach (Process proc in Process.GetProcesses())
listBox.AddToEnd(new ListBoxItem(proc.Id.ToString(), proc.ProcessName));

Now I'm just instantiating a ListBox class and during it's constructor setting up database and property collection association. I've also defined a ListBoxItem class that strongly types the Value and Text fields. Finally I have an AddToEnd method that takes a new listBoxItem.

This class is by no means complete or bug free. I'll probably want to do things implement capabilities like Add, Insert, Move, Remove, Sort, IEnumerable etcetera. Then I'll probably want to go on to other common stories such as making it easier/more generic to build data driven custom actions that change system state. Serializing/Deserializing CustomActionData. Building ICEs. And so on. Basically the plumbing details that many CAs have to do but really aren’t relevant to the problem trying to be solved.

Yes, I know… these are OO principals that I've learned over the years. I can sit down with a developer and read what he's doing and talk about it but frankly I've never taken the time to hone these skills because it was orthoganal to the problem of writing setup declaratively. After all, when your life is breathing MSI it's kind of hard to get worked up over things like NHibernate vs EF debates. But now that C# is my language of choice for custom actions, it's time to catch up on things I should have mastered years ago.

PS- Does anyone have any suggestions on good books to read? Please, nothing too heavy... go easy on me.


  1. Good general programming practice: Pragmatic Programmer - Andy Hunt et al.

    OOPy goodness:
    Head first design patterns

    Thorough details on programming practice: Code Complete

  2. haha - it sounds like you need to use LINQ to MSI :)

  3. LINQ to MSI looks very promising except for 2 problems:

    Adding a dependency of 3.5 instead of 2.0. That's a big leap.

    DTF LINQ to MSI isn't ready for prime time.

    For the time being, I see it as probably a good thing to learn for tools and build automation, but install time code should probably stay away.

  4. Chris,
    You aren't exactly a C# beginner, but this book covers a lot of OO concepts as well:

    The review on Slashdot of this book was pretty favorable as well:

    ...and you know how they can be with MSFT technologies.