Reputation: 509
I have custom DbContext which inherits from IdentityDbContext. Class looks like this:
public class ReaderContext : IdentityDbContext<IdentityUser>
{
//DbSets
public ReaderContext()
: base("name=ReaderDb")
{
System.Data.Entity.Database.SetInitializer<ReaderContext>(null);
Database.Initialize(true);
}
}
And when DbContext looks like this, code creating Repository (which is using ReaderContext) works fine:
container.RegisterType<IRepository, CustomRepository>(new HierarchicalLifetimeManager());
var repo = container.Resolve<IRepository>();
When I add another constructor (not removing existing one!) to ReaderContext, creating CustomRepository not works any more in UnityContainer.
public ReaderContext(DbConnection connection)
: base(connection, true)
{
}
I need to have it that way, so I can moq context with Effort. I'm using Unity container. Exception I'm having:
2017-08-07 19:02:57.9256 : Exception : Microsoft.Practices.Unity.ResolutionFailedException: Resolution of the dependency failed, type = "DataAccess.Database.Repositores.IRepository", name = "(none)". Exception occurred while: while resolving. Exception is: InvalidOperationException - The current type, System.Data.Common.DbConnection, is an abstract class and cannot be constructed. Are you missing a type mapping? ----------------------------------------------- At the time of the exception, the container was:
Resolving DataAccess.Database.Repositores.CustomRepository,(none) (mapped from DataAccess.Database.Repositores.IRepository, (none))
Resolving parameter "context" of constructor DataAccess.Database.Repositores.CustomRepository(DataAccess.Database.ReaderContext context) Resolving DataAccess.Database.ReaderContext,(none) Resolving parameter "connection" of constructor DataAccess.Database.ReaderContext(System.Data.Common.DbConnection connection) Resolving System.Data.Common.DbConnection,(none) ---> System.InvalidOperationException: The current type, System.Data.Common.DbConnection, is an abstract class and cannot be constructed. Are you missing a type mapping?
Why adding new constructors break unity configuration? Also, I tried set unity from scratch but coudn't make it work. Probably I don't know how unity works, so any tips are welcome :)
Upvotes: 1
Views: 2371
Reputation: 22655
By default Unity will select the constructor with the greatest number of parameters. So, initially the parameterless constructor was used and everything was fine.
However, when you added the ReaderContext(DbConnection connection)
constructor that constructor was now the constructor with the greatest number of arguments so Unity chose to use it. For that constructor, Unity saw it needed a DbConnection
but, as the exception message indicates, DbConnection
is abstract so Unity could not instantiate it and there was no type mapping from the abstract DbConnection
to a concrete non-abstract class that Unity could instantiate.
The solution is to explicitly tell Unity what you want it to do. If you want to use the parameterless constructor you would do it by providing an InjectionConstructor
with no arguments:
container.RegisterType<ReaderContext>(new InjectionConstructor());
If you wanted to use the DbConnection
constructor you would either have to explicitly configure Unity with how to construct a ReaderContext
or configure Unity with how to resolve the abstract DbConnection
. I would typically use the latter approach and configure the mappings and let Unity build the object graph:
container.RegisterType<DbConnection, SqlConnection>(
new InjectionFactory(c => new SqlConnection("connectionString")));
Upvotes: 8