Friday, November 28, 2008

Using the Windsor Fluent Interface and an XML Configuration file

The framework we've built uses the Windsor container quite heavily. Users of the framework supplied a dependencies.config file in their application that had a bunch of boilerplate stuff in it for our framework (facilities, framework component registrations, etc.) along with the registration for all of their components.

Boilerplate anything bothers me and boilerplate XML even more so. I wanted a nice programmatic way for the users to say "configure the framework" in their application as a substitute for all the XML. What this meant, however, was that I now needed to configure the container 2 ways: programmatically using the fluent interface available in the trunk, and using a config file.

My first attempt went something like this:

WindsorContainer c = new WindsorContainer("dependencies.config");
c.Register(Component.For<IFrameworkThing>().ImplementedBy<FrameworkThing>();
c.AddFacility<RequiredFacility>();


While that looks ok, the order things happened bit me. Our facility (RequiredFacility in this example) happens to listen to the ComponentModelCreated event raised by the Kernel when a component is added to add a ComponentActivator (more specifics here). Since the XML gets processed (and all the components in it get added) before our facility is added, we miss the events we need to handle.

I needed a way to have my facility in place before adding in the stuff in the config. Due to a lack of documentation and the castle forums guys taking Thanksgiving off, I went down a bunch of fruitless avenues. I looked into loading the framework stuff into a parent container and then creating a child container with

WindsorContainer child =
new WindsorContainer(
parentContainerAlreadyConfigured,
"dependencies.config");


but the parent doesn't get the ComponentModelCreated events from the child.

Eventually I ended up with the following solution. This came from using Reflector (the best documentation for Castle I've found to date) and mimicking what the WindsorContainer constructor itself does.


WindsorContainer container = new WindsorContainer();
container.AddFacility<RequiredFacility>();
//other programmatic config
XmlInterpreter configInterpreter =
new XmlInterpreter("dependencies.config");
configInterpreter.ProcessResource(
configInterpreter.Source,
container.Kernel.ConfigurationStore);
container.Installer.SetUp(
container,
container.Kernel.ConfigurationStore);



The API seems a bit ugly, but it works. I get all the events I need and the users of the framework don't have to deal with any more boilerplate Windsor configuration.

Update: It turns out you can replace all the XmlInterpreter stuff with this:

container.Install(
Configuration.FromXmlFile("dependencies.config"));

This does the same stuff, only it looks a lot nicer.

Friday, October 31, 2008

ASP.NET MVC and form editing scenarios

I'm a big fan of the new ASP.NET MVC framework and I've begun using it on several projects I'm delivering. Though each preview gets better and better, there are still a few scenarios that could work more smoothly. One of these is a normal form edit/post situation where the user types data into a form and posts it to a different action.

For example, the user browsers to Customers/Edit?id=1 and gets the Edit view. When submitting the form, the form posts to Customers/Update, which redirects back to Customers/List on success.

ScottGu's blog (and others') have examples for this, but most rely on a simple set of data used for the edit screen. ScottGu's example approach involves catching any exceptions during update and then re-rendering the Edit view. There are a few problems with this approach. The first is that the Url now shows Customers/Update and not Customers/Edit (so the same screen has different Urls). The second issue arises when your Edit view needs more than ViewData.Model to display. Suppose the Customer object has a Status property that you want to pick from a dropdown. To make this work, the Edit action would set ViewData["Statuses"] to the list of allowable statuses. Now, in order for Update to render the Edit view, we'd have to also load up Statuses. Now we're loading Statuses into ViewData in two places, the Edit action and the Update action.

Because of these issues, we've taken a different approach. Inside our base controller we override OnActionExecuted and look for exceptions. If an exception happened, we capture the ModelState and store it in TempData. We then redirect back to where we came from. If no exception happened and our TempData has ModelState stored in it from an invalid form attempt, we restore it.

Conceptually it's pretty simple, and it mostly works with the current beta release. It solves the two issues we had in that the Edit action is the only place the data for the Edit view is populated and since we redirect the Url is always correct.

There are still a few minor issues. One is a bug I found in DropDownList where it doesn't look at the Model to find the selected value. It is documented on CodePlex here..

I've posted a sample solution that uses this technique here. It's just the default MVC app with a new tab added to the page.

Our real application does a lot more than this, including hiding all the unit of work logic and automatically committing if there were no errors, as well as integrating a validation framework based on Castle.Components.Validator and jQuery. The extensibility of the MVC made adding all this stuff pretty easy and clean.

Saturday, September 13, 2008

C# mod operator (%) and negative numbers

The C# mod operator, %, takes the sign of the dividend as the sign of the result. Simply, this means that -1 % 3 is -1, and not 2 as I was expecting. Apparently every language I've ever programmed professionally in behaves the same as C#, so I'm surprised I never noticed it before. Of the other 2 languages I have handy, F# behaves just like C#, while Ruby gives me the result I expected.

A more comprehensive list can be found at Wikipedia.

This came up while trying to learn some WPF. I have a main window and a bunch of child windows that I want to cycle through with ctrl-tab. When I went to add cycling backwards with ctrl-shift-tab I was rewarded with a nice ArgumentOutOfRangeException.

Tuesday, July 01, 2008

NUnit within Visual Studio

My current client is not licensed for TFS, so we're going with NUnit for unit testing. Rather than pay actual money for TestDriven.net, we're using NUnitForVS, a nice free codeplex tool that integrates NUnit with all the unit testing infrastructure present in Visual Studio 2008 Professional and Team Editions.

It was a bit flaky at first, but a recent release has fixed all the non-trivial problems.

Check it out here.

Tuesday, June 10, 2008

Windsor and Linq DataContexts

For one of the systems I built I needed to use the Windsor container to resolve instances of a Linq DataContext. The DataContext was created using the standard Linq dbml designer. Using standard Windsor stuff, the configuration should look something like this:

<properties>
<connectionString>
Data Source=server;
Initial Catalog=Sample;
Integrated Security=True
</connectionString>
</properties>

...

<component
id="datacontext"
service="Sample.SampleDataContext, Sample"
type="Sample.SampleDataContext, Sample"
lifestyle="transient">
<parameters>
<connection>#{connectionString}</connection>
</parameters>
</component>

Easy, right? Unfortunately if you try to run this and do container.Resolve<SampleDataContext>(); you'll get an error like: "Key invalid for parameter connection." It turns out that what is happening is that Windsor doesn't know which Constructor to use. The generated DataContext has 2 single parameter constructors, one that takes a string named "connection", and the other that takes an IDbConnection named "connection". I think what happens is that the container tries to convert the property to an IDbConnection and it fails.

What we need to do is change the way the constructor is chosen. One simple way is just to add another constructor to your DataContext with a dummy ignored parameter. Like this:

public SampleDataContext(string connection, int ignoreThis)

If you then add <ignoreThis>5</ignoreThis> to the parameters section in the config then Windsor will find your new constructor and everything will work. This, however, is ugly.

A better way is to create a Facility. What we're going to do is assume that all our DataContexts will follow the same pattern, i.e., that we always want to use the constructor that takes a single string parameter.

First, we create a facility that inherits from Castle.MicroKernel.Facilities.AbstractFacility. We want to replace the default ComponentActivator, so we'll need to get ahold of the ComponentModel when it's created. We can override Init like this:

protected override void Init()
{
Kernel.ComponentModelCreated +=
(model) =>
{
if (typeof(System.Data.Linq.DataContext)
.IsAssignableFrom(model.Implementation))
{
model.CustomComponentActivator = typeof(CustomActivator);
}
};
}

Notice we're only setting a custom activator for classes that inherit from DataContext. Now all that's left is to implement CustomActivator. Luckily, the default activator is designed to be inherited from; everything we need to change is virtual. Create CustomActivator that inherits from Castle.MicroKernel.ComponentActivator.DefaultComponentActivator. You'll need a constructor that takes the same parameters. All we need to do is override SelectEligibleConstructor to force the container to choose the single string parameter one. We can do that just like this:

protected override
ConstructorCandidate SelectEligibleConstructor
(CreationContext context)
{
return
Model.Constructors.Cast<ConstructorCandidate>()
.First(c => c.Constructor.GetParameters().Length == 1
&& c.Constructor.GetParameters()[0]
.ParameterType == typeof(string));
}

The final step is just to add the facility to our configuration.

<facilities>
<facility id="linqFacility" type="Core.LinqFacility, Core" />
</facilities>

Now everything works as expected for all DataContexts in our config.

Wednesday, May 14, 2008

Anonymous Interface Implementation

With the introduction of lambdas, it's now incredibly easy to pass tiny bits of functionality around. Unfortunately, some existing methods in the Framework take parameters of an interface type, instead of a delegate. Contains, for example, takes an IEqualityComparer instead of a Predicate. This makes using these methods in an ad-hoc manner difficult. What we need is the ability to quickly throw together a temporary class that implements the interface, basically an anonymous type only with method implementation.

I submitted a Connect item about this (here), but as you can see it won't be making it into this release.

To tide myself over I wrote a version that is built on anonymous types, Reflection.Emit, and Funcs. You can download it here. This is a proof of concept...no warranties...don't use in production...blah blah blah.

As a sample, here's how to create an instance of IEqualityComparer that thinks strings are equal if they are the same length:

Make.Instance<IEqualityComparer<string>>(
new {
Equals = Make.Func(
(string x, string y) => x.Length == y.Length)
})


I had to use Eric Lippert's trick to get lambdas and inferencing working in anonymous types.

Friday, April 04, 2008

DataContractSerializer and 0 length array

In short, I don't think the DataContractSerializer for WCF likes 0 length arrays at all. I was getting mysterious exceptions and random crashing of my WCF service. I was using wsHttpBinding and getting some WS-Trust invalid or expired security token message so I switched to basicHttpBinding. When debugging that, after the return of my method on the server side, cassini would crash and I'd get Fatal Execution Engine Error messages in my event log.

I cut my service method down to nearly as simple as it could go:

return new MyClass { Name = "BLARG", Children = new MyClass[0] }

and that was still dying. But when I changed it to
Children = null
everything magically started working.

This really merits more investigation but it's after 5 on a Friday and I'm going home.

Tuesday, March 25, 2008

New stuff

New job means new laptop. New laptop means new laptop bag.

The new laptop is a Lenovo T61p with the 15" screen. I'm running Vista x64 on it and that part has gone smoothly so far. Design-wise, I think I liked my Dell D820 better. The T61p feels much heavier than the Dell (though I do have a 9 cell battery in this one), the screen is slightly off center, and I don't like the keyboard layout at all. I'm perhaps overly concerned about keyboard layouts and this one just doesn't do it for me. The biggest issues for me are that the arrow keys aren't normal sized keys, the escape key sits above F1, and the lower left corner is a special Fn key, rather than Ctrl. By default, Fn-Space triggers the built in Lenovo Zoom utility, which is really jarring when you just intended to pop up intellisense. I'm sure I'll get used to all that though.

The new laptop bag is an Ogio Metroid and it's nothing but fantastic. I was originally worried that the T61p wouldn't fit, but it easily does. The Metroid is a backpack with a laptop pocket, but it also has a file section in the front that keeps my papers from sliding down and getting crumpled in the main pocket. There's plenty of room for all my junk and the mp3 player pocket fits my external hard drive just fine. Plus, I got it from amazon for $60 (of which work reimbursed me $40).

Wednesday, February 27, 2008

Derived Properties in LINQ to SQL

When using a rich domain model, you often end up with properties that are dervied from other persisted values. To take a trivial example:

public bool HasMiddleName
{
get { return MiddleName != ""; }
}

where MiddleName is a persisted property (column in the database, mapped by LINQ, etc.).

This works fine in object land, but breaks down when you need to query the database based on this property. LINQ to SQL can't read into the definition of the property itself and figure out what to do. If you try to run something that looks like:

setOfObjects.Where(o => o.HasMiddleName)

you'll get an exception saying that LINQ to SQL doesn't know how to translate HasMiddleName.

Now you're left with a choice: either duplicate the implementation of your property in the query, or come up with something clever. Starting with the assumption that duplicating domain knowledge is bad, let's explore the clever path.

Our particular architecture builds up queries using IQueryable, to make sure that as much of our logic as possible is executed by the database, rather than in memory. IQueryable<T>.Where takes an Expression<Func<T, bool>>, basically an expression that represents a function taking your object and returning a boolean. In the normal case, you just pass a lambda to Where and the compiler builds the expression for you. In our case, we have to build the expression ourselves. Back in the domain object we do:

public static readonly Expression<Func<MyObject,bool>>
HasMiddleNameExpr = o => o.MiddleName != "";

Now we can write queries that look like:

var result = setOfObjects.Where(MyObject.HasMiddleNameExpr)

and things will run just fine. Great! Except we still have duplication: our object has a property with logic in it, and the definition of the expression with the logic in it. Let's remove that.

First, since Expressions can't be invoked directly, save a compiled version of the expression (i.e., a Func<MyObject,bool>).

public static readonly Func<MyObject,bool> HasMiddleNameFunc =
HasMiddleNameExpr.Compile();

Now, define the property in terms of the Func.

public bool HasMiddleName
{
get { return HasMiddleNameFunc(this); }
}

Now all the duplication is removed. Unfortunately this seems like quite a few hoops to have to jump through. Instead of just a property we now have a property, a static function, and a static expression representing the function.

Unfortunately, it gets worse. The particular query we were writing depended on two derived properties and not just one. That meant that we couldn't just call Where with our expression. We wanted all objects where either one or the other property was true. That meant we had to build the or expression ourselves. It looks something like this in the query:

ParameterExpression p =
Expression.Parameter(typeof(MyObject), "p");

var result = setOfObjects.Where(
Expression.Lambda<Func<MyObject,bool>>(
Expression.OrElse(
Expression.Invoke(MyObject.HasMiddleName,p),
Expression.Invoke(MyObject.HasLastName,p)),
p));

What this does is build an expression that represents something like:

p => MyObject.HasMiddleNameFunc(p) ||
MyObject.HasLastNameFunc(p)

The combining of two Func<T,bool> expressions via a logical operator could probably be hidden by an extension method to clean things up a bit.

Ultimately, though, we ended up deciding that there was no way a junior developer reading this code in the future would be able to maintain this, much less understand it. After all this exploration we opted just to duplicate the domain logic in the query.

Friday, January 25, 2008

Also

Why does SqlMethods.Like throw NotImplementedException when you try to use it against in memory objects?

It seems like it would be pretty easy to actually implement it with RegEx or something. It's really inconvenient that you can't mock your database to test tricky queries with in memory objects because of this.

Edit: Vote for my feedback!

Misc. Project Notes

First, a minor annoyance: If you happen to have join tables without primary keys defined, the LINQ designer won't generate the properties corresponding to the association. Either go have a talk with your DBA or update the Primary Key property for your Properties in the designer and you'll be fine.

Second, TFS is proving more of a hindrance than a help sometimes. So much of the build setup requires duplicated settings on all clients, rather than being centrally managed. Policies must be installed on all machines, code analysis configurations have to be imported into the solution, etc. It seems like the right way for this to work would be for the TFS server to transparently distribute and install any artifacts required by the project.

Additionally, code analysis is nice, but there's no way to have a check in policy that uses it that only applies to some of the projects in the solution. We'd like to exclude our unit test projects (since [ExpectedException] tests in particular result in unreferenced variable warnings), but it's all or nothing.

The source control piece is definitely nicer than VSS, but really, what isn't? There are a few recurring issues, though. Sometimes opening a solution causes lots of the project files to get checked out, even though there are no changes locally (doing a Compare confirms that all files are identical). The other issue revolves around the vsmdi file used with the testing bits. For some reason this file is included in the solution and checked into source control, even though it contains user-specific information. If you bring up the test list window and pick 3 tests to run, the vsmdi is updated to show this. VS tries to check out the file (which someone invariably already has out), which results in VS checking out the solution and adding a new vsmdi file named solutionname1.vsmdi (followed by solutionname2.vsmdi, etc.). Excluding vsdmi from source control entirely as part of TFS settings gets ignored, excluding the file manually from the solution gets ignored, etc. I'd love a workaround for this problem.

The only other thing that would make things easier is an update for BizTalk 2006 R2 so we can use VS2008 to develop against it and not have to run 2 IDEs (and have custom build steps using the 2005 devenv in our team build).

Despite all that complaining, we still have a pretty clever solution going that uses a ton of cool technologies like LINQ, CI, MSTEST, Rhino Mocks, Watin, Windsor, ASP.NET MVC, WCF, and BizTalk 2006 R2.