How to dispose object context in repository pattern - c#

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.

Related

Repository pattern - make it testable, DI and IoC friendly and IDisposable

What I have:
public interface IRepository
{
IDisposable CreateConnection();
User GetUser();
//other methods, doesnt matter
}
public class Repository
{
private SqlConnection _connection;
IDisposable CreateConnection()
{
_connection = new SqlConnection();
_connection.Open();
return _connection;
}
User GetUser()
{
//using _connection gets User from Database
//assumes _connection is not null and open
}
//other methods, doesnt matter
}
This enables classes that are using IRepository to be easily testable and IoC containers friendly. However someone using this class has to call CreateConnection before calling any methods that are getting something from database, otherwise exception will be thrown. This itself is kind of good - we dont want to have long lasting connections in application. So using this class I do it like this.
using(_repository.CreateConnection())
{
var user = _repository.GetUser();
//do something with user
}
Unfortunetelly this is not very good solution because people using this class (including even me!) often forget to call _repository.CreateConnection() before calling methods to get something from database.
To resolve this I was looking at Mark Seemann blog post SUT Double where he implements Repository pattern in correct way. Unfortunately he makes Repository implement IDisposable, which means I cannot simply inject it by IoC and DI to classes and use it after, because after just one usage it will be disposed. He uses it once per request and he uses ASP.NET WebApi capabilities to dispose it after request processing is done. This is something I cannot do because I have my classes instances which use Repository working all the time.
What is the best possible solution here? Should I use some kind of factory that will give me IDisposable IRepository ? Will it be easily testable then?
There are a few problematic spots in your design. First of all, your IRepository interface implements multiple levels of abstractions. Creating a user is a much higher level concept than connection management. By placing these behaviours together you are breaking the Single Responsibility Principle which dictates that a class should only have one responsibility, one reason to change. You are also violating the Interface Segregation Principle that pushes us toward narrow role interfaces.
On top of that, the CreateConnection() and GetUser method are temporal coupled. Temporal Coupling is a code smell and you are already witnessing this to be a problem, because you are able to forget the call to CreateConnection.
Besides this, the creation of the connection is something you will start to see on every repository in the system and every piece of business logic will need to either create a connection, or get an existing connection from the outside. This becomes unmaintainable in the long run. Connection management however is a cross-cutting concern; you don't want the business logic to be concerned in such low level concern.
You should start by splitting the IRepository into two different interfaces:
public interface IRepository
{
User GetUser();
}
public interface IConnectionFactory
{
IDisposable CreateConnection();
}
Instead of letting business logic manage the connection itself, you can manage the transaction at a higher level. This could be the request, but this might be too course grained. What you need is to start the transaction somewhere in between the presentation layer code and the business layer code, but without having to having to duplicate yourself. In other words, you want to be able to transparently apply this cross-cutting concern, without having to write it over and over again.
This is one of the many reasons that I started to use application designs as described here a few years ago, where business operations are defined using message objects and their corresponding business logic is hidden behind a generic interface. After applying these patterns, you will have a very clear interception point where you can start transactions with their corresponding connections and let the whole business operation run within that same transaction. For instance, you can use the following generic code that can be applied around every piece of business logic in your application:
public class TransactionCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand>
{
private readonly ICommandHandler<TCommand> decorated;
public TransactionCommandHandlerDecorator(ICommandHandler<TCommand> decorated) {
this.decorated = decorated;
}
public void Handle(TCommand command) {
using (var scope = new TransactionScope()) {
this.decorated.Handle(command);
scope.Complete();
}
}
}
This code wraps everything around a TransactionScope. This allows your repository to simply open and close a connection; this wrapper will ensure that the same connection is used nonetheless. This way you can inject an IConnectionFactory abstraction into your repository and let the repository directly close the connection at the end of its method call, while under the covers .NET will keep the real connection opened.
Create a repository factory that creates IDisposable repositories.
public interface IRepository : IDisposable {
User GetUser();
//other methods, doesn't matter
}
public interface IRepositoryFactory {
IRepository Create();
}
You create them within a using and they are disposed of when done.
using(var repository = factory.Create()) {
var user = repository.GetUser();
//do something with user
}
You can inject the factory and create the repositories as needed.
So, you already mentioned that
we dont want to have long lasting connections in application
which is absolutely right!
You need to open connection in each repository method implementation, execute queries or commands against the database, and then close the connection. I don't see why you would expose anything like connection to the domain layer. In other words, remove CreateConnection() methods from repositories. They are not needed. Each method will open/close it inside, when implemented.
There are times when you would want to wrap several repository method calls into something, but that is only related to transaction, not connection. In that case there are 2 answers:
Check the correctness of your Repository pattern implementation. You should have repositories only for Aggregate Roots. Not every entity qualifies as aggregate root. Aggregate root is the guaranteed transaction boundary, so you should not be worried about transactions anyway out of repository - each repository method call will naturally follow the boundary, since it handles only a single aggregate root at a time.
If you still need to execute operations against several aggregate roots in one go, then you will have to implement a pattern called Unit of Work. This is essentially a business layer transaction implementation. I don't recommend relying on built-in transaction features into storage technologies for this specific case (several aggregates in one go), because they differ from vendor to vendor (while relational DBs can guarantee several aggregate roots in one go, NoSQL DBs only guarantee single aggregate at a time).
From my experience, you should only need to modify single aggregate at a time. Unit of Work is a very rare case pattern. So, just rethink your repositories and aggregate roots, that should do the trick for you.
Just for the completeness of the answer - you do need to have repository interfaces, which you already have. Thus, your approach is already unit-testable.
You are mixing apples with oranges and peaches.
There are three concepts at play here:
The repository contract
The implementation details
Repository lifetime management
Your repository conceptually holds users, but it has a CreateConnection() method that indicates details of the implementation (a connection is needed). Not good.
What you need to do is remove the CreateConnection() method from the interface. Now you have a true definition of what a user repository is (by the way, you should call it that, IUserRepository).
On to the implementation details:
You have a user repository that talks to a database, so you should implement a DatabaseUserRepository class. This is where the details of creating a connection and handling it are stored. You may decide to keep an open connection for the lifetime of the object, or you may decide it's best to open and close a connection for every operation.
On to the lifetime of the object:
You have a dependency container. You may have decided you want your repository to be used as a singleton because your DatabaseUserRepository class implements atomic, thread-safe operations, or you may want your repository to be transient so a new instance is created because it implements a unit of work pattern which means that all changes are saved together (e.g. EF.SaveChanges()).
See the difference now?
The interface allows for unit testing. Any component that needs data from the database can use a mock repository that loads garbage from memory (e.g. MemoryUserRepository).
The implementation provides a repository that stores users in a database. You may even decide to have two versions of this class that implement the interface along with different strategies or patterns.
The lifetime of the repository will be setup according to the implementation details in the dependency container.
I would create a Connection Factory...
public class ConnectionFactory
{
public IDbConnection Create()
{
// your logic here
}
}
Now make it a dependency to your repositories, and use it inside you repositories as well... You don`t need an IDisposable repository, you need to dispose the connection.
I'm on the cellphone, so it's hard to give you a more detailed example. If you need, i can edit it later with a more detailed example.

what's a good way to handle generic db conn logic in dal/repo layer?

I'm developing a repo layer with several different repos like UserRepository, ReportRepository, etc. The connection string will be injected through the constructor of the repo. This pattern will be implemented consistently for all repos. Is there a way I can implement this logic generically without having to repeat this implementation for each repo? Each repo currently implements a corresponding interface. For example, UserRepository : IUserRepository. Is there a pattern you normally use to avoid the duplicate code? I could use abstract classes but I'm wondering if that would be too heavy. I've always seen repo classes implementing interfaces in past solutions I've worked on
Just use a base class, the typical pattern is:
public class UserRepository : IUserRepository,
RepositoryBase
{
public UserRepository(string connectionString)
: base(connectionString)
{
}
}
and put common code in RespositoryBase.

Unity Container - multiple databases with generic unity of work

I am using generic unity of work for EF6 from here:
https://genericunitofworkandrepositories.codeplex.com/
I have an application which uses two databases. I've created additional UnitOfWork interface and class that implements original unit of work interface:
namespace Repository.Pattern.UnitOfWork
{
public interface ILotteryBackOfficeUnitOfWorkAsync : IUnitOfWorkAsync
{
}
}
Second unit of work type for second database initialization:
namespace Repository.Pattern.Ef6
{
public class LotteryBackOfficeUnitOfWork : UnitOfWork, ILotteryBackOfficeUnitOfWorkAsync
{
public LotteryBackOfficeUnitOfWork(IDataContextAsync dataContext)
: base(dataContext)
{ }
}
}
In unity I register both unit of works for different data contexts:
public static void RegisterTypes(IUnityContainer container)
{
// NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
// container.LoadConfiguration();
// TODO: Register your types here
// container.RegisterType<IProductRepository, ProductRepository>();
var purusLotteryConnectionString = WebConfigurationManager.ConnectionStrings["PurusLotteryContext"].ConnectionString;
var purusLotteryBackOfficeConnectionString = WebConfigurationManager.ConnectionStrings["PurusLotteryBackOfficeContext"].ConnectionString;
container.RegisterType<IDataContextAsync, PurusLotteryContext>(new InjectionConstructor(purusLotteryConnectionString));
container.RegisterType<IUnitOfWorkAsync, UnitOfWork>(new HierarchicalLifetimeManager());
container.RegisterType<IDataContextAsync, PurusLotteryBackOfficeContext>("LotteryBackOfficeContext", new InjectionConstructor(purusLotteryBackOfficeConnectionString));
container.RegisterType<ILotteryBackOfficeUnitOfWorkAsync, LotteryBackOfficeUnitOfWork>(new HierarchicalLifetimeManager(),
new InjectionConstructor(container.Resolve<IDataContextAsync>("LotteryBackOfficeContext")));
container.RegisterType<IHomeService, HomeService>();
}
It works, but is this correct procedure?
One error I see is that you resolve during the registration phase. Not only is this dangerous (as is explained in the documentation of a different DI libary), in your case it causes the PurusLotteryBackOfficeContext to be used as constant and therefore injected as Singleton into the LotteryBackOfficeUnitOfWork. In other words, while this might seem to work during development, this will not work, because a DbContext can't be used as singleton.
Instead, you should use Unity's auto-wiring abilities as much as you can, otherwise a DI library has no advantage (and only disadvantages) over building up object graphs by hand.
Besides this, you are violating the Liskov Substitution Principle (LSP) in your design and this is causing you trouble in your DI configuration. You are violating the LSP because you have two incompatible implementations of the same abstraction. Both PurusLotteryContext and PurusLotteryBackOfficeContext implement IDataContextAsync, but they are incompatible, because they can't be interchanged, because they both work on a completely different database schema. Although they might seem to share the same interface, they don't share the same contract. Just look what happens when you inject a PurusLotteryContext into some class that needs to work with the backoffice. The application will break and this means you are violating the LSP.
Solution is to give them both their own independent abstraction. At first this might seem a weird thing to do, because they both have the same methods. But remember that an interface is much more than a set of method signatures; an interface describes a contract and behavior and since both implementations work on a completely different database schema they have a completely different contract. When you separate this, your code would look like this:
public class PurusLotteryContext : IPurusLotteryDataContextAsync {
public PurusLotteryContext(string conString) : base(conString) { }
}
public class LotteryUnitOfWork : ILotteryUnitOfWorkAsync {
public LotteryUnitOfWork(IPurusLotteryDataContextAsync dc) { }
}
public class PurusLotteryBackOfficeContext : IPurusLotteryBackOfficeDataContextAsync {
public PurusLotteryBackOfficeContext(string conString) : base(conString) { }
}
public class LotteryBackOfficeUnitOfWork : ILotteryBackOfficeUnitOfWorkAsync {
public LotteryBackOfficeUnitOfWork(IPurusLotteryBackOfficeDataContextAsync dc) { }
}
And this allows you to have the following registration:
container.Register<IPurusLotteryDataContextAsync>(new HierarchicalLifetimeManager(),
new InjectionFactory(c => new PurusLotteryContext(purusLotteryConnectionString)));
container.Register<IPurusLotteryBackOfficeDataContextAsync>(
new HierarchicalLifetimeManager(),
new InjectionFactory(c => new PurusLotteryBackOfficeContext(
purusLotteryBackOfficeConnectionString)));
container.RegisterType<ILotteryUnitOfWorkAsync, LotteryUnitOfWork>(
new HierarchicalLifetimeManager());
container.RegisterType<ILotteryBackOfficeUnitOfWorkAsync, LotteryBackOfficeUnitOfWork>(
new HierarchicalLifetimeManager());
Notice a few things about this registration:
The data context implementations are registered as hierarchical, because you typically want the Entity Framework DbContext to have a 'per request' lifestyle.
The data context implementations are registered using a factory, compared to using the container's auto-wiring ability. This is because auto-wiring doesn't help for these classes and a factory delegate will not only make the registration simpler, because also more type-safe (the compiler will help us if we make an error).
I know my answer comes late, but I want to point to a different direction here instead #Steve suggestion.
What about the named registration? Using a name to register the same interface with different implementations. Make sense that you have a contract and different implementations, there is nothing wrong on that.
If you want to keep the same interface at the time you register both implementations you can do it with a different name, take a look on the answer below
https://stackoverflow.com/a/18665983
Now, the intent for LSP is that derived types must be completely substitutable for their base types and again, in your case doesn't make to create a new contract with the same functionality and different signatures. I disagree with the #Steve suggestion. Bellow I am attaching a great example of LSP
https://stackoverflow.com/a/584732/819153
Another point of interest is the UnitOfWork.
When you're using EntityFramework and you instantiate your DbContext -
you're creating a new UnitOfWork.With EntityFramework you can "flush and reset" the UnitofWork by using SaveChanges(), you don't need to SaveChanges just to return the new ID - EF does it in the scope of the transaction already!
Here is a good article that you can read about it.
http://rob.conery.io/2014/03/04/repositories-and-unitofwork-are-not-a-good-idea/
I would recommend injecting directly the DataContext instead of the IUnitOfWork
Hope this help

Ninject and DbContext

Building a app with EF 6 and Ninject 3.2.2 I'm having some trouble wrapping my head around how to access the DbContext in a intelligent way.
As I understand in the newer versions of Ninject only constructor injection is encouraged. As EF 6, itself is repo and unit of work I'm not doing any abstractions on top of EF.
If would like to be able to use multiple small units of works so injecting the DbContext (uow) into every class that needs it is not going to work.
In a non IoC way I would do like this:
Using(var db = new DbContext){}
How do achieve this using Ninject as I no longer can do kernel.get in my using block...
I'd consider two approaches:
Create general DbContext, which can be hidden behind an interface:
public interface IPortalContext : IDisposable
{
DbSet<User> Users { get; }
DbContext Context { get; }
}
public class PortalContext : DbContext, IPortalContext
{
public PortalContext()
: base("PortalConnectionString")
{
}
public virtual DbSet<User> Users { get; set; }
}
then you can inject your context to the constructor without problem.
Create many small contexts which can be used in different scenarios and classes.
I don't think that first approach is bad since it only encapsulates your DbSets and DbContext making it easier to inject and test. You don't make any unnecessary layers above EF and whole interface seems quite transparent.
Anyway this approach is better than making whole IRepository<T> stuff to access another repository...
I'm not sure what you mean by "multiple small unit of works", but just for exposure, this is what I've done in a recent application:
Divided the domain in small bounded contexts (this is more of a conceptual step)
Each bounded context has: a context, a repository, a repository factory
Each context implements an IContext and a BaseContext that gives basic methods and common properties (IContext will be useful for mocking)
Each repository takes the relative context as a constructor paramenter
This is an example of a repository factory
public class CartRepositoryFactory : IRepositoryFactory
{
public IRepository Generate(CartContext ctx)
{
return new CartRepository(ctx);
}
}
At the application service layer, I inject a UoW and the repository factory that I need
If I want to work with several different context in one service, I simply create another service and combine the services that I need, injecting them
You might be asking, but why?!? This is madness!!
Well, because if the Repository manages the DbContext, then I can only do one operation per class instantiation. This allows me to open a DbContext and make several calls to the Repository.
Of course now you have the same problem at application service level, you can only call one method per instantiation, but it's far easier to manage.
Ultimately it all comes down to your taste: would you rather have a thin service or a thin repository?

Object sharing and dynamic instance creation

I've a base class for business logic operations that is being inherited by my co-worker. This class expose a constructor which requires an objectContext as parameter. You can think of this base class as a component for atomic CRUD operations (all its select, insert, edit and delete method will always act on just one entity).
Then, I have a "super class" which its primary purpose is shared the objectContext between all the above base class in order to execute some business transaction and also it must provide any baseClass instance, if required.
So, I'm looking for to elegant way to "inject" superClass's objectContext into a baseclass:
public BaseClass<T> where T : entity
{
private ObjectContext _ctx;
public BaseClass(ObjectContext ctx){ _ctx = ctx;}
public virtual IList<T> Select(){..}
public cirtual voind Insert(T entity){..}
// other stuff
}
public class SuperClass
{
private ObjectContext _ctx = new...
public BaseClass<TEntity> LoadBaseClass(TBase, TEntity) where TBase : BaseClass<TEntity>, where TEntity : class
{
BaseClass<TEntity> obj = Activator.CreateInstance(typeof(TBase), _ctx); // share objectContext
}
public int SaveAll(){return _ctx.SaveChanges();}
}
As you can see, my super class is able to return some baseClass instance through its type and it's just what I want. However, if some inherited class defines its own contructor with other parameter my LoadBaseClass method will fails.
I would find a clean solution in order to avoid any kind of possibility of error during instance creations from LoadBaseClass method. The only way I know is to define a private contructor, but by this way no-one will be able to inherit baseclass anymore..
What you are looking for is called Dependency Injection. You are now trying to build this by hand but there are a lot of tools that already do what you want.
Dependency Injection is all about constructing objects and configuring how and when those objects are created. It comes down to splitting object creation from your business logic.
In your case, you are working with something called the Unit Of Work and Repository pattern. Using a Dependency Injection container like Ninject you can easily configure your UnitOfWork to be shared between all repositories like this:
var kernel = new StandardKernel();
kernel.Bind<IMyRepository>().To<ConcreteRepository();
kernel.Bind<IMyUnitOfWork>().To<ObjectContextImp>().InRequestScope();
IMyRepository repos = kernel.Get<IMyRepository>();
What Ninject (or any DI tool) will do is try to construct a IMyRepository. You've configured it to look for a ConcreteRepository. Then it notices that the ConcreteRepository takes a IMyUnitOfWork in its constructor. In this case you have mapped this to your ObjectContextIml and added the InRequestScope option.
InRequestScope is for ASP.NET web applications and it means that your context should be created once for each request. Ninject has a couple of different Object Scopes that you can use to configure how your object should be created and shared.
This way, you have complete control over how your objects are created.

Categories