C# 存储库模式工作单元依赖项注入Ninject
我在体系结构中使用存储库、工作单元和依赖注入模式 我的分层: 核心 数据层 业务层 服务层 我的结构有点不对劲,在上面提到的工薪阶层中C# 存储库模式工作单元依赖项注入Ninject,c#,dependency-injection,ninject,repository-pattern,unit-of-work,C#,Dependency Injection,Ninject,Repository Pattern,Unit Of Work,我在体系结构中使用存储库、工作单元和依赖注入模式 我的分层: 核心 数据层 业务层 服务层 我的结构有点不对劲,在上面提到的工薪阶层中 public class UnitOfWork:IUnitOfWork { private readonly IDataContext _context; private IKullaniciDal _kullaniciDal; private IKategoriDal _kategoriDal; private IUrun
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
搜索了很多,我看到了一些生成存储库的示例,但是我不想直接从业务访问存储库实例,我想访问KullaniciDal类的实例
这是KullaniciDal的代码
public interface IKullaniciDal : IRepositoryEntityFramework<Kullanici>
{
}
public class KullaniciDal : RepositoryEntityFramework<Kullanici>, IKullaniciDal
{
public KullaniciDal(IDataContext dbContextBase) : base(dbContextBase)
{
}
}
公共接口ikullanicial:IRepositoryEntityFramework
{
}
公共类KullaniciDal:RepositoryEntityFramework,IKullaniciDal
{
公共KullaniciDal(IDataContext dbContextBase):基(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等,您不必担心传递依赖项,让容器为您完成工作
这也有其他坚实的设计优势。考虑一下,如果你正在执行一个HTTP过滤器,自动提交你的UWO与HTTP会话。过滤器只需要知道IUnitOfWork方法commit、rollback等。它应该依赖于最小的接口,而不需要知道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;
}
}
}
}
公共类UnitOfWork:IUnitOfWork,其中TContext:DbContext
{
私人词典库;
私有DbContext _context;
公共工作单元(TContext上下文)
{
_context=context??抛出新ArgumentNullException(nameof(context));
}
公共IRepository存储库(),其中tenty:class、ienty、new()
{
如果(_==null)
{
_存储库=新字典();
}
var type=typeof(tenty).Name;
if(_repositories.ContainsKey(类型))
{
返回(IRepository)_存储库[类型];
}
_Add(type,Activator.CreateInstance(typeof(RepositoryEntityFramework),_context));
返回_存储库[类型];
}
公共void SaveChanges()
{
_SaveChanges();
}
public void BeginTransaction(System.Data.IsolationLevel IsolationLevel=System.Data.IsolationLevel.ReadCommitted)
{
_context.Database.BeginTransaction();
}
公共boolcommit()
{
_context.Database.CommitTransaction();
返回true;
}
公共无效回滚()
{
_context.Database.RollbackTransaction();
}
///
///
///处理当前对象
///
公共空间处置()
{
处置(真实);
总干事(本);
}
///
///处理所有外部资源。
///
///dispose指示灯。
私有无效处置(bool处置)
{
如果(处置)
{
如果(_context!=null)
{
_context.Dispose();
_上下文=空;
}
}
}
}
我尝试了您提供的方法,但我有一个问题,即工作单元中的上下文实例和dal中的实例不一样。我在RequestScope()中使用ninject Bind().To();我在哪里wrong@OkanSARICA这一定是ninject配置中的一个范围问题,请也发布该代码。我使用的是ninject.Web.Common nuget软件包,我卸载了它并安装了ninject.Mvc3,问题解决了,很有趣,很高兴你解决了。让那个容器为你做范围界定。