Ho mappato la mia classe repository alla sua interfaccia e lo stesso vale per i servizi. Qui potrei registrarli manualmente. Ma vorrei che il mio codice mappasse dinamicamente questi in fase di esecuzione in modo che non dovessi registrarli manualmente ogni volta che creo un nuovo repository o servizio. Come posso ottenerlo?
Ecco il mio codice:
public void RegisterDependencies(IServiceCollection services, IConectionSetting connectionSetting)
{
services.AddDbContext<QuantumDbContext>(options => options.UseSqlServer(connectionSetting.Get()));
//services.AddDbContext<TestDbContext>(options => options.UseSqlServer(databaseFactory.ConnectionString));
services.AddTransient<IDatabaseFactory, DatabaseFactory>();
services.AddTransient<IDbContext, TestDbContext>();
services.AddTransient<IDbContext, QuantumDbContext>();
services.AddTransient<IUnitOfWorkManager, UnitOfWorkManager>();
services.AddTransient<IRepository<CodeTable>, Repository<CodeTable>>();
services.AddTransient<IRepository<Country>, Repository<Country>>();
services.AddTransient<IRepository<State>, Repository<State>>();
services.AddTransient<IRepository<City>, Repository<City>>();
services.AddTransient<ICodeTableService, CodeTableService>();
services.AddTransient<ICountryService, CountryService>();
}
Permettetemi di dividere la domanda in due domande:
1- Come registrare e risolvere i tipi generici in asp.net core con la libreria DI integrata?
(vedi Interfaccia generica dell'iniezione delle dipendenze di vNext )
services.AddTransient<IRepository<CodeTable>, Repository<CodeTable>>();
services.AddTransient<IRepository<Country>, Repository<Country>>();
services.AddTransient<IRepository<State>, Repository<State>>();
Puoi semplicemente registrare repository come questo:
services.AddTransient(typeof(IRepository<>), typeof(Repository<>));
2- Come implementare la registrazione batch (basata su convenzioni) in asp.net core con libreria DI integrata? (vedi Associazione basata su convenzione in ASP.NET 5 / MVC 6 )
services.AddTransient<ICodeTableService, CodeTableService>();
services.AddTransient<ICountryService, CountryService>();
Uso il seguente codice per implementare la registrazione in batch e funziona come previsto, ma non sono sicuro che sia valido (potrebbe esserci un codice errato in questa implementazione):
// i assume your service interfaces inherit from IService
Assembly ass = typeof(ICodeTableService).GetTypeInfo().Assembly;
// get all concrete types which implements IService
var allServices = ass.GetTypes().Where(t =>
t.GetTypeInfo().IsClass &&
!t.GetTypeInfo().IsAbstract &&
typeof(IService).IsAssignableFrom(t));
foreach (var type in allServices)
{
var allInterfaces = type.GetInterfaces();
var mainInterfaces = allInterfaces.Except
(allInterfaces.SelectMany(t => t.GetInterfaces()));
foreach(var itype in mainInterfaces)
{
if (allServices.Any(x => !x.Equals(type) && itype.IsAssignableFrom(x)))
{
throw new Exception("The " + itype.Name + " type has more than one implementations, please change your filter");
}
services.AddTransient(itype, type);
}
}