Repository generico in ASP.NET Core senza avere una riga AddScoped separata per tabella in Startup.cs?

Ho un repository generico nel mio progetto. Considera il seguente frammento di controller

public class Lookup1Controller : Controller { readonly MyDbContext _db; public Lookup1Controller(MyDbContext dataContext) { _db = dataContext; } public async Task Index() { IGenericRepository _repository = new GenericRepository(_db); var lookup1s = await _repository.SelectAll(); return View(lookup1s); } 

Non vedo la necessità di avere il mio riferimento del database sia nel mio repository generico che in ciascuno dei miei controller.

Lo refactoring a:

 public class Lookup1Controller : Controller { private IGenericRepository _repository; public Lookup1Controller(IGenericRepository repository) { _repository = repository; } public async Task Index() { var lookup1s = await _repository.SelectAll(); return View(lookup1s); } } 

che è molto più ordinato e le migliori pratiche di ASP.NET 5 da ciò che ho letto. ma otterrò il seguente errore se accedo al percorso del controller nel mio browser:

 InvalidOperationException: Unable to resolve service for type 'MyProject.Data.IGenericRepository`1[MyProject.Models.Lookup1]' while attempting to activate 'MyProject.Controllers.Lookup1. 

a causa di non ho iniettato il GenericRepository per utilizzare l’interfaccia.

Aggiungo alla mia Startup.cs una riga AddScoped per ciascuna delle mie tabelle nel metodo ConfigureServices

 services.AddScoped<IGenericRepository,GenericRepository> (); services.AddScoped<IGenericRepository,GenericRepository> (); services.AddScoped<IGenericRepository,GenericRepository> (); services.AddScoped<IGenericRepository,GenericRepository> (); etc 

in modo che il mio codice venga eseguito senza generare un’eccezione.

Tuttavia il mio database ha circa 100 tabelle di ricerca semplici. Quando guardo le 100 linee di codice di cui sopra, non sembra giusto.

Sembra copiare e incollare il codice. Ogni volta che aggiungo una nuova tabella aggiungendo un nuovo modello e controller con vista il mio codice verrà compilato senza darmi un errore. Ma se eseguo il programma e vado a quella vista, potrei ottenere l’errore di esecuzione del controller se mi sono dimenticato di aggiungere la riga AddScoped al mio Startup.cs . Non proprio buono per la mantenibilità.

La mia domanda:

  1. È davvero consigliabile disporre di un servizio. AddScoped per ciascuna tabella di ricerca nel metodo ConfigureServices di Startup.cs ?

  2. È un repository generico, quindi non c’è un modo per scrivere quelle 100 righe copia e incolla in una riga?

  3. In caso contrario, qual è il modo migliore per farlo usando il mio codice?

Basta usare gli overload di registrazione non generici (quelli in cui è necessario passare i 2 oggetti Type ). Quindi fornire i tipi generici aperti sia dell’interfaccia che dell’implementazione:

 services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>)); 

Nel controller aggiungere una dipendenza per un repository di un tipo specifico (un tipo generico chiuso)

 public HomeController(IGenericRepository repository) { ... }