Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Repository Interface that uses Generics with Dependency Injection?

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:

  1. Is this OK?
  2. If not where am I lost on this concept?
  3. Even if this is proper, what's the point of Unity to register Interface to concrete type? I've already done it because the generic repository forced me on declaration.

Please help clear this up for me, and I appreciate all your help!

like image 629
atconway Avatar asked Jan 16 '13 18:01

atconway


People also ask

How does interface help dependency injection?

Interface Injection is similar to Getter and Setter DI, the Getter, and Setter DI use default getter and setter but Interface Injection uses support interface a kind of explicit getter and setter which sets the interface property.

How do I create a generic repository?

To implement generic repository pattern, create two projects - one is an ASP.NET Core Web Application and another is a class library project, which are GR. Web and GR. Data respectively in the solution. The class library is named as SA.

Which contains generic methods for frequently used CRUD operations?

MVC 5 with Entity Framework scaffolding has created method stubs which contains all the CRUD operations related to Student Entity.


1 Answers

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.

like image 160
Nick Avatar answered Sep 18 '22 08:09

Nick