【问题标题】:best practice to implement repository pattern and unitOfWork in ASP.NET MVC [closed]在 ASP.NET MVC 中实现存储库模式和 unitOfWork 的最佳实践 [关闭]
【发布时间】:2013-12-20 16:06:24
【问题描述】:

我相信,从最近几天开始,我正在实施存储库模式和 UnitOfWork,我已经完成了很好的扩展。我相信有很多方法可以实现这一点,但我很感兴趣找到最好的方法。

我正在使用 Visual Studio 2013 在 ASP.NET MVC 5 中编写非常简单的示例。我的主要问题是 UnitOfWork 的实现。是否建议为每个业务问题使用多个 UnitOfWorks 以私有方法实现存储库功能并放弃公共功能供控制器使用????

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

现在在我的方法中;

  1. 一个 BaseContext:DbContext
  2. 多个 DbContext,将所有必需的表捆绑到扩展 BaseContext 的单个业务关注点
  3. 通用存储库接口 (CRUD)
  4. 通用存储库实现类
  5. 特定的存储库类,扩展通用存储库,以防在 CRUD 操作之上需要更多功能。
  6. Individual UnitOfWork --> 以私有方法获取所需的存储库/存储库,并提供仅用于使用函数的公共方法
  7. 控制器调用要求 UnitOfWork 使用公共方法。

在下面的程序中,我得到的只是函数标题列表并传递给控制器​​进行打印

通用存储库接口

 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()
    {

    }
}

基础上下文

 public class BaseContext<TContext> : DbContext where TContext : DbContext
{
    static BaseContext()
    {
        Database.SetInitializer<TContext>(null);
    }

    protected BaseContext()
        : base("name = ApplicationDbConnection")
    { }
}

函数上下文

 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();
    }
}

【问题讨论】:

  • 这是一个意见问题,并不适合 StackOverflow。您可以查看其他与编程相关的 StackExchange 站点之一,看看它是否更适合他们的问题指南。
  • 在我看来这个问题属于programmers.stackexchange.com
  • @Lankymart 我同意这是一个非常有用的问题,但最佳实践指南只是基于意见的另一种说法,因此更适合提到的其他 StackExchange 站点之一。 StackOverflow 的最佳实践指南在附有具体答案时非常有用。
  • 如果你们注意到我也放了小的完整示例存储库和工作单元,但我的问题是了解使用多个工作单元、封装存储库代码并为控制器提供公共功能来实现

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


【解决方案1】:

虽然它是基于意见的,但只是工作单元模式的名称暗示了对象的有限时间跨度。所以在控制器中使用它应该是这样的

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;
}

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

您将使用一些依赖注入工具,例如 ninject 或 mef,在后台将控制器与 repos 绑定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-08
    • 1970-01-01
    • 2011-07-08
    相关资源
    最近更新 更多