我在体系结构中使用存储库、工作单元和依赖项注入模式我的分层:
核心
数据层
BusinessLayer
ServiceLayer
我的结构有问题,以以上的工作班为单位
public class UnitOfWork:IUnitOfWork
{
private readonly IDataContext _context;
private IKullaniciDal _kullaniciDal;
private IKategoriDal _kategoriDal;
private IUrunDal _urunDal;
public UnitOfWork(IDataContext context)
{
_context = context;
}
public IKategoriDal KategoriDal => _kategoriDal ?? (_kategoriDal = new KategoriDal(_context));
public IKullaniciDal KullaniciDal => _kullaniciDal ?? (_kullaniciDal = new KullaniciDal(_context));
public IUrunDal UrunDal => _urunDal ?? (_urunDal = new UrunDal(_context));
public void SaveChanges()
{
_context.SaveChanges();
}
}
在这里,我想注入像_kullaniciDAL 这样的DataAccessLayers
搜索了很多,我看到了一些生成存储库的示例,但我不想直接从业务访问存储库实例,我想访问我的KullaniciDal类的实例这是KullaniciDal 的代码
public interface IKullaniciDal : IRepositoryEntityFramework<Kullanici>
{
}
public class KullaniciDal : RepositoryEntityFramework<Kullanici>, IKullaniciDal
{
public KullaniciDal(IDataContext dbContextBase) : base(dbContextBase)
{
}
}
我想给数据访问层写一些额外的函数,特别是其中的一些函数,并想将这些实例作为工作单元的一部分
如何注入Dal类?请注意,我将上下文对象传递给每个dal类
我在这里看到了几个问题。
首先,你的UoW正在更新DAL本身,而不是让DI注入它。如果你要走DI路由,最好让DI注入所有内容,让它自己管理对象的范围等。一般来说,如果您发现自己在基础结构类中使用new(),请退一步考虑注入它
public class UnitOfWork:IUnitOfWork
{
private readonly IDataContext _context;
public UnitOfWork(IDataContext context,IKullaniciDal kullaniciDal,IKategoriDal kategoriDal, IUrunDal urunDal)
{
KullaniciDal = kullaniciDal;
KategoriDal = kategoriDal;
UrunDal = urunDal;
_context = context;
}
public IKategoriDal KategoriDal{get;private set;}
public IKullaniciDal KullaniciDal{get;private set;}
public IUrunDal UrunDal{get;private set;}
public void SaveChanges()
{
_context.SaveChanges();
}
}
下一个问题更像是一个设计问题。为什么UoW需要所有这些DAL?我自己也觉得奇怪。
如果我正在实现一个需要控制UoW和DAL的业务层,我会简单地将它们注入业务层。
public class FooBLL
{
private IKullanicDal _kullanicDal;
private IUnitOfWork _unitOfWork;
public FooBLL(IKullanicDal kullanicDal,IUnitOfWork unitOfWork)
{
_kullanicDal = kullanicDal;
_unitOfWork = unitOfWork;
}
public void FooBusinessMethod()
{
_unitOfWork.Begin();
//do something with dal
//_unitOfWork.Commit etc
}
}
的确,当使用诸如EF之类的ORM时,存储库/dll和工作单元都需要上下文,但它们是独立的模式。我会允许你的DI容器适当地确定你的上下文、UoW、BLL等的范围,你不需要担心传递依赖关系,让容器为你做这项工作。
这也有其他SOLID设计的好处。考虑一下您是否正在实现一个http过滤器,该过滤器可以通过http会话自动提交您的uow。过滤器只需要知道IUnitOfWork方法提交、回滚等。它应该取决于最小接口,不需要知道DAL。
我发现了另一种在需要时即时创建存储库的解决方案。它还支持多个数据上下文,还有一点是IUnitOfWork接口继承了IDisposable。该代码适用于EF Core v2.0。这是所有UnitOfWork.cs类代码:
public class UnitOfWork<TContext> : IUnitOfWork<TContext> where TContext : DbContext
{
private Dictionary<string, dynamic> _repositories;
private DbContext _context;
public UnitOfWork(TContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
}
public IRepository<TEntity> Repository<TEntity>() where TEntity : class, IEntity, new()
{
if (_repositories == null)
{
_repositories = new Dictionary<string, dynamic>();
}
var type = typeof(TEntity).Name;
if (_repositories.ContainsKey(type))
{
return (IRepository<TEntity>)_repositories[type];
}
_repositories.Add(type, Activator.CreateInstance(typeof(RepositoryEntityFramework<TEntity>), _context));
return _repositories[type];
}
public void SaveChanges()
{
_context.SaveChanges();
}
public void BeginTransaction(System.Data.IsolationLevel isolationLevel = System.Data.IsolationLevel.ReadCommitted)
{
_context.Database.BeginTransaction();
}
public bool Commit()
{
_context.Database.CommitTransaction();
return true;
}
public void Rollback()
{
_context.Database.RollbackTransaction();
}
/// <inheritdoc />
/// <summary>
/// Disposes the current object
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Disposes all external resources.
/// </summary>
/// <param name="disposing">The dispose indicator.</param>
private void Dispose(bool disposing)
{
if (disposing)
{
if (_context != null)
{
_context.Dispose();
_context = null;
}
}
}
}