Autofac:使用输入和输出类型参数解析变量类型 [英] Autofac: Resolving variant types with both in and out type arguments

查看:85
本文介绍了Autofac:使用输入和输出类型参数解析变量类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题是我之前的问题的后续解答: Autofac:在一个复合物后面隐藏多个逆变实现.

This question is a follow up of my previous question: Autofac: Hiding multiple contravariant implementations behind one composite.

我正在尝试寻找Autofac的协方差和逆方差支持所能做的工作的界限.我注意到,Autofac的ContravariantRegistrationSource仅支持带有单个通用参数的通用接口,该通用参数用in关键字标记.这似乎限制了此功能的实用性,我想知道Autofac是否还有其他方法可以扩展对协方差和逆方差的支持.

I'm trying to find the boundries of what we can do with Autofac's covariance and contravariance support. I noticed that Autofac's ContravariantRegistrationSource only supports generic interfaces with a single generic parameter that is marked with the in keyword. This seems to limit the usefulness of this feature, and I'm wondering if Autofac has other ways in extending the support of covariance and contravariance.

我必须承认,我并不是在问这个问题,因为我正在从事一个真正的应用程序设计.为了教育起见,我刻意尝试查找Autofac的限制.

I must admit that I'm not asking this because of a real application design I'm working of. I'm deliberately trying to find Autofac's limits for the sake of education.

因此请考虑以下界面:

public interface IConverter<in TIn, out TOut>
{
    TOut Convert(TIn value);
}

以及以下实现:

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

以及以下注册方法:

var builder = new ContainerBuilder();

builder.RegisterSource(new ContravariantRegistrationSource());

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

var container = builder.Build();

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

With this design and configuration, I'd expect to be able to do this:

// 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>>();

或者让我用给定的定义将其抽象化:

Or let me put it more abstractly, with the given definitions:

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

public class AToCConverter : IConverter<A, C> { ... }

以及以下注册:

builder.RegisterType<AToCConverter>()
    .As<IConverter<C, A>>();

我希望以下调用能够成功:

I would expect the following calls to succeed:

container.Resolve<IConverter<C, A>>();
container.Resolve<IConverter<B, B>>();
container.Resolve<IConverter<A, C>>();

我们如何使用Autofac做到这一点?

How can we do this with Autofac?

推荐答案

我认为这是我们在Autofac中不太可能克服的局限性,但值得探索.

I think this is a limitation we're unlikely to overcome in Autofac, but it is interesting to explore.

我们可以做反变的解析",因为给定一个泛型类型参数,我们可以找到该参数可分配给的所有基类/接口类型.也就是说,给定string,我们可以搜索objectIComparable等的实现.

We can do contravariant 'resolve' because given a generic type argument we can find all of the base/interface types to which that argument would be assignable. That is, given string we can search for implementations for object, IComparable etc.

相反的方向-从参数类型到其所有子类-并不是那么容易.给定object,我们需要某种方式来查找其他所有内容.

Going in the opposite direction - from an argument type to all of its subclasses - isn't so easy. Given object we'd need some way to look for everything else.

有可能使用容器中注册的混凝土成分的知识,例如扫描所有组件以寻找可能的实现并向后工作,但这对Autofac而言并不好,因为在许多情况下,我们依靠拉"模型懒惰地创建组件.

It may be possible to use knowledge of the concrete components registered in the container, e.g. scan all components looking for possible implementations and work backwards, but this isn't great for Autofac because we rely on a 'pull' model to lazily create components in many cases.

希望这是值得深思的,有兴趣了解您的想法.

Hope this is food for thought, interested to see what you come up with.

这篇关于Autofac:使用输入和输出类型参数解析变量类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆