如何使用EF构建ASP.Net MVC应用程序?

Sco*_*tie 9 architecture asp.net-mvc entity-framework

我在构建如何使用Entity Framework构建MVC应用程序到n层应用程序时遇到了一些麻烦.

正常的教科书3层应用应该看起来像

数据访问 - >业务逻辑 - >演示

演示文稿不应该知道有关数据访问的任何信息.使用EF,所有图层都需要了解模型.所以我的架构现在看起来更像

Data Access->Business Logic
     |               |
      ---------------
             |
            MVC
Run Code Online (Sandbox Code Playgroud)

我在这里遗漏了什么,或者我是以错误的方式思考这个问题的?

我是否应该将EF本身视为数据访问层并将实体置于业务逻辑中?

rou*_*uen 9

好吧,我想你的问题是,如何在MVC应用程序中构建"层".看看这个简单的架构,我将它用于我的MVC应用程序,它看起来干净而高效.

  1. 解决方案中的项目 - 业务模型 - 充满代表业务领域的POCO类的简单类库.您可以在此处使用数据注释,使用验证逻辑的元数据类等.

  2. project - 基于EF的存储库 - 另一个简单的类库; 这里是定义的上下文(EF代码首先很好,但你可以先使用EF数据库或先使用模型 - 你只需要将POCO T4模板添加到业务模型类库中,没什么大不了的)和一组类 - 存储库

  3. 项目 - 我通常称它为"ServiceLayer"左右(我打开以获得更好的名称的建议:) - 它只包含接口,用于存储库和其他服务(在单独的项目中实现),这将基于我的MVC(或任何其他技术)申请用途; 2.project中的存储库实现了这些接口

  4. 项目 - MVC网站.它使用依赖注入(在DependencyResolver中构建,我喜欢使用Ninject容器)来映射存储库(和其他服务); 然后你可以使用构造函数注入控制器,或者一些"懒惰"的方法(见下文)

它看起来像这样:

瘦控制器:

public class SomethingController : BaseController
{
    public ActionResult DoSomething(SomeBusinessThing input)
    {
         if (ModelState.IsValid)
         {
             var result = CustomerRepository.DoSomeBusinessLogicAndPersistenceAndStuff(input);
             return View(result); // you can use AutoMapper here, if you dont want to use business object as viewmodels
         }
    }
}

我的存储库"property"继承自我的BaseController:

public class BaseController : Controller 
{
    // ... other stuff used by all (or multiple) controllers

    private ICustomerRepository _customerRepository;
        protected ICustomerRepository CustomerRepository
        {
            get
            {
                if (_customerRepository== null)
                    _customerRepository= DependencyResolver.Current.GetService();
                return _customerRepository;
            }
        }
}

如果您的控制器使用许多服务,您可以使用这个"懒惰"DI,但每个操作只能使用1-2个,因此使用构造函数注入所有服务会效率低下.有人可以通过这种方式告诉你"隐藏"依赖,但是如果你将所有这些东西放在一个地方--BaseController,那没什么大不了的.

那么,存储库的实现确实是您的业务.MVC应用程序甚至不知道你正在使用EF,它只知道服务的接口,并不关心底层实现(如果你需要,你可以随时切换!)

结论:

  • 控制器很瘦 - 没有业务逻辑

  • 模型是FAT - 在这种情况下,存储库封装了所有业务逻辑(您可以确定使用其他类型的服务,例如一些计算器用于处理等,请记住,MVC不关心,只知道接口)

  • ViewModel是Views的输入(ViewModel可以直接作为您的商业模型,也可以使用AutoMapper创建"纯"ViewModels)


Chr*_*tow 5

您可以将EF实体视为数据对象,并将单独的视图模型传递给视图.来自EF对象的数据可用于填充视图模型(像AutoMapper这样的库在这里很有用).这样,您的视图永远不会直接依赖于EF对象,只能在视图模型上.