Sunday, March 30, 2008

I've won!

The Elegant Code Essay contest that is. I just won a free copy of Beautiful Code. You can read my essay here. Many thanks to the nice people of Elegant Code.

Castle Dynamic Proxy

This blog has been silent for a while, and for good reason. Besides experiencing symptoms of writer's block,  I've also been playing around with a lot of new stuff (at least new to me), and no, it's not LINQ or any other stuff from Redmond this time.

One of the things I've been playing with is Dynamic Proxy and it's successor Dynamic Proxy 2 from the magnificent Castle stack.

Now, what are the problems that this library tries to solve? It tries to overcome the CLR's heavyweight proxy capabilities (extending MarshalByRefObject or ContextBoundObject) by providing lightweight proxies that can be generated on the fly for interfaces and classes (virtual properties and methods only). If this last sentence blows you away, don't worry. It's not that hard to understand.

I'm a big proponent of Persistence Ignorant (PI) domain models. Practically, this means that the assembly that contains my domain entities (also called POCO's) does not have any reference to other assemblies, except for the System assembly of the .NET Framework. The domain layer is the core of your application and it should be treated as such. You can compare it with the kernel of an operating system. It is the beating heart of ..., you get the picture.

This of course is easier said than done. You have to take some actions in order to accomplish PI domain models. Castle Dynamic Proxy can be used to simplify some of these actions and overcome some of the issues you come across while trying to achieve Persistence Ignorance. It's time for an example.

Let's say you have an entity in your domain model called Artist. An Artist can have a number of Records in his Repertoire.

public class Artist { private String _name; private Repertoire _repertoire; public String Name { get { return _name; } set { _name = value; } } public Repertoire Repertoire { get { return _repertoire; } set { _repertoire = value; } } } public class Repertoire { private readonly Artist _artist; private readonly List<Record> _records = new List<Record>(); public Repertoire(Artist artist) { _artist = artist; } public Artist Artist { get { return _artist; } } public virtual IEnumerable<Record> Records { get { return _records; } } } public class Record { private readonly String _title; public Record(String title) { _title = title; } public String Title { get { return _title; } } }

This is the simplest domain I could come up with. In some scenarios, I want to use Artist information without retrieving the records from it's Repertoire. Other scenario's require that the records of the Repertoire are available.

One solution would be to change the Records property of the Repertoire class to directly retrieve the records from a database gateway when this property is accessed. This violates the PI principle explained earlier by polluting the domain with infrastructure concerns.

Let's see how Castle Dynamic Proxy can help us out here. First we implement an interceptor (implements the IInterceptor interface from the Castle.Core.Interceptor namespace).

public class LazyLoadInterceptor : IInterceptor { private List<Record> _loadedRecords; public void Intercept(IInvocation invocation) { Repertoire repertoire = (Repertoire)invocation.Proxy; if(null == _loadedRecords) { // Some data access _loadedRecords = new List<Record>(); _loadedRecords.Add(new Record("Die Sonne")); _loadedRecords.Add(new Record("Mutter")); _loadedRecords.Add(new Record("Mein Teil")); Console.WriteLine("Repertoire of {0}", repertoire.Artist.Name); } invocation.ReturnValue = _loadedRecords; } }

We need to make sure that the Records property of the Repertoire class is marked as virtual. Calls to the Records property are intercepted. If the records are not yet loaded, then they are retrieved from the database. This interceptor lives in the infrastructure or data access part of your application. 

Next, we use this interceptor to intercept calls to the Records property.

public class ArtistRepository : IArtistRepository { public Artist FindBy(String name) { // Some data access Artist artist = new Artist(); artist.Name = name; ProxyGenerator proxyGenerator = new ProxyGenerator(); LazyLoadInterceptor lazyLoadInterceptor = new LazyLoadInterceptor(); IInterceptor[] interceptors = new IInterceptor[] { lazyLoadInterceptor }; Repertoire repertoire = (Repertoire)proxyGenerator .CreateClassProxy(typeof(Repertoire), interceptors, artist); artist.Repertoire = repertoire; return artist; } }

Notice that the Repertoire class doesn't need to have a default constructor. It is possible to specify constructor arguments.  You typically want to move this proxy setup code to some kind of a mapper class, but for the simplicity of this example this will do.

The following code results in the records to be retrieved only once, although the collection is accessed twice:

Artist artist = artistRepository.FindBy("Rammstein"); Console.WriteLine("Name: {0}", artist.Name); foreach(Record record in artist.Repertoire.Records) { Console.WriteLine("Record: {0}", record.Title); } foreach(Record record in artist.Repertoire.Records) { Console.WriteLine("Record: {0}", record.Title); }

Lazy loading is just one example where using proxies can be helpful. When you have a decent ORM at your disposal, you don't need to write this kind of code for lazy loading. In fact, NHibernate makes extensive use of Castle Dynamic Proxy to support lazy loading for you.

Other scenarios include cross-cutting concerns like dirty tracking, logging, tracing, etc. Interceptors also integrate nicely with Castle Windsor (what would you expect :-) ). This nicely written blog post explains how easy this is.

This example makes use of Dynamic Proxy 2. The first version of Castle Dynamic Proxy also supports mixins, which is not yet available for Dynamic Proxy 2 included with the Castle RC3 release. According to Hamilton Verissimo, Dynamic Proxy 2 is significantly more performant than it's first version.

If you, my dear reader want to know more about the use of dynamic proxies in your applications, than these articles and blog posts will provide you with some more information:

Till next time.

Friday, March 07, 2008

Sweet NUnit Integration in TeamCity

I would like to make a service announcement from the JetBrains fan club:

TeamCity 3.1 is here!

I took me about 15 minutes to upgrade my existing home installation. It actually took me this long because I have a slow PC  ;-). All my existing build projects and settings were nicely preserved. Make sure to read the upgrade notes though. You never know.

Now drewl on these new features:

  • Visualization of Build Agents’ workload
  • “Time to fix tests” statistics report for monitoring the project health
  • Improvements in 3rd party .NET tools integration
  • More types of notification options
  • Improved external database support (Oracle)
  • Scope filter for Code Duplicates and Inspections browsers
  • New options for builds triggering

The 3rd party improvements includes support for NUnit 2.4:

NUnit Settings

TeamCity also received the Jolt productivity award. Kudos!

Thursday, March 06, 2008

Book review: The .NET Developer's Guide to Directory Services Programming

Directory Services This is THE book on Active Directory and LDAP programming in .NET. Why? Because it's the only book that covers  System.DirectoryServices. This book contains a lot of tips & tricks and best practices when it comes to integrating Active Directory, ADAM and other LDAP stores in your enterprise applications. At least when you are using .NET 1.x or .NET 2.0. As I already mentioned in this post, .NET 3.5 introduces a new namespace that makes it more productive to enable LDAP stores in your applications.

This new namespace makes the contents of this book a little bit obsolete, but certainly not for .NET 1.x and .NET 2.0 applications. I did some minor LDAP programming before I've read this book. The impression I have now is that I was doing it all wrong! For the current project I'm working on, I'll be doing a fair amount of LDAP programming as we need to integrate Active Directory and a third-party LDAP store. I know one thing for sure. This book will be on my side while I'm developing this.

Sunday, March 02, 2008

Daily Stand-up Meetings

I finished reading the excellent article It's Not Just Standing Up: Patterns of Daily Stand-up Meetings written by Jason Yip. Somewhere in the beginning of this article, the author talks about self-organization:

The underlying theme for daily stand-up meetings is self-organization. This is not just because self-organization leads to better productivity but also, and perhaps more so, because it leads to a more humane, respectful, and mature work environment.

This is exactly what I've been talking about in my post on software factories. If you and your team are practicing Scrum, you should definitely give this article a thorough read.

Saturday, March 01, 2008

Behavior Driven Development on ALT.NET

There's a really interesting discussion going on at the ALT.NET user group about Behavior Driven Development. This post from Jimmy Bogard really hit home. It clearly describes BDD as I currently understand it (see my previous post).

I also want to mention that Joe Ocampo has started a new discussion forum on BDD, if you're interested. Aaah, nothing beats learning from the masters.

Till next time

Scrum Dashboard

A couple of years ago, my current employer paid a lot of good money for setting up a Team Foundation Server for its developers. Now, I'm not a big fan of TFS but we are trying to make the best of things. Setting up build scripts is a real PITA with a lot of friction compared to the magnificent TeamCity. The process templates (MSF agile and CMMI) that come out-of-the box suck big time too. To me, TFS looks like a big ball of mud.

Instead of using the standard templates, we are currently using the Scrum for Team System template of Conchango. It isn't great either, but it's better than nothing at all.

A while ago, I stumbled into this CodePlex project called Scrum Dashboard.

scrumdashboardpreview

Now that's more like it! It's being developed and used by the good people of EPiServer. It has a few prerequisites like TFS 2008, the TFS Web Access Power Tool and Scrum for Team System 2.0 which RTM'd earlier this week.

This is definitely something I want to try when our TFS is upgraded to TFS 2008. If you are using the Scrum Dashboard, please let me know your thoughts and experiences.