注册使用Autofac实现变体通用接口的具体类型

时间:2013-02-05 21:01:59

标签: c# generics autofac covariance

考虑使用Autofac 3.0.0将结构作为注册主题:

class Something
{
    public int Result { get; set; }
}

class SomethingGood : Something
{
    private int _good;
    public int GoodResult {
        get { return _good + Result; }
        set { _good = value; }
    }
}

interface IDo<in T> where T : Something
{
    int Calculate( T input );
}

class MakeSomethingGood : IDo<SomethingGood>
{
    public int Calculate( SomethingGood input ) {
        return input.GoodResult;
    }
}

class ControlSomething
{
    private readonly IDo<Something> _doer;
    public ControlSomething( IDo<Something> doer ) {
        _doer = doer;
    }

    public void Show() {
        Console.WriteLine( _doer.Calculate( new Something { Result = 5 } ) );
    }
}

我正在尝试注册具体类型MakeSomethingGood,然后通过逆变接口解决它。

var builder = new ContainerBuilder();
builder.Register( c => new MakeSomethingGood() ).As<IDo<SomethingGood>>();
builder.Register( c => new ControlSomething( c.Resolve<IDo<Something>>() ) ).AsSelf();

var container = builder.Build();
var controller = container.Resolve<ControlSomething>();

...而Resolve失败,因为找不到IDo<Something>

的组件

我做错了什么?

谢谢

1 个答案:

答案 0 :(得分:1)

您注册IDo<SomethingGood>并尝试解析IDo<Something>。这怎么可能有用?为此,IDo<T>应定义为协变:IDo<out T>

由于IDo<in T>被定义为逆变(使用in关键字),因此您无法简单地将IDo<SomethingGood>分配给IDo<Something>。这不会在C#中编译:

IDo<SomethingGood> good = new MakeSomethingGood();

// Won't compile
IDo<Something> some = good;

这就是为什么Autofac无法解决它,即使使用ContravariantRegistrationSource