Trabajando en un servicio API de solo lectura y haciendo uso de genéricos para empaquetar la operación en un proceso basado en convenciones.
Interfaz del repositorio:
public interface IRepository<TIdType,TEntityType> where TEntityType:class { Task<EntityMetadata<TIdType>> GetMetaAsync(); }Implementación del repositorio:
public class Repository<TIdType,TEntityType> : IRepository<TIdType,TEntityType> where TEntityType:class { public Repository(string connectionString) { // initialization } public async Tas<EntityMetadata<TIdType>> GetMetaAsync() { // implementation } } En Startup.cs -> ConfigureServices :
services.AddSingleton<IRepository<int, Employee>> ( p=> new Repository<int, Employee>(connectionString)); services.AddSingleton<IRepository<int, Department>> ( p=> new Repository<int, Department>(connectionString)); // and so onControlador:
public class EmployeeController : Controller { public EmployeeController(IRepository<int,Employee> repo) {//stuff} } Actualmente estoy repitiendo la implementación del repositorio para todos los tipos de entidades en ConfigureServices . ¿Hay alguna manera de hacer esto genérico también?
services.AddSingleton<IRepository<TIdType, TEntityType>> ( p=> new Repository<TIdType, TEntityType>(connectionString));Entonces, en la llamada del constructor del controlador, ¿puede obtener automáticamente el repositorio relevante?
Actualización 1 : No es un duplicado :
services.AddScoped(typeof(IRepository<>), ...) recibo un error. Using the generic type 'IRepostiory<TIdType,TEntityType>' requires 2 type argumentsDado que esta pregunta aún no está marcada correctamente como duplicada : la forma de registrar una clase genérica:
services.AddScoped(typeof(IRepository<,>), typeof(Repository<,>));ahora puedes resolverlo de la siguiente manera:
serviceProvider.GetService(typeof(IRepository<A,B>)); // or: with extensionmethod serviceProvider.GetService<IRepository<A,B>>();