.NET Core Generic Repository Dependency Injection

Home / .NET Core Generic Repository Dependency Injection

This morning I was updating some Data Models in a project, and noticed, based on my project scheme, that I would have to add a derived BaseRepository class. This is a side-effect of the way I’ve used Ninject for a long time and every IRepository<T> is specified to be a BaseRepository<T>. That pattern is a little annoying, and in some ways, is counter-intuitive when dealing with DI and generics.


Of course, this results in a bunch of derived classes for every IRepository<T> that you plan to use. And, as I said, the derived Repository itself does nothing more than provide a DI hook for the purposes of injecting the proper context into a BaseRepository<T>.

I really just didn’t want to keep following this tedious pattern. With a bit of usage I have under my belt with DI in .NET Core, and Reflection, I have found it to be very easy to inject an interface without knowing the type specification at all, initially. This got me thinking – why can’t I do with this all of my repositories without defining a bunch of derived classes?

It turns out this is easy to achieve. But, one has to be careful with projects that has multiple contexts. With the current .NET Core projects I’ve put together, there is a LoggingContext and a DataProtector context being used in all of my projects (see my other posts about EF based Logger and EF based DataProtector).

Long story short, to facilitate this idea, I created a single derived class from the BaseRepository. I called it DomainRepository. This was necessary so that the injected context type is known.

 
public class DomainRepository<T> : BaseRepository<T> where T : class
{
    public DomainRepository(DbdContext dbContext) : base(dbContext)
    {
    }
}

With only that one class defined, we are then able to use .NET Core DI to get an IRepository/BaseRepository for any with a single line of injection definition:

services.AddScoped(typeof(IRepository<>), typeof(DomainRepository<>));

And voila … no more defining a repository class for every type.. and it doesn’t break the other logging/data protection repositories..

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.