Dapper로 Unit Of Work 패턴을 구현하는 방법은 무엇입니까?

dapper repository-pattern unit-of-work

문제

현재, Unit Of Work + Repository Pattern과 함께 Dapper ORM을 사용하려고합니다.

내 인서트 및 업데이트가 어느 정도의 트랜잭션 처리를 필요로하기 때문에 단순한 리포지토리와 달리 Unit of Work를 사용하고 싶습니다. 대부분의 유용한 예제를 찾을 수 없었습니다. Entity Framework를 사용하고 작업 단위 (UOW)에서 누수 문제가있는 것 같습니다.

누군가가 올바른 방향으로 나를 가리켜 주시겠습니까?

인기 답변

Git 프로젝트 는 매우 유용하다. 나는 같은 것을 시작했고 나의 필요에 따라 약간의 변화를했다.

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();
}

자, 리포지토리는이 UnitOfWork를 어떤 식 으로든 받아 들여야합니다. 저는 Constructor로 Dependency Injection을 선택합니다.

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, .........);
    }
}

그리고 당신은 이것을 다음과 같이 부릅니다 :

거래 :

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;
    }
}

거래가없는 경우 :

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);
}

있다는 점 유의 하시길 바랍니다의 UnitOfWork는 DBTransaction 이상.

위 코드의 저장소에 대한 자세한 내용은 여기를 참조하십시오 .

나는 이미이 코드를 게시 한 여기 . 하지만이 질문은이 코드와 관련이 있습니다. 그래서 나는 원래의 답변에 대한 링크 대신에 다시 게시하고 있습니다.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow