IoC容器的协变服务解析

And*_*rey 7 c# ioc-container autofac dryioc

我正在为我的应用程序使用依赖注入模式而没有任何IoC容器.现在我决定使用一些IoC容器,因为我的Composition Root由数千行代码组成,但我没能使它与我的类一起使用,它们主动使用方差.例如以下界面

public interface IQuery<in TIn, out TOut>
{
    IReadOnlyCollection<TOut> Get(TIn key);
}
Run Code Online (Sandbox Code Playgroud)

和服务

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

纯DI工作正常

IQuery<string, object> service = new FakeRepository();
Run Code Online (Sandbox Code Playgroud)

但是Autofac和DryIoc都无法解决它.

service = autofacContainer.Resolve<IQuery<string, object>>(); // exception
service = dryIocContainer.Resolve<IQuery<string, object>>(); // exception
Run Code Online (Sandbox Code Playgroud)

我需要一些额外的设置吗?有没有其他IoC容器支持这个?我问得太多了吗?

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

dad*_*dhi 4

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

理论上没有什么没有什么可以阻止开放通用服务类型与封闭或非通用实现类型的注册。

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

container.Register(typeof(IQuery<,>), typeof(FakeRepository));
Run Code Online (Sandbox Code Playgroud)

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

container.Resolve<IQuery<string, object>>();
Run Code Online (Sandbox Code Playgroud)

可以进行类似的调整以将开放通用服务类型包括在RegisterMany.

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

最后,我在 DryIoc 跟踪器中创建了一个问题,并将思考如何以安全的方式启用它。

更新

新的DryIoc v2.12.7发布,Register能够注册开放通用服务类型。但不是RegisterMany. 检查问题以获取更多详细信息。