在ASP.NET MVC中实现存储库模式和unitOfWork的最佳实践

时间:2013-12-20 16:06:25

标签: asp.net-mvc entity-framework repository-pattern unit-of-work

我正在努力实现最近几天的Repository Pattern和UnitOfWork,我相信,我已经完成了很多扩展。我确信有很多方法可以实现,但我很有兴趣找到最佳方法。

我正在使用visual studio 2013在ASP.NET MVC 5中编写非常简单的示例。我主要关注的问题是UnitOfWork的实现。是否建议在私有方法中使用多个UnitOfWorks来实现存储库函数,并为控制器提供公共函数使用????

我通过通用存储库在控制器类中有函数表(SQL Server)。我有IGenericRepository,它有一个IQueryable函数,我有GenericRepository类,我正在实现这个接口。我得到了从baseContext继承的FunctionContext。我有baseContext的原因是所有dbcontexts都可以使用一个路径来命中数据库但同时保持表的数量仅限于业务需求。

现在我的方法;

  1. One BaseContext:DbContext
  2. 多个DbContext,将所有必需的表捆绑到扩展BaseContext
  3. 的各个业务关注点
  4. 通用存储库接口(CRUD)
  5. 通用存储库实现类
  6. 特定的Repository类,扩展Generic Reposirtory,以防在CRUD操作之上需要更多功能。
  7. 个人单位工作 - >以私有方法获取所需的存储库/存储库,并仅为使用函数提供公共方法
  8. 控制器调用要求UnitOfWork使用公共方法。
  9. 在下面的程序中,所有我都获得了功能标题列表并传递给控制器​​进行打印

    通用存储库接口

     public interface IGenericRepository<TEntity> : IDisposable
    {
        IQueryable<TEntity> GetAll(); 
    
    }
    

    通用存储库

    public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
    {
        protected DbSet<TEntity> _DbSet;
        private readonly DbContext _dbContext;
    
        public GenericRepository()
        {
    
        }
    
        public GenericRepository(DbContext dbContext)
        {
            this._dbContext = dbContext;
            _DbSet = _dbContext.Set<TEntity>();
        }
    
    
    
        public IQueryable<TEntity> GetAll()
        {
            return _DbSet;
        }
    
    
        public void Dispose()
        {
    
        }
    }
    

    BaseContext

     public class BaseContext<TContext> : DbContext where TContext : DbContext
    {
        static BaseContext()
        {
            Database.SetInitializer<TContext>(null);
        }
    
        protected BaseContext()
            : base("name = ApplicationDbConnection")
        { }
    }
    

    FunctionContext

     public class FunctionsContext : BaseContext<FunctionsContext>
    {
        public DbSet<App_Functions> Functions { get; set; }
    }
    

    函数映射类

    [Table("Functions")]
    public class App_Functions
    {
         public App_Functions()
        {
        }
    
        [Key]
        public int Function_ID { get; set; }
    
        [StringLength(50)]
        [Required]
        public string Title { get; set; }
    
        public int Hierarchy_level { get; set; }
    }
    

    功能域类

     public class Functions
    {
        public Functions()
        {
    
        }
    
        public int Function_ID { get; set; }
        public string Title { get; set; }
        public int Hierarchy_level { get; set; }
    }
    

    Function_UnitOfWork

    public class Function_UnitOfWork
    {
       private GenericRepository<App_Functions> _function_Repository = new GenericRepository<App_Functions>(new FunctionsContext());
    
       public Function_UnitOfWork()
       {
    
       }
    
       private List<Functions> getAllFunctionsFromRepository()
       {
           List<Functions> query = new List<Functions>();
    
           query = _function_Repository.GetAll().Select(x => new Functions
           {
               Function_ID = x.Function_ID,
               Title = x.Title,
               Hierarchy_level = x.Hierarchy_level
           }).ToList();
    
           return query; 
       }
    
       public List<Functions>GetAllFunctions()
       {
           return getAllFunctionsFromRepository();
       }
    
    
    
    }
    

    控制器类

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
             Function_UnitOfWork UOF = new Function_UnitOfWork();
    
           var a1 = UOF.GetAllFunctions();
    
            foreach(var item in a1)
            {
                var b1 = item.Title;
            }
    
    
            return View();
        }
    }
    

1 个答案:

答案 0 :(得分:2)

虽然它是基于意见的,但只是工作单位模式的名称表明对象的有限时间跨度。所以在控制器中使用它应该像

public ActionResult Index()
{
   using(var UOF = new Function_UnitOfWork()) {

     var a1 = UOF.GetAllFunctions();

     foreach(var item in a1)
     {
       var b1 = item.Title;
     }
   }

    return View();
}

我们使用的一种方法(简称)

public class DataObject { }

public class Repo: IRepo<T> where T: DataObject

public class RepoController<T> : Controller where T: DataObject {
   protected IRepo<T> Repo;
}

因此,控制器将是通用的,并且将具有特定仓库的字段

你将使用一些依赖注入工具,比如ninject或mef来绑定控制器和场景后面的repos。