我正在实现ASP.NET MVC应用程序,并且需要实现带有存储库模式的工作单元。我的实现设计如下:
UnitOfWork
对象负责根据需要发布COMMIT
s和ROLLBACK
s。UnitOfWork
对象包含Transaction
从内部数据库连接中获取的属性。该对象为内的操作提供了原子性UnitOfWork
。UnitOfWork
对象包含存储库作为在运行时注入的属性。IDbTransaction
对象UnitOfWork
。因此,现在我发现自己处于一种奇怪的境地,UnitOfWork
即必须注入需要UnitOfWork
自身属性的存储库才能实例化。所以我的问题是:我该怎么做?还是必须更改设计中的某些内容?
我目前正在使用SQL Server,并且使用Dapper进行SQL调用。另外,我正在考虑使用Autofac作为DI框架。
到目前为止,我所做的是实现UOW和示例存储库。代码如下。
IRepository.cs
:
public interface IRepository<TObj, TKey>
{
Task<TObj> DetallesAsync(TKey id);
Task<TKey> AgregarAsync(TObj obj);
}
DbRepository.cs
:
public abstract class DbRepository
{
private readonly IDbConnection _connection;
private readonly IDbTransaction _transaction;
protected IDbConnection Connection
{
get => _connection;
}
protected IDbTransaction Transaction
{
get => _transaction;
}
public DbRepository(IDbTransaction transaction)
{
_transaction = transaction;
_connection = _transaction.Connection;
}
}
RolRepository.cs
:
public class MSSQLRolRepository : DbRepository, IRolRepository
{
public MSSQLRolRepository(IDbTransaction transaction)
: base(transaction)
{
}
public async Task<int> AgregarAsync(Rol obj)
{
var result = await Connection.ExecuteScalarAsync<int>(MSSQLQueries.RolAgregar, param: obj, transaction: Transaction);
return result;
}
public async Task<Rol> DetallesAsync(int id)
{
var param = new { Id = id };
var result = await Connection.QuerySingleOrDefaultAsync<Rol>(MSSQLQueries.RolDetalles, param: param, transaction: Transaction);
return result;
}
public async Task<Rol> DetallesPorNombreAsync(string nombre)
{
var param = new { Nombre = nombre };
var result = await Connection.QuerySingleOrDefaultAsync<Rol>(MSSQLQueries.RolDetallesPorNombre, param: param, transaction: Transaction);
return result;
}
public async Task<Rol[]> ListarAsync(int pagina, int itemsPorPagina)
{
var param = new { Pagina = pagina, ItemsPorPagina = itemsPorPagina };
var result = await Connection.QueryAsync<Rol>(MSSQLQueries.RolListar, param: param, transaction: Transaction);
return result.ToArray();
}
public async Task<Rol[]> ListarTodosAsync()
{
var result = await Connection.QueryAsync<Rol>(MSSQLQueries.RolListar, transaction: Transaction);
return result.ToArray();
}
}
IUnitOfWork.cs
:
public interface IUnitOfWork : IDisposable
{
IDbTransaction Transaction { get; }
IDenunciaRepository DenunciaRepository { get; }
IUsuarioRepository UsuarioRepository { get; }
IRolRepository RolRepository { get; }
void Commit();
void Rollback();
}
MSSQLUnitOfWork.cs
:
public class MSSQLUnitOfWork : IUnitOfWork
{
private bool _already_disposed = false;
private IDbConnection _connection;
private IDbTransaction _transaction;
private IDenunciaRepository _denuncia_repository;
private IUsuarioRepository _usuario_repository;
private IRolRepository _rol_repository;
public IDbTransaction Transaction
{
get => _transaction;
}
public IDenunciaRepository DenunciaRepository
{
get => _denuncia_repository;
}
public IUsuarioRepository UsuarioRepository
{
get => _usuario_repository;
}
public IRolRepository RolRepository
{
get => _rol_repository;
}
public MSSQLUnitOfWork()
{
var connection_string = ConfigurationManager.ConnectionStrings["MSSQL"].ConnectionString;
_connection = new SqlConnection(connection_string);
_connection.Open();
_transaction = _connection.BeginTransaction();
//TODO: Crear repos con transacción
}
public void Commit()
{
_transaction.Commit();
}
public void Rollback()
{
_transaction.Rollback();
}
protected virtual void Dispose(bool disposeManagedObjects)
{
if (!_already_disposed)
{
if (disposeManagedObjects)
{
_transaction?.Dispose();
_connection?.Dispose();
}
_already_disposed = true;
}
}
public void Dispose()
{
Dispose(true);
}
}
我向您推荐3种不同的东西。
在实例化UnitOfWork的存储库中启动,提交和回滚数据事务-我建议的最低建议
创建一个Service类,您可以在其中创建UnitOfWork的实例,并将该实例或DBContext传递给您在事务中涉及的存储库
在知道当前DBContext的UnitOfWork类内创建Repository实例,然后您可以从UnitOfWork访问存储库操作,并在同一上下文中启动和结束事务。更多推荐
就像是:
UnitOfWorkInstance.MyRepositoryA.AddAsync(...);
UnitOfWorkInstance.MyRepositoryB.AddAsync(...);
UnitOfWorkInstance.Commit();
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句