Johan Herstad
Johan Herstad

Reputation: 692

How dependency injection is instantiated using Unit of Work?

I was looking to implement the Repository pattern with unit of work in my asp.net core 2.0 app. There are not many examples of doing this using the dependency injection (DI) principle being used in .net core. I tried to rewrite this example found in the docs. I also tried to add async operations where I could.

Now the idea is that the unit of work passes it's own dbcontext to the GenericRepository for each of the entities that is in use. This then makes sure that you ony use one dbcontext even if you work on two entities.

In my controller I fetch some data like this:

var model = new IndexViewModel
{
      Companies = await _unitOfWork.CompanyRepository.GetAsync()          
};

In my unit of work the dbcontext is being created using DI. Then it creates new instances of the GenericRepository for each entity while it passes it's dbcontext to the genericrepository's contructor:

private ApplicationDbContext _context;
private GenericRepository<Company> companyRepository;
private GenericRepository<Person> personRepository;        

public UnitOfWork(ApplicationDbContext context)
{
    _context = context;
}

public GenericRepository<Company> CompanyRepository
{
    get
    {
        if (this.companyRepository == null)
        {
            this.companyRepository = new GenericRepository<Company>(_context);
        }
        return companyRepository;
    }
}

//repeat for Person

But I fear the dependency injection will automatically create a new dbcontext for each time I use the GenericRepository.

public class GenericRepository<TEntity> where TEntity : class
{
    internal ApplicationDbContext _context;
    internal DbSet<TEntity> dbSet;

    public GenericRepository(ApplicationDbContext context)
    {
        _context = context;
        dbSet = context.Set<TEntity>();
    }
     //...other methods
}

I fear this will actually create two contexts. one for each(if two requests are made)? So in reality the dbcontext would be instantiated three times, one in unitofwork then one for each repository? Here is a link to the app on github. It is working, but I want to understand how this works. Thanks for any answers!

Upvotes: 2

Views: 5402

Answers (1)

Tseng
Tseng

Reputation: 64150

It all depends on how you register your DbContext and which lifetime you use.

The default overload of .AddDbContext will always register the DbContext with scoped lifetime. That means it will create one instance per request.

If you make it transient, it will create one instance per resolve and singleton one instance per application lifetime.

That should be true for most cases.

However, if you have a service which has a higher lifetime than its dependencies (i.e. a singleton and inject a scoped service), then the above is not true and you have to be careful when you design and do your registration and take this into consideration.

Upvotes: 4

Related Questions