这是一个很好的UnitOfWork与DDD的存储库模式设计

use*_*358 1 c# asp.net-mvc domain-driven-design unit-of-work repository-pattern

我正在使用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; }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,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;
        }
    }
 }
Run Code Online (Sandbox Code Playgroud)

我的存储库就是这样的

    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
         }
   }
Run Code Online (Sandbox Code Playgroud)

你怎么看?如果这不是DDD的UOW和Repository模式的正确实现,它会失败,因为只是为了抽象调用EF表而编写的一堆代码?

谢谢你的时间..

jga*_*fin 5

我对通用存储库过敏.每次我使用一个我必须做的解决开放/封闭原则的解决方法.

我建议您切换到根聚合特定存储库并在其中使用OR/M.

至于工作单位.EF和nhibernate已经实现了模式.只需创建一个界面,如:

public interface IUnitOfWork : IDisposable
{
    void SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

处理而不保存=回滚.

nhibernate实现看起来像(快速写入,未测试):

public class NHibernateUnitOfWork : IDisposable
{
    public NHibernateUnitOfWork(ISession session)
    {
        _transaction = session.BeginTransaction();
    }

    public void SaveChanges()
    {
        _transaction.Commit();
    }

    public void Dispose()
    { 
        _transaction.Dispose();
    }
}
Run Code Online (Sandbox Code Playgroud)

使用IoC容器非常简单.只需在其中注册实现.

我最喜欢在ASP.NET MVC中获得事务支持的解决方案是创建一个ActionFilter类似的自定义命令TransactionalAttribute,让它处理UnitOfWork实现:

[HttpPost, Transactional]
public ActionResult Update(YourModel model)
{
}
Run Code Online (Sandbox Code Playgroud)

我刚刚将答案转换为更详细的博客文章:http://blog.gauffin.org/2012/02/repositories-unit-of-work-and-asp-net-mvc/