我正在使用UOW和Repository模式构建一个Web应用程序。我对此有一个基本的了解,我想知道我是否应该为我的项目中的所有表保留一个UOW实现,或者根据功能保留一个单独的实现,例如:
public interface IHomeUOW
{
IGenericRepository<User> Users { get; }
IGenericRepository<TableA> Table_A { get; }
IGenericRepository<TableB> Table_B{ get; }
}
public interface IBusinessCaseUOW
{
IGenericRepository<TableA> Table_A { get; }
IGenericRepository<TableXYZ> Table_XYZ{ get; }
}
如您所见,TableA既可用于Home UOW,也可用于特定的商业案例UOW。一个UOW部分实现如下:
public class UnitOfWork : IUnitOfWork
{
private readonly ObjectContext _context;
private UserRepository _userRepository;
public UnitOfWork(ObjectContext Context)
{
if (Context == null)
{
throw new ArgumentNullException("Context wasn't supplied");
}
_context = Context;
}
public IGenericRepository<User> Users
{
get
{
if (_userRepository == null)
{
_userRepository = new UserRepository(_context);
}
return _userRepository;
}
}
}
我的存储库就像这样
public interface IGenericRepository<T>
where T : class
{
//Fetch records
T GetSingleByRowIdentifier(int id);
T GetSingleByRowIdentifier(string id);
IQueryable<T> FindByFilter(Expression<Func<T, bool>> filter);
// CRUD Ops
void AddRow(T entity);
void UpdateRow(T entity);
void DeleteRow(T entity);
}
public abstract class GenericRepository<T> : IGenericRepository<T>
where T : class
{
protected IObjectSet<T> _objectSet;
protected ObjectContext _context;
public GenericRepository(ObjectContext Context)
{
_objectSet = Context.CreateObjectSet<T>();
_context = Context;
}
//Fetch Data
public abstract T GetSingleByRowIdentifier(int id);
public abstract T GetSingleByRowIdentifier(string id);
public IQueryable<T> FindByFilter(Expression<Func<T, bool>> filter)
{
//
}
//CRUD Operations implemented
}
public class UserRepository : GenericRepository<User>
{
public UserRepository(ObjectContext Context)
: base(Context)
{
}
public override User GetSingleByRowIdentifier(int id)
{
//implementation
}
public override User GetSingleByRowIdentifier(string username)
{
//implementation
}
}
你怎么看?如果这不是DDD的UOW和Repository模式的正确实现,它会失败,因为只是编写一堆代码来抽象调用EF表吗?
谢谢你的时间..
答案 0 :(得分:5)
我对通用存储库过敏。每次我使用一个我必须做的解决开放/封闭原则的解决方法。
我建议您切换到根聚合特定存储库并在其中使用OR / M.
工作单位。 EF和nhibernate已经实现了模式。只需创建一个界面,如:
public interface IUnitOfWork : IDisposable
{
void SaveChanges();
}
不保存处置=回滚。
nhibernate实现看起来像(快速写入,未经过测试):
public class NHibernateUnitOfWork : IDisposable
{
public NHibernateUnitOfWork(ISession session)
{
_transaction = session.BeginTransaction();
}
public void SaveChanges()
{
_transaction.Commit();
}
public void Dispose()
{
_transaction.Dispose();
}
}
使用IoC容器非常简单。只需在其中注册实现。
我最喜欢在ASP.NET MVC中获得事务支持的解决方案是创建一个名为ActionFilter
的自定义TransactionalAttribute
并让它处理UnitOfWork实现:
[HttpPost, Transactional]
public ActionResult Update(YourModel model)
{
}
我刚刚将答案转换为更详细的博文:http://blog.gauffin.org/2012/02/repositories-unit-of-work-and-asp-net-mvc/
答案 1 :(得分:1)
我认为这是错误的。
UnitOfWork是Transaction(简单来说)。它至少应包含一个方法Complete(Commit)。
如果你使用EntityFramework你包装ObjectContext,如果你使用纯ADO .NET你包装TransactionScope,如果使用NHibernate ISession等。
这是我的UOF:
public interface IUnitOfWork : IDisposable
{
void Complete();
TRepository GetRepository<TRepository, TItem>()
where TRepository : IRepository<TItem>
where TItem : class;
}