简体   繁体   中英

Covariant service resolution by IoC container

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.

Update

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM