6

我目前被分配到一个使用实体框架的 asp mvc 项目。这将是一个业务线应用程序。我想使用存储库和工作单元模式开发这个应用程序。我是这种模式的新手(也是.net 的新手),我在理解这种模式以及如何实现它时遇到了问题。

我已经阅读了很多文章,我认为这就是我的应用程序应该是的样子

实体框架 -> 存储库 -> 工作单元 -> 客户端(Asp MVC)

我附上了这篇文章中的一些代码 http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in -an-asp-net-mvc-应用程序

using System;
using ContosoUniversity.Models;

namespace ContosoUniversity.DAL
{
    public class UnitOfWork : IDisposable
    {
        private SchoolContext context = new SchoolContext();
        private GenericRepository<Department> departmentRepository;
        private GenericRepository<Course> courseRepository;

        public GenericRepository<Department> DepartmentRepository
        {
            get
            {

                if (this.departmentRepository == null)
                {
                    this.departmentRepository = new GenericRepository<Department>(context);
                }
                return departmentRepository;
            }
        }

        public GenericRepository<Course> CourseRepository
        {
            get
            {

                if (this.courseRepository == null)
                {
                    this.courseRepository = new GenericRepository<Course>(context);
                }
                return courseRepository;
            }
        }

        public void Save()
        {
            context.SaveChanges();
        }

        private bool disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    context.Dispose();
                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    }
}

工作单元将具有存储库,并将在创建时创建 DBContext

因此控制器将在创建时创建工作单元。要显示数据,我将使用此代码

var department = UoW.departmentRepository.Find(1);
return View(department);

当客户端单击保存按钮时,我将运行此代码

UoW.departmentRepository.Update(department);
UoW.Save();

我的问题:

  1. 如果从数据检索到客户端单击保存按钮需要几个小时怎么办。据我所知,我们必须尽可能缩短上下文。

  2. 我应该把业务逻辑放在哪里?我把它放在存储库中吗?所以我会在保存之前调用 UoW.departmentRepository.Validate(department) 。但是,如果我需要验证与其他实体相关的实体怎么办。我打电话给 UoW.departmentRepository.Validate(课程,部门)吗?

是否有此类应用程序的完整示例项目?

编辑

正如 Ant P 建议的那样,我需要添加另一层来放置我的业务逻辑。

这就是我到目前为止所做的

工作单位:

public class UnitOfWork : IDisposable
{
    private DBContext _context = new DBContext();

    public DBContext Context 
    {
      get 
      {
        return this._context;
      }
    }

    public void Save()
    {
        _context.SaveChanges();
    }

    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                context.Dispose();
            }
        }
        this.disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

商业逻辑:

public class SalesBusinessLogic : IDisposable
{
    private ICustomerRepository _customerRepo;
    private ISalesRepository _salesRepo;
    private UnitOfWork _uow;

    public SalesBusinessLogic(UnitOfWork uow)
    {
      this._uow = uow;
    }

    public ICustomerRepository CustomerRepo
    {
        get
        {

            if (this._customerRepo == null)
            {
                this._customerRepo = new CustomerRepository(this._uow);
            }
            return this._customerRepo;
        }
    }

    public ISalesRepository SalesRepo
    {
        get
        {

            if (this._salesRepo == null)
            {
                this._salesRepo = new SalesRepository(this._uow);
            }
            return this._salesRepo;
        }
    }

    public bool Validate(Sales sales)
    {
      //this is where validation performed
      return true;
    }
}

控制器:

public SalesController : Controller
{
    private UnitOfWork _uow = new UnitOfWork();
    private SalesBusinessLogic _bl = new SalesBusinessLogic(this._uow);

    public ActionResult Index()
    {
        var sales = _bl.SalesRepo.Find(1);
        sales.CustomerID = 1;
        if _bl.Validate(sales)
        {
          _bl.SalesRepo.Update(sales);
          _uow.Save();
        }
        return View(sales);
    }    
}

这里 UnitOfWork 仅充当 dbcontext 的提供者,将由业务逻辑和存储库使用。存储库将在 BusinessLogic 类中。

服务器端验证将由 BusinessLogic 处理,客户端验证将由 Web 层中的视图模型处理。

我唯一担心的是 UnitofWork 中的 dbcontext 是可公开访问的。

我在这里的方向正确吗?

4

1 回答 1

9

如果从数据检索到客户端单击保存按钮需要几个小时怎么办。据我所知,我们必须尽可能缩短上下文。

这不是问题——控制器是根据请求实例化的。当用户查看页面时,它不会持续存在。听起来您误解了控制器在什么时候被实例化。当您在控制器的构造函数中实例化 UnitOfWork 时,流程如下所示:

  • 用户发出 POST 请求(通过单击“保存”)。
  • 请求到达服务器并实例化控制器(从而实例化工作单元)。
  • 调用动作方法。
  • 工作单元被处置。

我应该把业务逻辑放在哪里?我把它放在存储库中吗?所以我会在保存之前调用 UoW.departmentRepository.Validate(department) 。但是,如果我需要验证与其他实体相关的实体怎么办。我打电话给 UoW.departmentRepository.Validate(课程,部门)吗?

通常,您的业务逻辑将被抽象为位于 Web 应用程序和存储库之间的单独层。向您展示直接注入控制器的存储库的教程假定您具有“精简”业务逻辑。

但是,验证绝对不是存储库的工作。您应该为每个视图创建一个单独的视图模型并在控制器中验证它们。存储库应该仅用于 CRUD 操作。

于 2013-09-19T08:15:39.963 回答