I've been looking at implementing these patterns in a project I am working on. The UoW has the database context and then instantiates a number of repositories with that context. My question is to do with disposing the context. A lot of articles I have seen have the repository as IDisposable and they then dispose of the context. This has confused me no end, am I missing something or (in my case) should it just be the UoW that disposes of the context? Also, should I be implementing IDisposable on my repositories?
Thanks
Chris
The unit of work class coordinates the work of multiple repositories by creating a single database context class shared by all of them. If you wanted to be able to perform automated unit testing, you'd create and use interfaces for these classes in the same way you did for the Student repository.
A DbContext instance represents a combination of the Unit Of Work and Repository patterns such that it can be used to query from a database and group together changes that will then be written back to the store as a unit.
The Unit of Work is a type of business transaction, and it will aggregate all Repository transactions (CRUD) into a single transaction. Only one commit will be made for all modifications. If any transaction fails to assure data integrity, it will be rolled back.
The Unit of Work pattern is used to aggregate multiple operations into a single transaction. With this we ensure that either all operations succeed or fail as a single unit. Note that you can use the Repository pattern without using the Unit of Work pattern.
Yes, the Unit of Work should implement IDisposable
and dispose the context, not the repositories.
Here's one example:
public interface IUnitOfWork : IDisposable
{
void Commit();
}
public class EntityFrameworkUnitOfWork<TContext> : IUnitOfWork
where TContext : DbContext, new()
{
public EntityFrameworkUnitOfWork()
{
this.DbContext = new TContext();
ConfigureContext(this.DbContext);
}
protected virtual void ConfigureContext(TContext dbContext)
{
dbContext.Configuration.ProxyCreationEnabled = false;
dbContext.Configuration.LazyLoadingEnabled = false;
dbContext.Configuration.ValidateOnSaveEnabled = false;
}
protected TContext DbContext { get; private set; }
public void Commit()
{
this.DbContext.SaveChanges();
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposing)
{
return;
}
if (this.DbContext == null)
{
return;
}
this.DbContext.Dispose();
this.DbContext = null;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With