c# - 为什么 AutoFac 的 AsImplementedInterfaces 在另一种类型上会破坏我的解析器?

标签 c# .net dependency-properties autofac

在下面的代码示例中,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/

相关文章:

.net - 使用.Net ServiceInstaller在服务安装上设置 'Start Parameters'吗?

c# - 如何自动设置 DateCreated 和 DateUpdated

c# - 使用 TestStack.White 设置 `VirtualizingPanel.IsVirtualizing`

c# - 绑定(bind)到 IEnumerable<object> 依赖属性

c# - Azure.Data.Tables.TableClient 是线程安全的吗?

c# - Microsoft Unity 容器的性能

c# - C# 中的错误记录

c# - TCP/IP客户端服务器在c#中通过不同网络进行通信

c# - 在 VS2017 中将依赖程序集包含到 NuGet 包中

c# - 如何在自定义控件的 View 模型中绑定(bind)依赖属性