在下面的代码示例中,Debug.Assert 将失败。
如果 AsImplementedInterfaces() 扩展从 IBreaker 注册中删除,foo.Bar 将不会为空。为什么会这样?
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> {}
}
最佳答案
您的注册有几个问题。首先,了解 RegisterAssemblyTypes
的工作原理:它获取一个程序集并发现该程序集中的所有类,并向您的构建器注册这些类型。您可以使用 AsXYZ
进一步扩充调用,以控制每种类型在最终容器中的键控方式。
现在,在您的示例中,您将执行三次此操作,每次使用不同的扩充,每次您都将注册所有类型。前两个注册是将所有类型注册为特定接口(interface)的封闭类型。第三次,您再次注册相同的类型,但现在不是封闭类型,有效地打破了之前的注册。
解决方案是使用Where
扩充来限制每次注册哪些类型的范围,这样相同的类型就不会被不同的扩充注册多次。
关于c# - 为什么 AutoFac 的 AsImplementedInterfaces 在另一种类型上会破坏我的解析器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10440111/