Ubik Systems Blog
Autofac on CodeProject
Posted by Nicholas Blumhardt | April 19, 2008 18:27
I've been wanting to write an introductory, from-the-ground-up article on Autofac for a while, and here it is!
Good Citizenship
Posted by Nicholas Blumhardt | March 28, 2008 19:42
This set of design principles is a few years old, but I'm not sure how widely it is referenced. I can't even remember who originally pointed me towards it...
There are a couple of Java-centric points, but its still absolutely invaluable advice for designing robust classes in .NET.
I especially like 'never expect or return null' - how much easier would our lives be if ever API followed this convention?
Enabling Rich Domain Models with Services
Posted by Nicholas Blumhardt | March 02, 2008 13:07
Rinat Abdullin has just posted an interesting article that cuts to the core of a very tricky problem that you face building applications on top of IoC:
Components often need to create instances of other container-managed components at will.
Calling new is a simple and natural thing to do in a non-DI
application, but takes more care when using DI. After all, avoiding the use of
new is half of what DI is about.
If you haven't read Rinat's article, head over and check it out. (Rinat doesn't just contribute code and CPU cycles to the Autofac project, but also a large number of brain-cycles.)
The solution is to create adapters that bridge the gap between components in the container, and the container itself. This is done using an interface that is independent of the container, to keep the components free of dependencies on the container, which I must reiterate, is the rule.
The reason this problem interests me so much is that it is so common but so infrequently addressed. One of my great passions is for domain-driven design, and I'm always looking for ways to make a domain model richer.
A typically contrived example is determining the current value of a holding of stock:
public class Shareholding
{
public Shareholding(string symbol, int quantity) {...}
public string Symbol { get {...} }
public int Quantity { get {...} }
}
To get the current value of a holding, we can use a quote service:
public interface IQuoteService
{
decimal GetQuote(string symbol);
}
All of this is well and good - determining the value of a holding is a simple operation and the quote service can obviously be injected into whichever controller is going to do the calculation.
An incremental improvement though is to encapsulate the logic in a property
of the Shareholding class itself. Perhaps we'll set the quote service
as an optional dependency:
public class Shareholding
{
public IQuoteService QuoteService { set; private get; }
public decimal Current Value
{
get
{
return QuoteService.GetQuote(Symbol) * Quantity;
}
}
...
To get the value:
// In some method...
var shareholding = new Shareholding("ABC", 1000);
shareholding.QuoteService = this.QuoteService;
Console.WriteLine(shareholding.Value);
Spot the problem? Any class that wants to create shareholdings must itself have
reference to an IQuoteService so that it can manually inject the dependency.
This breaks some of the encapsulation that we were originally trying to achieve by
exposing Shareholding's reliance on the service. This isn't so bad if the caller is created directly by the container, but if not, it has a flow-on effect
through all components that create instances of other components - if Shareholding
then creates more components themselves with dependencies, we're in real trouble. Every component along the line will have to obtain a reference to an IQuoteService and pass this along.
Now, that's the context of our problem. In Rinat's example, which deals with executing workflows, a hand-coded factory encapsulating a reference to the container is a rather nice solution. When building a domain model with hundreds of interrelated classes that all may create instances of each other, this becomes impractical in my eyes.
Aside: Udi Dahan, a man who knows more than a little about DDD, posted an article on his solution while I was writing this. Udi's solution uses events and looks very workable, but appears as though it might exhibit increasing complexity as the depth of dependencies within the domain model increases. I could certainly be wrong and definitley need to spend some more time investigating Udi's model.
A syntactic shortcut that Rinat has touched on and that I am interested in exploring further is to utilise .NET's typing features to substitute delegate signatures for the adapter/resolver interfaces:
public class Shareholding
{
public delegate Shareholding Factory(string symbol, int quantity);
public Shareholding(string symbol, int quantity) {...}
...
We can register an instance of this delegate in the container:
builder.Register<Shareholding>().FactoryScoped(); builder.RegisterGeneratedFactory<Shareholding.Factory>();
This lets us later resolve that factory delegate as a dependency, and use it to create
our Shareholding without any awareness of the injected quote service:
// In some method...
var shareholding = this.ShareholdingFactory("ABC", 1000);
Console.WriteLine(shareholding.Value);
I cheated a bit just there. What the RegisterGeneratedFactory() method does,
is (approximately):
builder.Register<Shareholding.Factory>(
(c, p) =>
(symbol, quantity) =>
c.Resolve<Shareholding>(new Parameter("symbol", symbol), new Parameter("quantity", quantity)))
.ContainerScoped();
Now that is a mouthful of lambda! Autofac 1.1 uses Linq to translate the parameters of the
Shareholding.Factory delegate, symbol and quantity into
named parameters that can be fed to the container's Shareholding constructor call.
At the moment I feel like this kind of container usage is really on the edge and perhaps you should expect some less exotic scenarios in my future posts, however DI/IoC is a very deep architectural pattern, and in the coming years (before it eliminated entirely by languages without the structural object creation issues we face in C#,) lots of people are going to hit these same challenges. I hope that we can take some of these concepts along with Autofac to make solving these problems more straightforward.
Closing note - you need a pretty flexible ORM, like NHibernate before you'll get very far trying to pull tricks like this with your domain model ;)
The Diamond Age
Posted by Nicholas Blumhardt | February 29, 2008 18:12
I don't want to stray too far from the usually dry technical content of this blog :) but The Diamond Age by Neal Stephenson deserves an exception.
His earlier novel, Snow Crash, is something of a cyberpunk masterpiece set in the virtual world of tomorrow. Its about computers, an ancient Sumerian god, linguistics and a katana-wielding pizza delivery driver. It wasn't a hard sell.
The Diamond Age, on the other hand, is about nanotechnology, and well, a girl's schoolbook... As much as I loved Snow Crash it has taken me years to get around to reading it.
And, it is brilliant. The world of The Diamond Age is so easily traced back to the world we know today, but in most other respects, especially social ones, eerily foreign.
Advanced nanotechnology as imagined by Stephenson changes the way people work, interact and think, even more than the Internet has changed us.
Get your copy fresh from a matter compiler (!!!) near you!
SharpDevelop 3.0
Posted by Nicholas Blumhardt | February 25, 2008 08:48
Hi everyone. Just a quick note to share some joy - I recently shelled out for Visual Studio 2008, then, of course, decided to check out the competition. I like it.
SharpDevelop 3.0 has just hit beta 1, and feels like a good solid tool. Unlike Visual Studio, which comes bundled with a lot of very advanced designer-driven functionality, SharpDevelop feels like the product of the more agile mindset driving the project.
I'd gladly trade half of the VS features for integrated code coverage testing like this:
For this reason alone, SharpDevelop has already found its place in my workflow. The integrated Subversion support is nice too, but of course Tortoise is still the one client to rule them all :)
Guidance for Introducing Dependency Injection into Existing Applications
Posted by Nicholas Blumhardt | February 04, 2008 20:01
Much like you can never go back to datasets from a good ORM, working without dependency injection seems tedious after building DI applications. Getting DI into an existing app should be a great way to move the codebase forward incrementally, but there isn't much guidance out there on how to do it.
Many developers in a position to set the architectural direction of large projects are already dealing with significant existing codebases, and I think this is one of the reasons that DI is still a relatively under-utilised technology in .NET applications.
I've started an article over on the Autofac wiki that will hopefully grow to include this sort of advice - for now the main points I think need to be addressed are:
- What benefits can you expect from migrating to a DI-styled architecture?
- Where should you start?
- How can you introduce a new architectural pattern without creating even more complexity?
- What strategies or best practices can help when making the transition?
Autofac has a couple of features that I think will make it the container of choice for this situation, simply because lambdas are so flexible. Wrapping a typical static factory method is trivial:
builder.Register(c => MyFactory.CreateProduct()).WithScope(InstanceScope.Factory);
With that the job is done and you can move on. The same thing can always be achieved in XML configuration, but little complications that come from the environment or the need to pass parameters could turn this into a headache quickly.
The other guidance that I think would be useful is a catalogue of simple patterns and/or refactorings to help with the task, e.g. creating an instance-based adapter for classes exposing static methods.
As you would have seen if you followed the article link, the page really is a shell so far. If you have any tales from the trenches or tips that you think could help someone tackling DI in a large scale existing project, it would be great to hear from you!
A New Year and a New Engagement
Posted by Nicholas Blumhardt | January 09, 2008 19:39
I have recently been fortunate enough to join Patrick, Mark and Gang from ThinkAbout Solutions to work for Dataract. Everyone is proving fantastic to work with, and the task at hand is adequately challenging :)
Dataract create, among other products, a workflow solution integrating WWF and SharePoint. The level of customisation provided to clients is going to be a rich source of interesting design tasks. IoC is very handy in these situations, however I'm interested in refining approaches using ORM and IoC in an integrated way to create customised domain objects with data mappings that are flexible and maintainable. Limiting the amount of generic schema is always tricky in any customisation job - it would be great to be able to eliminate it altogether.
The intersection of ORM and IoC is an area where extremely rich and powerful domain models can be built. Surprisingly, not too many people seem to have tackled this yet and there is definitely room for additions to the collection of best practices in this area.
Something I've been considering, and perhaps will write a future article on, is the requirement in most (perhaps all) data mapping frameworks that domain objects have a parameterless constructor. IoC container support would be very easy to add, in most cases, however there may be some residual issues surrounding dynamic proxies...
If you're working with a system that creates or decorates business domain objects with services using IoC, it would be great to hear about your experiences.
Incidentally, I have posted an article on the Autofac site about the use of modules when structuring systems with IoC. Feedback would be great if you get a chance to check it out.
Autofac gets MVC Integration
Posted by Nicholas Blumhardt | December 13, 2007 20:37
Autofac now has ASP.NET MVC integration. This means that you can have Autofac create your controllers to handle web requests, cleanly wired up to their service dependencies from the container.
I had a look at the MVC Contrib project, hoping to add the Autofac integration there, but it seems like there is a bit of chaos going on there at the moment. Given that the idea of using an IoC container is to reduce coupling, I find it extremely amusing that the entire MVC Contrib project is currently implemented in a single assembly that references Windsor, Spring.NET and StructureMap! That's a lot of bulk to add for a class or two. I'm sure they'll sort it out soon though.
To take advantage of Autofac's dependency management and component disposal features, the integration creates an 'inner container' per web request. Getting an event handler for the HttpApplication.EndRequest event to fire reliably without requiring a handler in Global.asax.cs seems to necessitate an HTTP module implementation, so the integration currently requires you register it in Web.config.
If anyone out there knows how to:
- Reiliably handle EndRequest without an HTTP module, or
- Register an HTTP module programmatically
then please speak up! :)
Now that the new Entity Framework CTP is out, the real work can begin. The current plan is to provide an Autofac persistence service that can be used semi-transparently with either Microsoft's Linq to Entities or the Linq to NHibernate provider as the back-end. No doubt about it, that is going to be a challenge.
IQueryable on In-Memory Objects
Posted by Nicholas Blumhardt | November 22, 2007 21:31
Does anyone out there know where Enumerable.ToQueryable() from the early LINQ previews went?
I'm keen to mock IQueryable<T> to test some queries and would like to adapt an IEnumerable<T> for the purpose - implementing this by hand looks like a pain - surely there is an implementation provided with the BCL..?
If not, I guess you can expect to see some 'writing a pointless and trivial IQueryable provider'-type articles in this space :)
Return of the Batch Enumerable
Posted by Nicholas Blumhardt | November 17, 2007 09:58
Just a quick post about a little extension to IEnumerable<T> that caused a nasty case of VM upsets when Mark Monsour and I tried to run it after building on the VS2005 compiler. (Where's your blog, Mark? :P)
Turns out that the solution works under the 2008 compiler - perhaps we were doing something crazy in the last attempt a year ago - for interest's sake here is the code anyway:
static class InBatchesExtension
{
public static IEnumerable<IEnumerable<T>> InBatches<T>(
this IEnumerable<T> source,
int batchSize)
{
using (var enumerator = source.GetEnumerator())
while(enumerator.MoveNext())
yield return TakeBatch(enumerator.Current, enumerator, batchSize);
}
static IEnumerable<T> TakeBatch<T>(T item, IEnumerator<T> rest, int max)
{
yield return item;
int count = 1;
while (count++ < max && rest.MoveNext())
yield return rest.Current;
}
}
This code breaks an IEnumerable<T> up into batches, so that you can write code like:
var ints = new[] { 1, 2, 3, 4, 5, 6, 7 };
foreach (var batch in ints.InBatches(3))
{
Console.Write("Batch: ");
foreach (var item in batch)
Console.Write(item.ToString() + " ");
Console.WriteLine();
}
This prints:
Batch: 1 2 3 Batch: 4 5 6 Batch: 7
See the
discussion on Luke's blog if you're curious as to why the using
statement is necessary.
Disclaimer: These articles represent the opinions of the authors and may not match the official position of Ubik Systems Pty. Ltd. Confirmation should be sought on all matters involving professional advice.
