如何在ASP MVC中实现工作单元,存储库和业务逻辑?

时间:2013-09-19 02:59:06

标签: c# asp.net-mvc entity-framework design-patterns domain-driven-design

我目前被分配到使用实体框架的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-application

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(部门)。但是,如果我需要验证与其他实体相关的实体,该怎么办?我是否打电话给UoW.departmentRepository.Validate(课程,部门)?

  3. 是否有针对此类应用的完整示例项目?

    修改

    正如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层中的viewmodel处理。

    我唯一关心的是UnitofWork中的dbcontext是公共可访问的。

    我在这方面的正确方向吗?

1 个答案:

答案 0 :(得分:9)

  

如果从数据检索到客户端单击“保存”按钮需要数小时,该怎么办?据我所知,我们必须尽量缩短背景。

这不是问题 - 控制器是按请求实例化的。用户查看页面时不会保留。听起来你误解了控制器实例化的时间。当您在控制器的构造函数中实例化UnitOfWork时,流程如下所示:

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

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

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

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