Autofac:使用in和out类型参数解析变体类型

这个问题是我之前提出的问题的后续问题: Autofac:隐藏一个复合背后的多个逆变实现 。

我试图找到我们可以用Autofac的协方差和逆变支持做些什么的边界。 我注意到Autofac的ContravariantRegistrationSource仅支持具有使用in关键字标记的单个generics参数的通用接口。 这似乎限制了这个function的实用性,我想知道Autofac是否有其他方法来扩展协方差和逆变的支持。

我必须承认,由于我正在使用的真实应用程序设计,我不是在问这个问题。 为了教育,我故意试图找到Autofac的限制。

请考虑以下界面:

 public interface IConverter { TOut Convert(TIn value); } 

以下实施:

 public class ObjectToStringConverter : IConverter { string IConverter.Convert(object value) { return value.ToString(); } } 

以下注册:

 var builder = new ContainerBuilder(); builder.RegisterSource(new ContravariantRegistrationSource()); builder.RegisterType() .As<IConverter>(); var container = builder.Build(); 

通过这种设计和配置,我希望能够做到这一点:

 // This call succeeds because IConverter is // explicitly registered. container.Resolve<IConverter>(); // This call fails, although IConverter is // assignable from IConverter. container.Resolve<IConverter>(); 

或者让我更抽象地说,给定的定义:

 public class A { } public class B : A { } public class C : B { } public class AToCConverter : IConverter { ... } 

以下注册:

 builder.RegisterType() .As<IConverter>(); 

我希望以下调用成功:

 container.Resolve<IConverter>(); container.Resolve<IConverter>(); container.Resolve<IConverter>(); 

我们怎么能用Autofac做到这一点?

我认为这是我们在Autofac中不太可能克服的限制,但探索它很有意思。

我们可以做逆变’resolve’,因为给定generics类型参数,我们可以找到该参数可赋值的所有基类/接口类型。 也就是说,给定string我们可以搜索objectIComparable等的实现。

走向相反的方向 – 从参数类型到其所有子类 – 并不容易。 给定object我们需要一些方法来寻找其他所有东西。

可以使用容器中注册的具体组件的知识,例如扫描所有组件以寻找可能的实现并向后工作,但这对于Autofac来说并不是很好,因为我们依赖于“拉”模型来懒惰地创建组件很多情况。

希望这是值得深思的,有兴趣看看你想出了什么。

您在观察ContravariantRegistrationSource仅识别具有一个通用参数的类型时是正确的。 查看来源 (目前在约166行),你会看到那个限制。 考虑如何提供注册源以提供可能的候选者,我可以理解,解除限制将需要在实现中更复杂。

我想说这并不能certificate你达到了Autofac的限制,只有这个特定注册源的限制。 我将把它作为练习让读者增强ContravariantRegistrationSource实现,我确信Autofac项目非常乐意接受它回到核心。