I'm using dependency injection pattern for my application without any IoC Container. Now I decided to use some IoC Container because my Composition Root consists of thousands lines of code, but I failed to make it work with my classes, which actively use variance. For example the following interface
public interface IQuery<in TIn, out TOut>
{
IReadOnlyCollection<TOut> Get(TIn key);
}
and service
public class FakeRepository : IQuery<object, string>
{
public IReadOnlyCollection<string> Get(object key)
{
return new[] { key.ToString() };
}
}
Pure DI works fine
IQuery<string, object> service = new FakeRepository();
But neither Autofac nor DryIoc can resolve it.
service = autofacContainer.Resolve<IQuery<string, object>>(); // exception
service = dryIocContainer.Resolve<IQuery<string, object>>(); // exception
Do I need some additional setup? Is there any other IoC container that support this? Am I asking too much?
The full code: https://dotnetfiddle.net/vlw17R
It won't work in current DryIoc versions (stable v2.12.6 and preview v3.0.0-preview-03).
But nothing in theory prevents the registering of open-generic service type with closed or non-generic implementation type.
For the single service-to-implementation registration:
container.Register(typeof(IQuery<,>), typeof(FakeRepository));
DryIoc will throw the exception because of the internal check for implemented types. If I adjust the check to include open-generic version of service type, then this works:
container.Resolve<IQuery<string, object>>();
The similar adjustment may be done to include open-generic service types in RegisterMany
.
But the remaining issue will be with ResolveMany
. It is rather an implementation detail, but having both closed and open-generic versions of services may produce two instances when resolving a collection.
Concluding, I have created an issue in DryIoc tracker, and will think how to enable this in a safe manner.
The new DryIoc v2.12.7 is released with Register
capable of registering the open-generic service type. But not the RegisterMany
. Check the issue for more details.