Nel tentativo di risolvere la mia classe di servizio, ricevo un errore che non è possibile DbContext
perché è una classe astratta. Il messaggio di errore è qui:
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)
'
Il DBContext si presenta così:
public class MyDbContext : System.Data.Entity.DbContext, IMyDbContext
{
public MyDbContext()
: base("MainConnectionString")
{
}
La mia ipotesi è che EF cerchi una stringa di connessione nel file di configurazione; ma la stringa di connessione è definita:
<connectionStrings>
<add name="MainConnectionString" connectionString="Server=.\SQLEXPRESS;Database=MyDB;User Id= . . ." providerName="System.Data.SqlClient" />
</connectionStrings>
Registrazione di unità:
La mia domanda, quindi, è come fa EF a capire come costruire questa classe, poiché chiaramente mi manca qualcosa nella configurazione.
UnityContainer container = new UnityContainer();
container.RegisterType<IMyDbContext, MyDbContext>();
container.RegisterType<IMyRepository, MyRepository>();
container.RegisterInstance<IUnityContainer>(container);
Sono riuscito a farlo funzionare, cambiando la registrazione per passare esplicitamente il nome della stringa di connessione:
UnityContainer container = new UnityContainer();
container.RegisterType<IMyDbContext, MyDbContext>(new InjectionConstructor("MainConnectionString"));
. . .
container.RegisterInstance<IUnityContainer>(container);
Secondo questa risposta :
Unity risolverà un tipo concreto (.Resolve), ma le interfacce devono essere esplicitamente registrate associandole a tipi concreti.
Quindi, hai 2 scelte:
IMyDbContext
con Unity IMyDbContext
e usa il tipo concreto (nel qual caso Unity lo risolverà automaticamente, anche se potresti aver bisogno di farlo manualmente per controllare la durata) Si noti che l'intento principale di utilizzare un'interfaccia con DI è quello di essere in grado di scambiare le implementazioni , quindi se l'applicazione non si sta effettivamente scambiando in uno schema di database identico per un altro, in questo caso probabilmente non è necessaria l'interfaccia.