如何在AutoFac上使用内部构造函数解析公共类 [英] How to resolve public class with internal constructor on AutoFac

查看:92
本文介绍了如何在AutoFac上使用内部构造函数解析公共类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have this class to be instantiated in a unittest:

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

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

If I instantiate the test class from another (unittests) assembly with a new Customer() works because I added [assembly: InternalsVisibleTo("MyProject.Tests")]

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

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

But when i setup an autofac container in the other (unittest) assembly

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

我无法使用autofac解决.

I can't resolve with autofac.

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

我最好的猜测是内部构造函数不可用.但是在另一个旁边添加 [assembly:InternalsVisibleTo("Autofac")] 并没有帮助.

My best guess was that the internal constructor was not available. But adding [assembly: InternalsVisibleTo("Autofac")] next to the other doesn't help.

Autofac抛出的异常是

The exception thown by Autofac is

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不能处理内部构造函数吗?

Can Autofac not handle internal constructors?

推荐答案

Autofac无法定位非公共构造函数,因为它使用

Autofac can't locate non-public constructors because it uses the DefaultConstructorFinder class which searches only for public constructors by default.

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

You have to create your custom implementation of the IConstructorFinder interface like this:

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.Where(c => !c.IsStatic).ToArray());

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

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

Then you have to use the FindConstructorsWith extension method on type registration:

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

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

The InternalsVisibleToAttribute can't help in this case because it affects only the compile time.

这篇关于如何在AutoFac上使用内部构造函数解析公共类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆