IoC容器的协变服务解析

时间:2018-01-17 13:20:50

标签: c# autofac ioc-container dryioc

我正在为我的应用程序使用依赖注入模式而没有任何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

1 个答案:

答案 0 :(得分:3)

它无法在当前的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已发布,Register能够注册开放式通用服务类型。但不是RegisterMany。查看issue了解详情。