IoC 容器的协变服务解析

Covariant service resolution by IoC container

我在没有任何 IoC 容器的情况下为我的应用程序使用依赖注入模式。现在我决定使用一些 IoC 容器,因为我的 Composition Root 包含数千行代码,但我没能让它与我的 类 一起工作,它积极使用方差。比如下面的界面

public interface IQuery<in TIn, out TOut>
{
    IReadOnlyCollection<TOut> Get(TIn key);
}

和服务

public class FakeRepository : IQuery<object, string>
{
    public IReadOnlyCollection<string> Get(object key)
    {
        return new[] { key.ToString() };
    }
}

纯 DI 工作正常

IQuery<string, object> service = new FakeRepository();

但是Autofac和DryIoc都无法解决。

service = autofacContainer.Resolve<IQuery<string, object>>(); // exception
service = dryIocContainer.Resolve<IQuery<string, object>>(); // exception

我需要一些额外的设置吗?还有其他支持此功能的 IoC 容器吗?我是不是要求太多了?

完整代码:https://dotnetfiddle.net/vlw17R

它不适用于当前的 DryIoc 版本(稳定版 v2.12.6 和预览版 v3.0.0-preview-03)。

但理论上 没有任何东西可以阻止将开放通用服务类型注册为封闭或非通用实现类型。

对于单个服务到实施注册:

container.Register(typeof(IQuery<,>), typeof(FakeRepository));

DryIoc 将抛出异常,因为内部检查已实现的类型。如果我调整检查以包括服务类型的开放通用版本,那么这有效:

container.Resolve<IQuery<string, object>>();

可以进行类似的调整以在 RegisterMany 中包含开放式通用服务类型。

但是剩下的问题将与ResolveMany有关。它更像是一个实现细节,但是同时拥有封闭和开放通用版本的服务可能在解析集合时产生两个实例。

最后,我已经在 DryIoc 跟踪器中创建了 an issue,并且会考虑如何以安全的方式启用它。

更新

DryIoc v2.12.7 is released with Register capable of registering the open-generic service type. But not the RegisterMany. Check the issue 了解更多详情。