问题
On trying to resolve my service class, I'm getting an error that DbContext
cannot be constructed because it's an abstract class. The error message is here:
Unity.Exceptions.ResolutionFailedException: 'Resolution of the dependency failed, type = 'MyService.MyClass', 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 ...
...
Resolving MyApp.MyRepository,(none)
Resolving parameter 'myDbContext' of constructor MyApp.MRepository(MyApp.IMyDbContext myDbContext)
...
Resolving parameter 'existingConnection' of constructor MyApp.MyDbContext(System.Data.Common.DbConnection existingConnection, System.Data.Entity.Infrastructure.DbCompiledModel model, System.Boolean contextOwnsConnection)
Resolving System.Data.Common.DbConnection,(none)
'
The DBContext looks like this:
public class MyDbContext : System.Data.Entity.DbContext, IMyDbContext
{
public MyDbContext()
: base("MainConnectionString")
{
}
My guess is that EF looks for a connection string in the config file; but the connection string is defined:
<connectionStrings>
<add name="MainConnectionString" connectionString="Server=.\SQLEXPRESS;Database=MyDB;User Id= . . ." providerName="System.Data.SqlClient" />
</connectionStrings>
Unity Registration:
My question, therefore, is how does EF work out how to construct this class, as clearly I'm missing something in the configuration.
UnityContainer container = new UnityContainer();
container.RegisterType<IMyDbContext, MyDbContext>();
container.RegisterType<IMyRepository, MyRepository>();
container.RegisterInstance<IUnityContainer>(container);
回答1:
As per this answer:
Unity will resolve a concrete type (.Resolve), but interfaces have to be explicitly registered by associating them with concrete types.
So, you have 2 choices:
- Register the
IMyDbContext
interface with Unity - Stop using
IMyDbContext
and use the concrete type (in which case Unity will resolve it automatically, although you may need to do it manually to control the lifetime)
Note the primary intent of using an interface with DI is to be able to swap implementations, so if your application is not actually swapping in one identical database schema for another, you probably don't need the interface in this case.
回答2:
I managed to get this working, by changing the registration to explicitly pass the connection string name:
UnityContainer container = new UnityContainer();
container.RegisterType<IMyDbContext, MyDbContext>(new InjectionConstructor("MainConnectionString"));
. . .
container.RegisterInstance<IUnityContainer>(container);
来源:https://stackoverflow.com/questions/48516702/entity-framework-error-when-using-unity