我有一个要在单元测试中实例化的类:
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
构造函数吗?
答案 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。对不起,我的英语。