Auto-Generated Factories in Autofac 2 is a brilliant addition to Autofac. The concept is simple. Often a service / class has dependencies that are relatively expensive to instantiate and may or may not be used by the service. Rather than instantiating the dependency during service construction, the container provides a lazy container, Func<T> or Lazy<T> for example, during construction that provides a way to access the dependency and instantiate it only at time of use. One can easily create the lazy containers in code, but Auto-Generated Factories in Autofac 2 give you this functionality for free!
Auto-Generated Factories in Autofac using Lazy<T>
Since I’ve been going on and on about Lazy<T> and Lazy<T,TMetadata> in .NET 4, it only makes sense that I beat the subject to death again :)
The NewsController below has a dependency of Lazy<IEnumerable<IPublisher>> because the instantiation of various publishers to publish the news is an expensive process and may or may not be used by the controller depending on the action called by the client.
Using Auto-Generated Factories in Autofac we only have to register the various publishers and add the LazyDependencyModule to the ContainerBuilder for Autofac to magically create the Lazy<T> container needed by the NewsController.
Here is some simple code to illustrate the idea:
class Program
{
static void Main(string[] args)
{
var builder = new ContainerBuilder();
// Module in Autofac.Integration.Mef
builder.RegisterModule(new LazyDependencyModule());
// Native Collection Support in Autofac 2!!
builder.RegisterType<NewsPublisher1>().As<IPublisher>();
builder.RegisterType<NewsPublisher2>().As<IPublisher>();
builder.RegisterType<NewsController>();
var container = builder.Build();
var controller = container.Resolve<NewsController>();
controller.Publish(new News());
}
}
public class NewsController
{
Lazy<IEnumerable<IPublisher>> _publishers;
public NewsController(Lazy<IEnumerable<IPublisher>> publishers)
{
_publishers = publishers;
}
public void Publish(News news)
{
_publishers.Value.ToList().ForEach(p => p.Publish(news));
}
}
Notice how Autofac automatically injects a Lazy<IEnumerable<IPublisher>> dependency for us. That is slick!
Auto-Generated Factories in Autofac using Func<T>
We can’t always count on using the .NET Framework 4.0, so let Auto-Generated Factories in Autofac 2 inject a Func<IEnumerable<IPublisher>> dependency with a few minor changes to the code:
class Program
{
static void Main(string[] args)
{
var builder = new ContainerBuilder();
// Native Collection Support in Autofac 2!!
builder.RegisterType<NewsPublisher1>().As<IPublisher>();
builder.RegisterType<NewsPublisher2>().As<IPublisher>();
builder.RegisterType<NewsController>();
var container = builder.Build();
var controller = container.Resolve<NewsController>();
controller.Publish(new News());
}
}
public class NewsController
{
Func<IEnumerable<IPublisher>> _publishers;
public NewsController(Func<IEnumerable<IPublisher>> publishers)
{
_publishers = publishers;
}
public void Publish(News news)
{
_publishers().ToList().ForEach(p => p.Publish(news));
}
}
That's just wicked cool!
Conclusion
Auto-Generated Factories is a really nice feature in Autofac 2. If you haven’t played with Autofac and are interested in a lightweight and user friendly IoC Container, you owe it to yourself to download the source and check out the group.
Next time I will show you how these Auto-Generated Factories inspired similar functionality in Unity 2 :)
Hope this helps.
