如何在AutoFac上使用内部构造函数解析公共类

时间:2018-10-13 12:44:20

标签: autofac

我有一个要在单元测试中实例化的类:

public class Customer
{
    internal Customer(Guid id) {
        // initialize property
    }
}

如果我使用new Customer()从另一个(单元测试)程序集中实例化测试类,则是因为我添加了[assembly: InternalsVisibleTo("MyProject.Tests")]

var sut = new Customer(Guid.NewGuid()); // works

但是当我在另一个(单元测试)程序集中设置一个autofac容器时

var builder = new ContainerBuilder();
builder.RegisterType<Customer>().AsSelf();
var container = builder.Build();

我无法使用autofac解决。

var theParam = new NamedParameter("id", Guid.NewGuid());
_sut = container.Resolve<Customer>(theParam); // throws exception

我最好的猜测是内部构造函数不可用。但是在彼此之间添加[assembly: InternalsVisibleTo("Autofac")]并没有帮助。

Autofac抛出的异常是

Autofac.Core.DependencyResolutionException: 
An error occurred during the activation of a particular registration. See the inner exception for details. 
Registration: Activator = Customer (ReflectionActivator), 
Services = [MyProject.Customer], 
Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, 
Sharing = None, 
Ownership = OwnedByLifetimeScope 
---> No accessible constructors were found for the type 'MyProject.Customer'. 

Autofac不能处理internal构造函数吗?

1 个答案:

答案 0 :(得分:6)

Autofac无法找到非公共构造函数,因为它使用DefaultConstructorFinder类,该类默认情况下仅搜索公共构造函数。

您必须像这样创建IConstructorFinder接口的自定义实现:

public class AllConstructorFinder : IConstructorFinder 
{ 
    private static readonly ConcurrentDictionary<Type, ConstructorInfo[]> Cache =
        new ConcurrentDictionary<Type, ConstructorInfo[]>();


    public ConstructorInfo[] FindConstructors(Type targetType)
    {
        var result = Cache.GetOrAdd(targetType,
            t => t.GetTypeInfo().DeclaredConstructors.ToArray());

        return result.Length > 0 ? result : throw new NoConstructorsFoundException();
    } 
} 

然后您必须在类型注册中使用FindConstructorsWith扩展方法:

builder.RegisterType<Customer>()
   .FindConstructorsWith(new AllConstructorFinder())
   .AsSelf();

InternalsVisibleToAttribute在这种情况下无济于事,因为它仅影响编译时间。

P.S。对不起,我的英语。