Currently, I am trying to use Dapper ORM with Unit Of Work + Repository Pattern.
I want to use Unit of Work as opposed to a simple dapper Repository due to the fact that my insert and updates require a degree of transaction processing. I have been unable to find any useful examples as most seem to use Entity Framework and have leakage issue within the Unit of Work.
Could someone please point me in the right direction?
The main advantage to use repository pattern is to isolate the data access logic and business logic, so that if you make changes in any of this logic it can't effect directly on other logic. For more information, please go through the Repository Pattern Article.
In Visual Studio, create a new console project, and in Solution Explorer right-click References and select Manage NuGet Package Manager and search for Dapper and using the NuGet Package Manager Console command for the Nugget Package Manager “install-package dapper”, and this will install Dapper into your project.
Unit of Work in C# is the concept that is related to the effective implementation of the Repository Design Pattern. So, to understand this concept it is important to understand the concept of the Repository Pattern.
This Git project is very helpful. I started from the same and did some changes as per my need.
public sealed class DalSession : IDisposable { public DalSession() { _connection = new OleDbConnection(DalCommon.ConnectionString); _connection.Open(); _unitOfWork = new UnitOfWork(_connection); } IDbConnection _connection = null; UnitOfWork _unitOfWork = null; public UnitOfWork UnitOfWork { get { return _unitOfWork; } } public void Dispose() { _unitOfWork.Dispose(); _connection.Dispose(); } } public sealed class UnitOfWork : IUnitOfWork { internal UnitOfWork(IDbConnection connection) { _id = Guid.NewGuid(); _connection = connection; } IDbConnection _connection = null; IDbTransaction _transaction = null; Guid _id = Guid.Empty; IDbConnection IUnitOfWork.Connection { get { return _connection; } } IDbTransaction IUnitOfWork.Transaction { get { return _transaction; } } Guid IUnitOfWork.Id { get { return _id; } } public void Begin() { _transaction = _connection.BeginTransaction(); } public void Commit() { _transaction.Commit(); Dispose(); } public void Rollback() { _transaction.Rollback(); Dispose(); } public void Dispose() { if(_transaction != null) _transaction.Dispose(); _transaction = null; } } interface IUnitOfWork : IDisposable { Guid Id { get; } IDbConnection Connection { get; } IDbTransaction Transaction { get; } void Begin(); void Commit(); void Rollback(); }
Now, your repositories should accept this UnitOfWork in some way. I choose Dependency Injection with Constructor.
public sealed class MyRepository { public MyRepository(IUnitOfWork unitOfWork) { this.unitOfWork = unitOfWork; } IUnitOfWork unitOfWork = null; //You also need to handle other parameters like 'sql', 'param' ect. This is out of scope of this answer. public MyPoco Get() { return unitOfWork.Connection.Query(sql, param, unitOfWork.Transaction, .......); } public void Insert(MyPoco poco) { return unitOfWork.Connection.Execute(sql, param, unitOfWork.Transaction, .........); } }
And then you call it like this:
With transaction:
using(DalSession dalSession = new DalSession()) { UnitOfWork unitOfWork = dalSession.UnitOfWork; unitOfWork.Begin(); try { //Your database code here MyRepository myRepository = new MyRepository(unitOfWork); myRepository.Insert(myPoco); //You may create other repositories in similar way in same scope of UoW. unitOfWork.Commit(); } catch { unitOfWork.Rollback(); throw; } }
Without Transaction:
using(DalSession dalSession = new DalSession()) { //Your database code here MyRepository myRepository = new MyRepository(dalSession.UnitOfWork);//UoW have no effect here as Begin() is not called. myRepository.Insert(myPoco); }
Please note that, UnitOfWork is more than DBTransaction.
More details about Repository in above code could be found here.
I have already post this code here. But this question looks more relevant to me for this code; so I am posting again instead of just link to original answer.
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