I am attempting to use the following Generic Repository Interface for DI and constructor injection:
public interface IRepository<TEntity> : IDisposable where TEntity : class
The problem is in order to define an instance of the Interface, I must provide the class type like this:
private IRepository<Person> _personRepository;
The issue with this is if I'm using DI (and I'm using Unity for IoC framework), then I have to define multiple instances in my constructor to get all repository interfaces I need to work with like this:
public MyClass(IRepository<Person> personRepository,
IRepository<Orders> ordersRepository,
IRepository<Items> itemsRepository,
IRepository<Locations> locationsRepository)
{
_personRepository = personRepository;
_OrdersRepository = ordersRepository;
_itemsRepository = itemsRepository;
_locationsRepository = locationsRepository;
}
Questions:
Please help clear this up for me, and I appreciate all your help!
As noted by D Stanley, a dependency must be a concrete interface. Otherwise, where are you going to declare T? Your dependent class could be generic, but you still have to say "T is a Person" at some point.
That said, Unity handles registering generic types pretty nicely.
Let's say you implement IRepository<T>
with a generic class Repository<T>
that wraps a DbSet<T>
(or whatever).
The following registration and resolves will then work (which includes injecting into any constructors):
container.RegisterType(typeof(IRepository<>), typeof(Repository<>));
// no specific registration needed for the specific type resolves
container.Resolve(<IRepository<Person>);
container.Resolve(<IRepository<Order>);
If you needed a specific override of a type (says the Items repository is special for whatever reason so it has a fully implemented ItemRepository
class), just register that specific implementation after the generic one:
container.RegisterType<IRepository<Item>, ItemRepository>();
Resolving IRespository<Item>
will now get your specific implementation.
For the record, I think this can only be done in code, and not configuration files. Someone feel free to correct that assumption.