为什么AutoFac的AsImplementedInterfaces破坏了我在另一种类型的解析器?

bri*_*anc 4 .net c# dependency-properties autofac

在下面的代码示例中,Debug.Assert将失败.

如果从IBreaker注册中删除了AsImplementedInterfaces()扩展,则foo.Bar将不为null.为什么会这样?

using System;
using System.Diagnostics;
using System.Reflection;
using Autofac;

namespace AutoFacTest
{
class Program
{
    static void Main(string[] args)
    {
        var builder = new ContainerBuilder();

        var thisAssembly = Assembly.GetExecutingAssembly();

        builder.RegisterAssemblyTypes(typeof(IFoo<>).Assembly, thisAssembly).AsClosedTypesOf(typeof(IFoo<>))
                .AsImplementedInterfaces().PropertiesAutowired().InstancePerDependency();

        builder.RegisterAssemblyTypes(typeof(IBar<>).Assembly, thisAssembly)
               .AsClosedTypesOf(typeof(IBar<>)).AsImplementedInterfaces().InstancePerDependency();

        builder.RegisterAssemblyTypes(typeof(IBreaker).Assembly, thisAssembly).InstancePerDependency()
                .AsImplementedInterfaces(); //<------ will work if this is removed

        var container = builder.Build();

        var foo = container.Resolve<IFoo<int>>();

        Debug.Assert(foo.Bar!=null);

        Console.ReadLine();
    }
}

public interface IBreaker {}

public class BreakerImpl<T> : IBreaker {}

public class BarImpl : IBar<int>{}

public class FooImpl : IFoo<int>
{
    public IBar<int> Bar { get; set; }
}

public interface IFoo<T>
{
    IBar<T> Bar { get; set; }
}

public abstract class Foo<T> : IFoo<T>
{
    public IBar<T> Bar { get; set; }
}

public interface IBar<T>{}

public abstract class Bar<T> : IBar<T> {}
}
Run Code Online (Sandbox Code Playgroud)

Pet*_*old 9

您的注册存在一些问题.首先,了解RegisterAssemblyTypes它是如何工作的:它需要一个程序集并发现该程序集中的所有类,并向构建器注册类型.您可以进一步扩充调用AsXYZ以控制每个类型在最终容器中的键控方式.

现在,在您的示例中,每次注册所有类型时,您都会执行此操作三次,每次都有不同的扩充.您注册所有类型的前两个注册为特定接口的封闭类型.第三次,您再次注册相同类型但现在不是封闭类型,有效地打破了以前的注册.

解决方案是使用Where扩充来限制每次注册类型的范围,以便相同类型不会使用不同的扩充注册多次.