Asp.net mvc UnitOfWork-存储库-服务模式建议
因此,通常在实现此模式时,我让Asp.net mvc UnitOfWork-存储库-服务模式建议,asp.net-mvc,repository-pattern,unit-of-work,Asp.net Mvc,Repository Pattern,Unit Of Work,因此,通常在实现此模式时,我让服务获取存储库,然后让存储库获取工作单元 我在玩弄挂起UnitOfWork上的一个方法,该方法获取存储库,如下所示: public class UnitOfWork : IUnitOfWork { public IRepository<TEntity> GetRepository<TEntity>() where TEntity : Core.Domain.Model.EntityBase<TEntity> {
服务
获取存储库
,然后让存储库获取工作单元
我在玩弄挂起UnitOfWork
上的一个方法,该方法获取存储库
,如下所示:
public class UnitOfWork : IUnitOfWork
{
public IRepository<TEntity> GetRepository<TEntity>() where TEntity : Core.Domain.Model.EntityBase<TEntity>
{
return new Repository<TEntity>(this);
}
}
公共类UnitOfWork:IUnitOfWork
{
公共IRepository GetRepository(),其中tenty:Core.Domain.Model.EntityBase
{
返回新存储库(此存储库);
}
}
然后服务
将获取工作单元
,并可以从中解析所需的存储库
你觉得怎么样?你看到这有什么缺陷吗?我在我的ASP.NET MVC程序中使用了类似的方法,到目前为止,它运行得非常好 我的
IUnitOfWork
界面如下所示:
public interface IUnitOfWork
{
IRepository<TEntity> GetRepositoryFor<TEntity>() where TEntity : class;
void SaveChanges();
}
public interface IRepository<TEntity> : IQueryable<TEntity> where TEntity : class
{
TEntity Find(params object[] keyValues);
void Insert(TEntity entity);
void Update(TEntity entity);
void Delete(TEntity entity);
}
然后像这样将其传递给我的服务:
public abstract class BaseService
{
public BaseService(IUnitOfWork unitOfWork)
{
// etc...
}
}
您是对的,这使得服务可以轻松解析其存储库,而无需将它们单独传递给构造函数,这在您可能在单个服务中使用多个存储库(例如,采购订单和产品)的情况下非常有用
像这样使用ORM不可知接口的一个好处是,这意味着您可以轻松地切换ORM。老实说,我从实体框架转换到另一个ORM的可能性很小,但事实是,如果需要的话,我可以。作为奖励,我的服务更容易测试,我还发现这使我的服务类更干净,因为它现在完全不知道正在使用的ORM,并且完全针对上面的两个接口工作
关于关于通用存储库接口的评论,我的建议是要务实,做最适合您和您的应用程序的事情。关于Stackoverflow,在这个主题上有很多问题,答案各不相同,关于哪种方法是最好的(例如,公开IQueryable
vsIEnumerable
,通用与非通用)
我曾尝试过没有通用存储库,因为您可能已经注意到我的IRepository
界面看起来像IDbSet
;我之所以选择这种方法,是因为它允许我的实现处理您使用DbContext
所做的所有实体框架实体状态管理工作
public void Delete(TEntity entity)
{
if (Context.Entry(entity).State == EntityState.Detached)
{
EntitySet.Attach(entity);
}
EntitySet.Remove(entity);
}
如果我使用了
IDbSet
,我需要在我的服务层中执行此操作,这将需要依赖于DbContext
,这似乎比我的通用存储库更容易泄漏。如果您使用的是OR/M,则通用存储库实际上没有任何用途。@jgauffin-请您为我详细说明一下,好吗?通用存储库与使用或/M,除非您为每个实体类型自定义它们。