I study different DI patterns.
And now I interested in the lazy life-time implementation.
For example, I want to write a proxy class that hides the factory behind a service's interface.
Can any of existing IoC containers (.NET) create this kind of proxy class dynamically at runtime?
interface IService
{
void Foo();
void Bar();
}
class ServiceFactoryProxy : IService
{
private readonly Func<IService> _factory;
public ServiceFactoryProxy(Func<IService> factory)
{
if (factory == null) throw new ArgumentNullException("factory");
_factory = factory;
}
public void Foo()
{
_factory().Foo();
}
public void Bar()
{
_factory().Foo();
}
}
Here is how it can be done in Castle:
http://litemedia.info/lazy-loading-property-with-castle-dynamicproxy2
Unity does this out of the box. You declare a dependency of type Func<IService>
in your constructor (like you did with ServiceFactoryProxy
) and tell Unity how it should resolve IService
. The container will generate the delegate for you.
Update
That proxy looks like an encapsulation of Lazy<T>
.
If that is your intention you might want to have a look at this extension for Unity.
As far as I know Unity 3.0 will have support for .NET4 so I expect something similar to turn up as part of Unity with the next release.
Update2
It took me a while but I finished the lazy proxy feature. It generates IL code that looks like this
public class MyContract_LazyInstantiationProxy : IMyContract
{
private readonly Lazy<IMyContract> instance;
public MyContract_LazyInstantiationProxy(Func<IMyContract> factory)
{
Guard.AssertNotNull(factory, "factory");
this.instance = new Lazy<IMyContract>(factory);
}
public IMyContract Instance
{
get { return this.instance.Value; }
}
public string Foo(Bar bar)
{
return this.Instance.Foo(bar);
}
}
So you get the performance of hand-coded lazy proxies but they will be generated dynamically for you.
Have a look at the TecX project on codeplex. The lazy proxy generation can be found in the source code of TecX.Unity.Proxies. A sample on how to use it is in the according test project TecX.Unity.Proxies.Test.