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

Ste*_*ven 9 c# dependency-injection ioc-container covariance autofac

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

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

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

请考虑以下界面:

public interface IConverter<in TIn, out TOut>
{
    TOut Convert(TIn value);
}
Run Code Online (Sandbox Code Playgroud)

以下实施:

public class ObjectToStringConverter : IConverter<object, string>
{
    string IConverter<object, string>.Convert(object value)
    {
        return value.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

以下注册:

var builder = new ContainerBuilder();

builder.RegisterSource(new ContravariantRegistrationSource());

builder.RegisterType<ObjectToStringConverter>()
    .As<IConverter<object, string>>();

var container = builder.Build();
Run Code Online (Sandbox Code Playgroud)

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

// This call succeeds because IConverter<object, string> is
// explicitly registered.
container.Resolve<IConverter<object, string>>();

// This call fails, although IConverter<string, object> is
// assignable from IConverter<object, string>.
container.Resolve<IConverter<string, object>>();
Run Code Online (Sandbox Code Playgroud)

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

public class A { }
public class B : A { }
public class C : B { }

public class AToCConverter : IConverter<A, C> { ... }
Run Code Online (Sandbox Code Playgroud)

以下注册:

builder.RegisterType<AToCConverter>()
    .As<IConverter<C, A>>();
Run Code Online (Sandbox Code Playgroud)

我希望以下调用成功:

container.Resolve<IConverter<C, A>>();
container.Resolve<IConverter<B, B>>();
container.Resolve<IConverter<A, C>>();
Run Code Online (Sandbox Code Playgroud)

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

Nic*_*rdt 4

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

我们可以进行逆变“解析”,因为给定一个泛型类型参数,我们可以找到该参数可分配给的所有基本/接口类型。也就是说,假设string我们可以搜索等的实现objectIComparable

朝着相反的方向——从参数类型到它的所有子类——并不那么容易。鉴于object我们需要某种方法来寻找其他一切。

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

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