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:

    <add name="MainConnectionString" connectionString="Server=.\SQLEXPRESS;Database=MyDB;User Id= . . ." providerName="System.Data.SqlClient" />

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>();
1/30/2018 1:28:37 PM

Accepted Answer

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"));
. . .
1/30/2018 1:30:17 PM

Popular Answer

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:

  1. Register the IMyDbContext interface with Unity
  2. 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.

Related Questions


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow