C# 当依赖项需要运行时值时,如何注入依赖项?

C# 当依赖项需要运行时值时,如何注入依赖项?,c#,dependency-injection,asp.net-mvc-5,inversion-of-control,autofac,C#,Dependency Injection,Asp.net Mvc 5,Inversion Of Control,Autofac,我正在实现一个ASP.NET MVC应用程序,需要实现使用存储库的工作单元模式。我的实现设计如下: UnitOfWork对象负责根据需要发出COMMITs和ROLLBACKs UnitOfWork对象包含一个从内部数据库连接获取的事务属性。此对象为工作单元内的操作提供原子性 UnitOfWork对象将存储库作为运行时注入的属性包含在内 每个存储库都需要提供为支持原子性而创建的IDbTransaction对象UnitOfWork 所以现在我发现自己处于一种奇怪的境地,在UnitOfWork中,

我正在实现一个ASP.NET MVC应用程序,需要实现使用存储库的工作单元模式。我的实现设计如下:

  • UnitOfWork
    对象负责根据需要发出
    COMMIT
    s和
    ROLLBACK
    s
  • UnitOfWork
    对象包含一个从内部数据库连接获取的
    事务
    属性。此对象为
    工作单元
    内的操作提供原子性
  • UnitOfWork
    对象将存储库作为运行时注入的属性包含在内
  • 每个存储库都需要提供为支持原子性而创建的
    IDbTransaction
    对象
    UnitOfWork
所以现在我发现自己处于一种奇怪的境地,在
UnitOfWork
中,必须注入需要
UnitOfWork
自身属性的存储库才能被实例化。所以我的问题是:我该怎么做?或者设计中的某些东西需要改变

目前我正在使用SQL Server,我使用Dapper进行SQL调用。另外,我正在考虑使用Autofac作为DI框架

到目前为止,我所做的是实现UOW和一个示例存储库。代码如下

IRepository.cs

公共接口IRepository
{
任务DetallesAsync(TKey id);
任务AgregarAsync(TObj-obj);
}
DbRepository.cs

公共抽象类DbRepository
{
专用只读IDbConnection\u连接;
私有只读IDbTransaction\u事务;
受保护的IDB连接
{
获取=>\u连接;
}
受保护的IDB事务
{
获取=>\u事务;
}
公共数据库存储库(IDbTransaction)
{
_交易=交易;
_连接=_transaction.connection;
}
}
RolRepository.cs

公共类MSSQLRolRepository:DbRepository,IRolRepository
{
公共MSSQLRolRepository(IDbTransaction事务)
:基本(事务)
{
}
公共异步任务AgregarAsync(Rol obj)
{
var result=await Connection.ExecuteScalarAsync(mssqlquerys.RolAgregar,param:obj,transaction:transaction);
返回结果;
}
公共异步任务DetallesAsync(int-id)
{
var param=new{Id=Id};
var result=await Connection.QuerySingleOrDefaultAsync(MSSQLQueries.RolDetalles,param:param,transaction:transaction);
返回结果;
}
公共异步任务DetallesPorNombreAsync(字符串nombre)
{
var param=new{Nombre=Nombre};
var result=wait Connection.QuerySingleOrDefaultAsync(MSSQLQueries.RolDetallesPorNombre,param:param,transaction:transaction);
返回结果;
}
公共异步任务ListarAsync(int-pagina,int-itemsPorPagina)
{
var param=new{Pagina=Pagina,ItemsPorPagina=ItemsPorPagina};
var result=wait Connection.querySync(mssqlquerys.RolListar,param:param,transaction:transaction);
返回result.ToArray();
}
公共异步任务ListarTodosAsync()
{
var result=wait Connection.querysync(mssqlquerys.RolListar,事务:transaction);
返回result.ToArray();
}
}
IUnitOfWork.cs

公共接口IUnitOfWork:IDisposable
{
IDbTransaction事务{get;}
IDenunciaRepository DenunciaRepository{get;}
IUsuarioRepository UsuarioRepository{get;}
IRolRepository-RolRepository{get;}
无效提交();
无效回滚();
}
MSSQLUnitOfWork.cs

公共类MSSQLSUnitOfWork:IUnitOfWork
{
private bool _已处置=false;
专用IDBU连接;
私人交易;
私有IDenunciaRepository\u denuncia\u repository;
私有Iusuario存储库(usuario存储库);;
私有IRolRepository _rol_repository;
公开交易
{
获取=>\u事务;
}
公共思想非公开的
{
get=>\u退出存储库;
}
公共IUSUARIO存储库USUARIO存储库
{
get=>\u usuario\u存储库;
}
公共IRolRepository存储库
{
get=>\u rol\u存储库;
}
公共MSSQLSUnitOfWork()
{
var connection_string=ConfigurationManager.ConnectionStrings[“MSSQL”].ConnectionString;
_连接=新的SqlConnection(连接\u字符串);
_connection.Open();
_事务=_connection.BeginTransaction();
//TODO:Crear回购交易协议
}
公共无效提交()
{
_Commit();
}
公共无效回滚()
{
_transaction.Rollback();
}
受保护的虚拟void Dispose(bool disposeManagedObjects)
{
如果(!\u已处理)
{
if(处置对象)
{
_事务处理?.Dispose();
_连接?.Dispose();
}
_已处理=真;
}
}
公共空间处置()
{
处置(真实);
}
}

我向你推荐3种不同的东西

  • 在实例化UnitOfWork的存储库中启动、提交和回滚数据事务—我建议至少这样做

  • 创建一个服务类,您可以在其中创建UnitOfWork的实例,并将实例或DBContext传递给事务中涉及的存储库

  • 在知道当前DBContext的UnitOfWork类中创建存储库实例,然后可以从UnitOfWork访问存储库操作,并在同一上下文中启动和结束事务。更多推荐

  • 比如:

    UnitOfWorkInstance.MyRepositoryA.AddAsync(...);
    UnitOfWorkInstance.MyRepositoryB.AddAsync(...);
    UnitOfWorkInstance.Commit();
    
    我找到了迈塞尔
    builder.RegisterType<MSSQLUnitOfWork>()
           .As<IUnitOfWork>()
           .InstancePerLifetimeScope()
    builder.Register(c => c.Resolve<IUnitOfWork>().Transation)
           .As<IDbTransaction>();
    builder.Register(c => c.Resolve<IUnitOfWork>().Connection)
           .As<IDbConnection>();