Unity + EntLib = ?

If you've been following Grigori Melnik's blog, you'll know a bit about Unity, the new Dependency Injection container that's coming in Enterprise Library 4.0. Unfortunately I won't be able to make it to the Unity Extensibility Workshop later this month (it's just a little bit out of my way), but I was lucky enough to have Grigori and Scott Densmore (yes, he's back!) give me a quick overview of Unity the other day, and I have to say it looks very nice so far.

However this initial presentation was really only about Unity as a stand-alone beast. That's fine - it's important to know that it can be used independently of the rest of Enterprise Library if you so wish - but the thing that I'm really interested in is how Enterprise Library application blocks will be "refactored to take advantage of Unity" (direct quote from Grigori's blog). There are a few clues in Scott's latest post, which focuses primarily on how this change will clean up some of the under-the-covers plumbing in Enterprise Library. This is a worthwhile goal (I've never been a big fan of the countless factories and assemblers), but I'm yet to fully understand what impact this will have on the average developer who, let's face it, doesn't normally need to look under the hood to see how it all works, provided it does all work.

In general, a key benefit of using dependency injection is that code can take a dependency on only the interface of a component, plus it needn't worry itself on how that object is created. This is particularly useful if you want to allow different implementations to be used at different times (such as mocks for unit testing), or if you need flexibility in how those instances are going to be created. It's a very useful pattern, but since the Enterprise Library application blocks already include several layers of abstraction internally it isn't obvious what advantages the Unity integration will provide.

To give an example, let's look at how a developer may call the Logging Application Block and Data Access Application Block today:

 Logger.Write("My message", new string[] {"Category1", "Category2"});

Database database = DatabaseFactory.CreateDatabase("Northwind");
int result = database.ExecuteNonQuery("spDoStuff", 5, "Foo");

Now in both of these cases, the developer doesn't know what concrete instances are created (TraceListeners, Filters and Formatters for the Logging Application Block, Databases for the Data Access Application Block). They also don't need to worry themselves about how those instances are constructed - granted the options are limited (configuration- or sometimes attribute-driven), but at least this is hidden behind the factory or facade.

So what might these blocks look like when accessed via Unity? I haven't seen any code that describes this yet, but I imagine it will need to look something like this:

 // First set up the unity container and tell it how to configure the blocks.
// I have no idea how this will work, so let's not speculate :-)

ILogger logger = unityContainer.Get<ILogger>();
logger.Write("My message", new string[] {"Category1", "Category2"});

IDatabase database = unityContainer.Get<IDatabase>("Northwind");
int result = database.ExecuteNonQuery("spDoStuff", 5, "Foo");

Now ignoring any potentially necessary bootstrapping code, this isn't drastically different from what we do today, although it would be a little more verbose for facade-based blocks such as Logging, Exception Handling and Validation. But what benefits does it provide? Well, for one thing, I could provide a completely different implementation of either block without changing my code. This sounds attractive, until you consider that your new implementation must have the exact same semantics of the original block - for example it would need to use the same LogEntry with the same properties, utilise categories and filters for the same purpose, and so on. So really I can't imagine why you would ever want to use a different implementation, since it would essentially need to behave identically to the current block. The pattern makes a bit more sense for the Data Access Application Block, but it's not really any different to what you can already do with the existing API using derived Database classes.

Scott made it very clear on his blog that they are not planning on doing away with the current block APIs anytime soon, so there isn't any need to panic. But still I think it makes sense to ask what benefits EntLib users will get out of this refactoring exercise, given that the team could be spending time on other priorities. I also know (as does Scott, more than anyone), that changing the core architecture of EntLib is very time-consuming, given that there are seven different blocks built on top of it.

Still I am willing to be sold on this effort. I would like to see the internal architecture cleaned up and I would be very happy if building and extending blocks were made a little easier. And if someone can explain to me how the Unity integration will make my life as an architect and developer easier, I'm more than willing to listen. But in my wishlist for EntLib 4.0, I have to say that other things are higher up on my list, so I'd like to hear the team explain exactly what we are getting out of this and why we would want to change the way we've been using the blocks for the past three years.

If you agree or disagree with me, or if you can inject any additional information into the conversation that will help me or the EntLib team think about this differently, please speak up - as you know, this is the kind of dialogue that patterns & practices team, and the developer community as a while, continues to thrive on.