I have this class to be instantiated in a unittest:
public class Customer
{
internal Customer(Guid id) {
// initialize property
}
}
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
But when i setup an autofac container in the other (unittest) assembly
var builder = new ContainerBuilder();
builder.RegisterType<Customer>().AsSelf();
var container = builder.Build();
I can't resolve with autofac.
var theParam = new NamedParameter("id", Guid.NewGuid());
_sut = container.Resolve<Customer>(theParam); // throws exception
My best guess was that the internal constructor was not available. But adding [assembly: InternalsVisibleTo("Autofac")]
next to the other doesn't help.
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'.
Can Autofac not handle internal
constructors?
Autofac can't locate non-public constructors because it uses the DefaultConstructorFinder class which searches only for public constructors by default.
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);
}
}
Then you have to use the FindConstructorsWith
extension method on type registration:
builder.RegisterType<Customer>()
.FindConstructorsWith(new AllConstructorFinder())
.AsSelf();
The InternalsVisibleToAttribute
can't help in this case because it affects only the compile time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With