Lifetime of DataContext, LinqToSql - c#

I have found on the Internet an article which presents how to implement repository pattern. The implementation looks similar like here:
class ProductRepository : IProductRepository
{
var context;
public ProductRepository() {
this.context = new MyDataBaseDataContext();
}
// the rest of methods
}
But Im not quite sure is this right, what is happened with context? Is the Garbage Collector dispose this object? Or better should I create context with using (...) { } statement?

Repository should not open a data context, DataContext must be passed to it - since it must not own it. Let's say you have an operation which needs to be in a transaction and involves multiple repositories, what would you do?
You need to use UnitOfWork pattern.
In this pattern, a UoW (which wraps a DataContext) is passed to a repository.
Practically, ProductManager in Business layer creates a Unit Of Work.

The simple answer to this question is that the repository should be sure to dispose the data context itself, rather than letting it be finalized by the .NET runtime. This can be achieved by following the standard .NET dispose pattern...
class ProductRepository : IProductRepository, IDisposable
{
var context;
public ProductRepository() {
this.context = new MyDataBaseDataContext();
}
// the rest of methods
public void Dispose()
{
if (context != null)
{
context.Dispose();
context = null;
}
}
}

I guess it depends on whether you need transactions across repository operations and your need for tracking changes. The data datacontext can be immensely helpful since it can let you retrieve a bunch of objects, modify them in the application and then simply call SubmitChanges /RollbackChanges at any time you see fit. But if you don't expose this functionality in your repository you are probably better off by just "using" an instance in each repository method since this will preserve memory usage and resources for tracking changes.

Related

Should repositories be properties on the unit of work when using Entity Framework?

I have scoured the web looking for a good implementation of the Repository/Unit of Work pattern using Entity Framework. Everything I've come across is either tightly coupled at some point in the abstraction or assumes that the DbContext used by the Unit of Work and Repositories is shared and should live for the entire HTTP request (instance per request via dependency injection).
For example, assuming you are consuming repositories from the service layer, a service constructor might look like this:
public DirectoryService(IUnitOfWork unitOfWork, ICountryRepository countryRepo, IProvinceRepository provinceRepo)
{
/* set member variables... */
}
The unit of work constructor might look like:
public UnitOfWork(IDbContext context)
{
_context = context;
}
And a repository constructor might look like:
CountryRepository(IDbContext context)
{
_context = context;
}
This solution makes the blind assumption that the Dependency injection is setting up the Unit of Work and Repositories to share the same IDbContext using instance per request. Is that really a safe assumption to make?
If you are using dependency injection with instance per request, the same IDbContext will be injected into multiple units of work. The unit of work is no longer atomic, is it? I might have pending changes in one service that are then committed in another service because the context is shared across multiple units of work.
To me it seems to make more sense to set up a IDbContextFactory and get a fresh database context with each unit of work.
public interface IDbContextFactory
{
IDbContext OpenContext();
}
public class UnitOfWork
{
private IDbContextFactory _factory;
private IDbContext _context;
UnitOfWork(IDbContextFactory factory)
{
_factory = factory;
}
internal IDbContext Context
{
get { return _context ?? (_context = _factory.OpenContext()); }
}
}
The problem then becomes, how do I make my Unit of Work implementation available to the injected repositories? I don't want to assume instance per request because then I'm right back in the same boat I started in.
The only thing I can think of is to follow Entity Framework's lead and make the repositories (IDbSet<T>) part of the unit of work (DbContext).
So then I might have units of work that look like this:
public class DirectoryUnitOfWork : IDirectoryUnitOfWork
{
private IDbContextFactory _factory;
private IDbContext _context;
public DirectoryUnitOfWork(IDbContextFactory factory)
{
_factory = factory;
}
protected IDbContext Context
{
get { return _context ?? (_context = _factory.OpenContext()); }
}
public ICountryRepository CountryRepository
{
get { return _countryRepo ?? (_countryRepo = new CountryRepository(Context)); }
}
public IProvinceRepository ProvinceRepository
{
get { return _provinceRepo ?? (_provinceRepo = new ProvinceRepository(Context)); }
}
void Commit()
{
Context.SaveChanges();
}
}
Then my Directory service starts to look like this
public class DirectoryService : IDirectoryService
{
private IDirectoryUnitOfWork _unitOfWork;
public DirectoryService(IDirectoryUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public GetCountry(int id)
{
return _unitOfWork.CountryRepository.GetById(id);
}
public GetProvince(int id)
{
return _unitOfWork.ProvinceRepository.GetById(id);
}
public void AddProvince(Province province)
{
_unitOfWork.ProvinceRepository.Create(province);
Country country = GetCountry(province.CountryId);
country.NumberOfProvinces++; // Update aggregate count
_unitOfWork.Commit();
}
/* ... and so on ... */
}
It seems like a lot of work, but using this method leaves everything loosely coupled and unit testable. Am I missing an easier way, or is this a good way to do it if I am going to abstract away Entity Framework?
You should never abstract an ORM (itself an abstraction), but you should abstract the Persistence. The only UoW I'm using is a db transaction and that's a persistence detail. You don't need to use UoW and Repository together. You should think if you really need all this stuff.
Personally, I'm using the repository by default because Persistence is the last thing I do in an app. I don't care about patterns per se , I do care about decoupling my BL or the UI from DAL. Your upper layers (everything except DAL, which is the lowest layer from a dependency point of view) should always know about an abstraction, so that you can go as wild as you want in the DAL implementation.
One trick a lot of devs don't know is that design patterns (especially architectural ones) should be treated as a high level principle first and as a technical know-how second. Simply put, the thing that matters the most is the benefit a pattern is trying to achieve (the principle, the bigger picture), not its actual implementation (the "low level" details).
Ask yourself why should the BL know about a UoW in the first place. The BL only knows about an abstraction dealing with business objects. And you never work with the whole BL as once, you're always in a specific BL context. Your DirectoryService seems to be doing way to much for its own good. Updating stats doesn't look like it belongs to the same context as adding a new Province. Also why do you need UoW for queries?
One mistake I see a lot is devs rushing to write whatever code (with a design pattern attached) when they aren't doing the most important part: the design itself. When you have the improper design, problems appear and you start looking for workarounds. One of them is this UoW with Repository properties, which require a high layer like BL to know more than business concerns. Now the BL needs to know that you're using a UoW, a lower level pattern which is great for the DAL, not so great for the BL.
Btw, UoW never makes sense for quering as you're dealing with a 'read' situation, UoW is only for 'writes'. I don't mention EF or any ORM because they don't really matter, your BL service (Directory Service) is already corrupted by an infrastructural detail required by improper design. Note that sometimes you do need to compromise in order to implement a solution, but this is not the case.
Proper design means you know about your bounded context (yeah, DDD concept you can apply it regardless how much DDD you want to do) and don't put everything that might use the same data in one place. You have specific contexts for use cases and counting provinces (a presentation/reporting detail) is really a different use case than adding Province.
Adding the province and then publishing an event which signals to a handler to update stats is a more elegant, maintainable solution. No UoW required either.
Your code would look like this
public class DirectoryService : IDirectoryService
{
public DirectoryService(IProvinceRepository repo, IDispatchMessage bus)
{
//assign fields
}
/* other stuff */
//maybe province is an input model which is used by the service to create a business Province?
public void AddProvince(Province province)
{
_repo.Save(province);
_bus.Publish( new ProvinceCreated(province));
}
}
public class StatsUpdater:ISubscribeTo<ProvinceCreated> /* and other stat trigger events */
{
public void Handle(ProvinceCreated evnt)
{
//update stats here
}
}
In a way it simplifies things, in other way you might thing it complicates stuff. Actually, this is a maintainable approach, because the stats updater can subscribe to many events but the logic stays in one class only. And the DirectoryService does only the things that are assumed it does (what part of the name AddProvince hints you that the method also updates stats?).
In conclusion, you need to design the BL better before rushing to complicate your life with UoW, DbContext, Repositories as properties etc
or assumes that the DbContext used by the Unit of Work and Repositories is shared and should live for the entire HTTP request
This is clearly wrong. Assuming that the context is shared between the UoW and Repositories doesn't mean that the context lifetime should depend on the HTTP request. Rather - you can create new instances of the context and the UoW that use it whenever you want. This is only a convenience to have a default UoW that lives for the HTTP request but creating new, local units of work could be handy.
On the other hand, if repositories are exposed from the UoW:
public class UnitOfWork
{
...
public IUserRepository UserRepo
{
get { ... }
}
public IAccountRepository AccountRepo
{
get { ... }
}
then not sharing the same context between repos could have unexpected results:
UoW uow = ....
var u1 = uow.User.FirstOrDefault( u => u.ID == 5 );
var u2 = uow.Account.FirstOrDefault( a => a.ID_USER == 5 ).User;
You would definitely expect these two to return the same instance of the user of the id 5 and what's more, sharing the same context would mean that the second query could retrieve the user from the 1st level cache. On the other hand, two different contexts for two repos means that you get two different instances.
This also means that this would not be possible
var u1 = uow.User.FirstOrDefault( u => u.ID == 5 );
var a1 = uow.Account.FirstOrDefault( a => a.ID == 177 );
a1.User = u1; // oops!
as mixing entites from different contexts would just raise an exception. But the above scenario is a common one!
The conclusion from these observations is that you should share the context between repos. But, if you need a fresh instance, you just create a local, fresh instance of the context, inject it into the UoW, from where it gets injected into repos, and dispose it at will.

Unit of Work + Repository Pattern: The Fall of the Business Transaction Concept

Combining Unit of Work and Repository Pattern is something used fairly widely nowadays. As Martin Fowler says a purpose of using UoW is to form a Business Transaction while being ignorant of how repositories actually work (being persistent ignorant). I've reviewed many implementations; and ignoring specific details (concrete/abstract class, interface,...) they are more or less similar to what follows:
public class RepositoryBase<T>
{
private UoW _uow;
public RepositoryBase(UoW uow) // injecting UoW instance via constructor
{
_uow = uow;
}
public void Add(T entity)
{
// Add logic here
}
// +other CRUD methods
}
public class UoW
{
// Holding one repository per domain entity
public RepositoryBase<Order> OrderRep { get; set; }
public RepositoryBase<Customer> CustomerRep { get; set; }
// +other repositories
public void Commit()
{
// Psedudo code:
For all the contained repositories do:
store repository changes.
}
}
Now my problem:
UoW exposes public method Commit to store the changes. Also, because each repository has a shared instance of UoW, each Repository can access method Commit on UoW. Calling it by one repository makes all other repositories store their changes too; hence the result the whole concept of transaction collapses:
class Repository<T> : RepositoryBase<T>
{
private UoW _uow;
public void SomeMethod()
{
// some processing or data manipulations here
_uow.Commit(); // makes other repositories also save their changes
}
}
I think this must be not allowed. Considering the purpose of the UoW (business transaction), the method Commit should be exposed only to the one who started a Business Transaction for example Business Layer. What surprised me is that I couldn't find any article addressing this issue. In all of them Commit can be called by any repo being injected.
PS: I know I can tell my developers not to call Commit in a Repository but a trusted Architecture is more reliable than trusted developers!
I do agree with your concerns. I prefer to have an ambient unit of work, where the outermost function opening a unit of work is the one that decides whether to commit or abort. Functions called can open a unit of work scope which automatically enlists in the ambient UoW if there is one, or creates a new one if there is none.
The implementation of the UnitOfWorkScope that I used is heavily inspired by how TransactionScope works. Using an ambient/scoped approach also removes the need for dependency injection.
A method that performs a query looks like this:
public static Entities.Car GetCar(int id)
{
using (var uow = new UnitOfWorkScope<CarsContext>(UnitOfWorkScopePurpose.Reading))
{
return uow.DbContext.Cars.Single(c => c.CarId == id);
}
}
A method that writes looks like this:
using (var uow = new UnitOfWorkScope<CarsContext>(UnitOfWorkScopePurpose.Writing))
{
Car c = SharedQueries.GetCar(carId);
c.Color = "White";
uow.SaveChanges();
}
Note that the uow.SaveChanges() call will only do an actual save to the database if this is the root (otermost) scope. Otherwise it is interpreted as an "okay vote" that the root scope will be allowed to save the changes.
The entire implementation of the UnitOfWorkScope is available at: http://coding.abel.nu/2012/10/make-the-dbcontext-ambient-with-unitofworkscope/
Make your repositories members of your UoW. Don't let your repositories 'see' your UoW. Let UoW handle the transaction.
Don't pass in the UnitOfWork, pass in an interface that has the methods you need. You can still implement that interface in the original concrete UnitOfWork implementation if you want:
public interface IDbContext
{
void Add<T>(T entity);
}
public interface IUnitOfWork
{
void Commit();
}
public class UnitOfWork : IDbContext, IUnitOfWork
{
public void Add<T>(T entity);
public void Commit();
}
public class RepositoryBase<T>
{
private IDbContext _c;
public RepositoryBase(IDbContext c)
{
_c = c;
}
public void Add(T entity)
{
_c.Add(entity)
}
}
EDIT
After posting this I had a rethink. Exposing the Add method in the UnitOfWork implementation means it is a combination of the two patterns.
I use Entity Framework in my own code and the DbContext used there is described as "a combination of the Unit-Of-Work and Repository pattern".
I think it is better to split the two, and that means I need two wrappers around DbContext one for the Unit Of Work bit and one for the Repository bit. And I do the repository wrapping in RepositoryBase.
The key difference is that I do not pass the UnitOfWork to the Repositories, I pass the DbContext. That does mean that the BaseRepository has access to a SaveChanges on the DbContext. And since the intention is that custom repositories should inherit BaseRepository, they get access to a DbContext too. It is therefore possible that a developer could add code in a custom repository that uses that DbContext. So I guess my "wrapper" is a bit leaky...
So is it worth creating another wrapper for the DbContext that can be passed to the repository constructors to close that off? Not sure that it is...
Examples of passing the DbContext:
Implementing the Repository and Unit of Work
Repository and Unit of Work in Entity Framework
John Papa's original source code
Realize it has been a while since this was asked, and people may have died of old age, transferred to management etc. but here goes.
Taking inspiration from databases, transaction controllers and the two phase commit protocol, the following changes to the patterns should work for you.
Implement the unit of work interface described in Fowler's P of EAA book, but inject the repository into each UoW method.
Inject the unit of work into each repository operation.
Each repository operation calls the appropriate UoW operation and injects itself.
Implement the two phase commit methods CanCommit(), Commit() and Rollback() in the repositories.
If required, commit on the UoW can run Commit on each repository or it can commit to the data store itself. It can also implement a 2 phase commit if that is what you want.
Having done this, you can support a number of different configurations depending on how you implement the repositories and the UoW. e.g. from simple data store without transactions, single RDBMs, multiple heterogeneous data stores etc. The data stores and their interactions can be either in the repositories or in the UoW, as the situation requires.
interface IEntity
{
int Id {get;set;}
}
interface IUnitOfWork()
{
void RegisterNew(IRepsitory repository, IEntity entity);
void RegisterDirty(IRepository respository, IEntity entity);
//etc.
bool Commit();
bool Rollback();
}
interface IRepository<T>() : where T : IEntity;
{
void Add(IEntity entity, IUnitOfWork uow);
//etc.
bool CanCommit(IUnitOfWork uow);
void Commit(IUnitOfWork uow);
void Rollback(IUnitOfWork uow);
}
User code is always the same regardless of the DB implementations and looks like this:
// ...
var uow = new MyUnitOfWork();
repo1.Add(entity1, uow);
repo2.Add(entity2, uow);
uow.Commit();
Back to the original post. Because we are method injecting the UoW into each repo operation the UoW does not need to be stored by each repository, meaning Commit() on the Repository can be stubbed out, with Commit on the UoW doing the actual DB commit.
In .NET, data access components typically automatically enlist to ambient transactions. Hence, saving changes intra-transactionally becomes separated from comitting the transaction to persist the changes.
Put differently - if you create a transaction scope you can let the developers save as much as they want. Not until the transaction is committed the observable state of the database(s) will be updated (well, what is observable depends on the transaction isolation level).
This shows how to create a transaction scope in c#:
using (TransactionScope scope = new TransactionScope())
{
// Your logic here. Save inside the transaction as much as you want.
scope.Complete(); // <-- This will complete the transaction and make the changes permanent.
}
I too have been recently researching this design pattern and by utilizing the Unit Of Work and Generic Repository Pattern I was able to extract the Unit of Work "Save Changes" for the Repository implementation. My code is as follows:
public class GenericRepository<T> where T : class
{
private MyDatabase _Context;
private DbSet<T> dbset;
public GenericRepository(MyDatabase context)
{
_Context = context;
dbSet = context.Set<T>();
}
public T Get(int id)
{
return dbSet.Find(id);
}
public IEnumerable<T> GetAll()
{
return dbSet<T>.ToList();
}
public IEnumerable<T> Where(Expression<Func<T>, bool>> predicate)
{
return dbSet.Where(predicate);
}
...
...
}
Essentially all we are doing is passing in the data context and utilizing the entity framework's dbSet methods for basic Get, GetAll, Add, AddRange, Remove, RemoveRange, and Where.
Now we will create a generic interface to expose these methods.
public interface <IGenericRepository<T> where T : class
{
T Get(int id);
IEnumerable<T> GetAll();
IEnumerabel<T> Where(Expression<Func<T, bool>> predicate);
...
...
}
Now we would want to create an interface for each entity in entity Framework and inherit from IGenericRepository so that the interface will expect to have the method signatures implemented within the inherited repositories.
Example:
public interface ITable1 : IGenericRepository<table1>
{
}
You will follow this same pattern with all of your entities. You will also add any function signatures in these interfaces that are specific to the entities. This would result in the repositories needing to implement the GenericRepository methods and any custom methods defined in the interfaces.
For the Repositories we will implement them like this.
public class Table1Repository : GenericRepository<table1>, ITable1
{
private MyDatabase _context;
public Table1Repository(MyDatabase context) : base(context)
{
_context = context;
}
}
In the example repository above I am creating the table1 repository and inheriting the GenericRepository with a type of "table1" then I inherit from the ITable1 interface. This will automatically implement the generic dbSet methods for me, thus allowing me to only focus on my custom repository methods if any. As I pass the dbContext to the constructor I must also pass the dbContext to the base Generic Repository as well.
Now from here I will go and create the Unit of Work repository and Interface.
public interface IUnitOfWork
{
ITable1 table1 {get;}
...
...
list all other repository interfaces here.
void SaveChanges();
}
public class UnitOfWork : IUnitOfWork
{
private readonly MyDatabase _context;
public ITable1 Table1 {get; private set;}
public UnitOfWork(MyDatabase context)
{
_context = context;
// Initialize all of your repositories here
Table1 = new Table1Repository(_context);
...
...
}
public void SaveChanges()
{
_context.SaveChanges();
}
}
I handle my transaction scope on a custom controller that all other controllers in my system inherit from. This controller inherits from the default MVC controller.
public class DefaultController : Controller
{
protected IUnitOfWork UoW;
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
UoW = new UnitOfWork(new MyDatabase());
}
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
UoW.SaveChanges();
}
}
By implementing your code this way. Every time a request is made to the server at the beginning of an action a new UnitOfWork will be created and will automatically create all the repositories and make them accessible to the UoW variable in your controller or classes. This will also remove your SaveChanges() from your repositories and place it within the UnitOfWork repository. And last this pattern is able to utilize only a single dbContext throughout the system via dependency injection.
If you are concerned about parent/child updates with a singular context you could utilize stored procedures for your update, insert, and delete functions and utilize entity framework for your access methods.
In a very simple application
In some applications, the domain model and the database entities are identical, and there is no need to do any data mapping between them. Let's call them "domain entities". In such applications, the DbContext can act both as a repository and a unit of work simultaneously. Instead of doing some complicated patterns, we can simply use the context:
public class CustomerController : Controller
{
private readonly CustomerContext context; // injected
[HttpPost]
public IActionResult Update(CustomerUpdateDetails viewmodel)
{
// [Repository] acting like an in-memory domain object collection
var person = context.Person.Find(viewmodel.Id);
// [UnitOfWork] keeps track of everything you do during a business transaction
person.Name = viewmodel.NewName;
person.AnotherComplexOperationWithBusinessRequirements();
// [UnitOfWork] figures out everything that needs to be done to alter the database
context.SaveChanges();
}
}
Complex queries on larger apps
If your application gets more complex, you'll start writing some large Linq queries in order to access your data. In that situation, you'll probably need to introduce a new layer that handle these queries, in order to prevent yourself from copy pasting them across your controllers. In that situation, you'll end up having two different layers, the unit of work pattern implemented by the DbContext, and the repository pattern that will simply provide some Linq results executing over the former. Your controller is expected to call the repository to get the entities, change their state and then call the DbContext to persist the changes to the database, but proxying the DbContext.SaveChanges() through the repository object is an acceptable approximation:
public class PersonRepository
{
private readonly PersonDbContext context;
public Person GetClosestTo(GeoCoordinate location) {} // redacted
}
public class PersonController
{
private readonly PersonRepository repository;
private readonly PersonDbContext context; // requires to Equals repository.context
public IActionResult Action()
{
var person = repository.GetClosestTo(new GeoCoordinate());
person.DoSomething();
context.SaveChanges();
// repository.SaveChanges(); would save the injection of the DbContext
}
}
DDD applications
It gets more interesting when domain models and entities are two different group of classes. This will happen when you will start implementing DDD, as this requires you to define some aggregates, which are clusters of domain objects that can be treated as a single unit. The structure of aggregates does not always perfectly map to your relational database schema, as it can provides multiple level of abstractions depending on the use case you're dealing with.
For instance, an aggregate may allow a user to manage multiple addresses, but in another business context you'll might want to flatten the model and limit the modeling of the person's address to the latest value only:
public class PersonEntity
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public bool IsValid { get; set; }
public ICollection<AddressEntity> Addresses { get; set; }
}
public class AddressEntity
{
[Key]
public int Id { get; set; }
public string Value { get; set; }
public DateTime Since { get; set; }
public PersonEntity Person { get; set; }
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string CurrentAddressValue { get; private set; }
}
Implementing the unit of work pattern
First let's get back to the definition:
A unit of work keeps track of everything you do during a business transaction that can affect the database. When you're done, it figures out everything that needs to be done to alter the database as a result of your work.
The DbContext keeps tracks of every modification that happens to entities and will persist them to the database once you call the SaveChanges() method. Like in the simpler example, unit of work is exactly what the DbContext does, and using it as a unit of work is actually how Microsoft suggest you'd structure a .NET application using DDD.
Implementing the repository pattern
Once again, let's get back to the definition:
A repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection.
The DbContext, cannot act as a repository. Although it behaves as an in-memory collection of entities, it does not act as an in-memory collection of domain objects. In that situation, we must implement another class for the repository, that will act as our in-memory collection of domain models, and will map data from entities to domain models. However, you will find a lot of implementations that are simply a projection of the DbSet in the domain model and provide IList-like methods that simply maps entities back and reproduce the operations on the DbSet<T>.
Although this implementation might be valid in multiple situations, it overemphasizes over the collection part, and not enough on the mediator part of the definition.
A repository is a mediator between the domain layer and the infrastructure layer, which means its interface is defined in the domain layer. Methods described in the interface are defined in the domain layer, and they all must have a meaning in the business context of the program. Ubiquitous language being a central concept of DDD, these methods must provide a meaningful name, and perhaps "adding a person" is not the right business way to name this operation.
Also, all persistence-related concepts are strictly limited to the implementation of the repository. The implementation defines how a given business operation translates in the infrastructure layer, as a series of entities manipulation that will eventually be persisted to the database through an atomic database transaction. Also note that the Add operation on a domain model does not necessarily implies an INSERT statement in the database and a Remove will sometimes end up in an UPDATE or even multiple INSERT statements !
Actually, here is a pretty valid implementation of a repository pattern:
public class Person
{
public void EnsureEnrollable(IPersonRepository repository)
{
if(!repository.IsEnrollable(this))
{
throw new BusinessException<PersonError>(PersonError.CannotEnroll);
}
}
}
public class PersonRepository : IPersonRepository
{
private readonly PersonDbContext context;
public IEnumerable<Person> GetAll()
{
return context.Persons.AsNoTracking()
.Where(person => person.Active)
.ProjectTo<Person>().ToList();
}
public Person Enroll(Person person)
{
person.EnsureEnrollable(this);
context.Persons.Find(person.Id).Active = true;
context.SaveChanges(); // UPDATE statement
return person;
}
public bool IsEnrollable(Person person)
{
return context.Persons.Any(entity => entity.Id == person.Id && !entity.Active);
}
}
Business transaction
You're saying a purpose of using unit of work is to form a Business Transaction, which is wrong. The purpose of the unit of work class is to keeps track of everything you do during a business transaction that can affect the database, to alter the database as a result of your work in an atomic operation. The repositories do share the unit of work instances, but bear in mind that dependency injection usually uses a scoped lifetime manager when injecting dbcontext. This means that instances are only shared within the same http request context, and different requests will not share changes tracking. Using a singleton lifetime manager will share instances among different http request which will provoke havoc in your application.
Calling the unit of work save changes method from a repository is actually how you are expected to implementation a DDD application. The repository is the class that knows about the actual implementation of the persistence layer, and that will orchestrate all database operations to commit/rollback at the end of transaction. Saving changes from another repository when calling save changes is also the expected behavior of the unit of work pattern. The unit of work accumulates all changes made by all repositories until someone calls a commit or a rollback. If a repository makes changes to the context that are not expected to be persisted in the database, then the problem is not the unit of work persisting these changes, but the repository doing these changes.
However, if your application does one atomic save changes that persists change operations from multiple repositories, it probably violates one of the DDD design principles. A repository is a one-to-one mapping with an aggregate, and an aggregate is a cluster of domain objects that can be treated as a single unit. If you are using multiple repositories, then you are trying to modify multiple units of data in a single transaction.
Either your aggregate is designed too small, and you need to make a larger one that holds all data for your single transaction, with a repository that will handle all that data in a single transaction ; either you're trying to make a complex transaction that spans over a wide part of your model, and you will need to implement this transaction with eventual consistency.
Yes, this question is a concern to me, and here's how I handle it.
First of all, in my understanding Domain Model should not know about Unit of Work. Domain Model consists of interfaces (or abstract classes) that don't imply the existence of the transactional storage. In fact, it does not know about the existence of any storage at all. Hence the term Domain Model.
Unit of Work is present in the Domain Model Implementation layer. I guess this is my term, and by that I mean a layer that implements Domain Model interfaces by incorporating Data Access Layer. Usually, I use ORM as DAL and therefore it comes with built-in UoW in it (Entity Framework SaveChanges or SubmitChanges method to commit the pending changes). However, that one belongs to DAL and does not need any inventor's magic.
On the other hand, you are referring to the UoW that you need to have in Domain Model Implementation layer because you need to abstract away the part of "committing changes to DAL". For that, I would go with Anders Abel's solution (recursive scropes), because that addresses two things you need to solve in one shot:
You need to support saving of aggregates as one transaction, if the aggregate is an initiator of the scope.
You need to support saving of aggregates as part of the parent transaction, if the aggregate is not the initiator of the scope, but is part of it.

How to dispose object context in repository pattern

I implemented a repository pattern to my application dat .
I have :
public class EFRepository<T>
{
DbContext // My db context
public IQureable<T> GetQuery()
{
DataContext.CreateQuery(...);
}
}
Now let say I have user repository :
public class UserRepository : EFRepository
{
public UserGetUserDetails(int userId)
{
GetQuery().Where(u=>u.Id = userId).First();
}
}
my problem is how to release the DbContext when I use the EF repository in derived repositories.
Lets say : UserRepository: EFRepository , and it uses the GetQuery then I have to dispose the context.
Any good idea how to make this in generic repository?
You should think about what unit of work you have. (there are many other tutorials on the internet). The idea is to keep the same dbcontext and to re-use it while being in the same unit of work. This way, entities will already be attached to the context when needing them, etc..
Now, this being a web application, your unit of work would be in this case a request. While in the same request, reuse your DBContext. There are many ways to do this and just off the top of my head - you will want something like 'OnActionExecuting' where you take care of your context.
But even better would be to use an Inversion of Control pattern (there are many frameworks out there that use this, i primarily use NInject . This will automatically create a new instance of a certain class, when needed, depending on the scope you suggested - in this case 'onRequestScope'. A lot more to say about IoC but not the scope of the question
I have used a similar pattern in the past and in my case I actually inherited from DbContext, which itself implements IDisposable. Provided you are using EFRepository or classes derived from it in a using block you should be fine.
If you would prefer a DbContext member variable, then EFRepository will need to implement IDisposable and call DbContext.Dispose() from its Dispose method.

Is it bad practice to have a repository that manually opens and closes a db connection?

Environment: ASP.NET MVC3 C#
Say I have some repository (semi-psuedo):
public interface IRepository
{
create();read();update();delete();opendb();closedb();
}
public class CarRepository : IRepository
{
private DbContext namedDbContext;
public void opendb()
{
namedDbContext = new DbContext();
}
public void closedb()
{
namedDbContext.dispose();
}
}
And then in a controller the repository is injected and used as follows to manually control the db connection lifetime:
public class SomeController : Controller
{
private IRepository CarRepository;
public void SomeController(IRepository _carRepository)
{
CarRepository = _carRepository;
}
public ActionResult SomeAction(int CarId)
{
CarRepository.opendb();
var car = CarRepository.read(CarId);
CarRepository.closedb();
}
}
Is this considered bad practice because it is taking the control of the connection from the repository and placing it in the controller? I am worried about memory leaks from using dependency injection and want to ensure duplicate connections are not opened, nor long running and unused.
Yes. Sure. Most ADO.NET drivers uses connection pooling, so the actual connection process isn't that heavy. And you have TransactionScope which can take care of transaction over multiple connections, but it wont be as fast as one transaction over one connection.
I am worried about memory leaks from using dependency injection and want to ensure duplicate connections are not opened, nor long running and unused.
A IoC will guaranteed clean up the connection (a large user base have made sure of that). There is no guarantee that a programmer will do the cleanup in all places.
The REpository pattern provides an abstraction of the persistence layer. It shouldn't expose any of the persistence details such as db connection. What if the storage is an xml file, or a cloud storage?
So yes, it is bad practice. If you want more control, you might make the repository use the unit of work pattern, so that a higher level should decide when a transaction is commited, but that's it. No knowledge of the database should be exposed by the repository.
AS for memory leaks, make repository implmement IDIsposable (where you close any outstanding open conenctions)and just makes sure that the DI container manages a repository instance per request, it will call Dispose on it.
Part of a repository is abstracting away the details of persistence.
I see two problems with your proposal:
You are leaking the abstraction more than necessary by naming these methods "opendb" and "closedb" and
If you go down this route, you should return IDisposable (the connection object) from the opendb() method, and wrap the action in a using block to ensure that the connection gets closed.
Typically, you can just let the repository create a connection for each method, so you just have to get it right in your repository methods. The challenge comes when you want to perform multiple actions against the repository, without using a separate connection for each piece.
To achieve that, you could expose the notion of a unit-of-work from the repository. Your unit of work will implement the interface for the repository's methods, so you can't call them outside of a unit-of-work. It will also implement IDisposable, so whenever you call into your repository you will use a using block. Internally, the repository will manage the connection, but will neither expose the connection nor "talk about it."
For example:
public ActionResult SomeAction(int CarId)
{
using (var repo = CarRepository.BeginUnitOfWork())
{
var car = repo.read(CarId);
// do something meaningful with the car, do more with the repo, etc.
}
}

Should Linq to SQL repository implement IDisposable

I've been googling a ton on repository patterns with Linq over the last few days. There's a lot of info out there but it's often contradictory and I'm still looking for a definitive source.
One of the things I'm still not sure about is whether the repository should instantiate it's own DataContext and have a SubmitChanges method, or if the DataContext should be injected and the submission handled externally. I've seen both designs but no real comment on the reasoning.
Anyway, the following pattern is pretty common
class Repository<T>
{
DataContext db = new LinqDataContext();
public IEnumerable<T> GetAll() { ... }
public T GetById() { ... }
... etc
public void SubmitChanges() { ... }
}
So my main question is, with the above implementation, why does the repository not need to implement IDisposable? I've seen literally hundreds of examples as above, and none of them seem to bother disposing the DataContext. Isn't this a memory leak?
Disposing a DataContext closes the underlying connection if you have autoclose set to false. If you do not call dispose, you have to wait for the GC to call it for you. You should implement IDisposable and dispose of your repositories which should in turn dispose their DataContext.
Another solution is to create a new data context for each method in your repository if your methods don't work together within a single transaction. Then you can dispose your contexts as soon as they are used via a using() directive.
Not necessary but you probably should implement IDisposable.

Categories