Reputation: 377
The Simple Injector docs describe how to implement a lazy dependency. However, this example only covers registering a simple interface (IMyService
). How would this work with an open generic (EG. IMyService<T>
)?
Here's my existing registration:
container.Register(typeof(IDbRepository<>), typeof(DbRepository<>));
Obviously the following code doesn't compile as I'm not specifying the generic type:
container.Register(typeof(IDbRepository<>),
() => new LazyDbRepositoryProxy<>(new Lazy<IDbRepository<>(container.GetInstance<>)));
Is this possible in Simple Injector? I can only see the following overrides for Register, non of which allow a func / instanceCreator to be passed in:
public void Register(Type openGenericServiceType, params Assembly[] assemblies);
public void Register(Type openGenericServiceType, IEnumerable<Assembly> assemblies);
public void Register(Type openGenericServiceType, Assembly assembly, Lifestyle lifestyle);
public void Register(Type openGenericServiceType, IEnumerable<Assembly> assemblies, Lifestyle);
public void Register(Type openGenericServiceType, IEnumerable<Type> implementationTypes, Lifestyle);
public void Register(Type openGenericServiceType, IEnumerable<Type> implementationTypes);
Upvotes: 1
Views: 301
Reputation: 172606
A code construct such as you suggested is not one you can express in C#. But by making a small change to your design, you can elegantly solve your problem.
The trick is to inject Container
into your LazyDbRepositoryProxy<T>
. This way, Simple Injector can easily construct new LazyDbRepositoryProxy<T>
instances using auto-wiring which prevents you from having to register a delegate (which won't work for open-generic types).
So change your LazyDbRepositoryProxy<T>
to the following:
// As this type depends on your DI library, you should place this type inside your
// Composition Root.
public class LazyDbRepositoryProxy<T> : IDbRepository<T>
{
private readonly Lazy<DbRepository<T>> wrapped;
public LazyDbRepositoryProxy(Container container)
{
this.wrapped = new Lazy<IMyService>(container.GetInstance<DbRepository<T>>));
}
}
And register your types as follows:
container.Register(typeof(DbRepository<>));
container.Register(typeof(IDbRepository<>), typeof(LazyDbRepositoryProxy<>));
Upvotes: 1