【问题标题】:How do architect an ASP.Net MVC app with EF?如何使用 EF 构建 ASP.Net MVC 应用程序?
【发布时间】:2011-12-10 14:30:31
【问题描述】:

我在概念化如何将带有实体框架的 MVC 应用程序构建为 n 层应用程序时遇到了一些麻烦。

普通的、教科书式的 3 层应用程序应该看起来像

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

演示文稿不应该对数据访问一无所知。使用 EF,所有层都需要了解模型。所以我的架构现在看起来更像

Data Access->Business Logic
     |               |
      ---------------
             |
            MVC

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

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

【问题讨论】:

  • 这是一本很好的关于 .NET 应用程序架构的读物,其中有一个关于 MVC 的部分:amazon.com/…

标签: asp.net-mvc entity-framework architecture


【解决方案1】:

我可以向您推荐一本非常好的(我认为)关于 .NET 平台上的域驱动架构设计的书。本书 si 使用 .NET 4.0 称为 N 层域驱动架构指南。书中解释了如何使用 EF 和 MVC(以及许多其他东西,如 Silverlight、带有 Unity 的 IoC 等)创建良好的架构。

书可以在这个地址下载:

http://msdn.microsoft.com/es-es/architecture/en/

示例应用程序也很有趣:

http://microsoftnlayerapp.codeplex.com/

为 EF 创建实体的最佳方式是创建独立于持久层的 POCO 类。这些领域实体包含在领域(业务)逻辑层中。

书中还解释了应用程序应该被划分为更多层,他们解释了表示层、应用程序层、域层、基础设施层(主要是数据持久性)、横切层和分布式服务层。

【讨论】:

    【解决方案2】:

    好吧,我想您的问题是,如何在 MVC 应用程序中构建“层”。 看看这个简单的架构,我将它用于我的 MVC 应用程序,它似乎干净高效。

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

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

    3. 项目 - 我通常称它为“ServiceLayer”左右(我愿意建议更好的名称:) - 它只包含接口,用于存储库和其他服务(在单独的项目中实现),这将我的 MVC(或任何其他技术)基于应用程序的使用; 2.project 中的存储库实现了这些接口

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

    看起来像这样:

    瘦控制器:

    公共类SomethingController:BaseController { 公共 ActionResult DoSomething(SomeBusinessThing 输入) { 如果(模型状态。IsValid) { var 结果 = CustomerRepository.DoSomeBusinessLogicAndPersistenceAndStuff(input); 返回视图(结果); // 如果你不想使用业务对象作为视图模型,你可以在这里使用 AutoMapper } } }

    我的存储库“属性”是从我的 BaseController 继承的:

    公共类 BaseController : 控制器 { // ...所有(或多个)控制器使用的其他东西 私人 ICustomerRepository _customerRepository; 受保护的 ICustomerRepository CustomerRepository { 得到 { 如果(_customerRepository== null) _customerRepository= DependencyResolver.Current.GetService(); 返回_customerRepository; } } }

    如果你的控制器使用许多服务,你可以使用这个“惰性”DI,但每个操作只有 1-2 个,所以用构造函数注入所有这些服务效率低下。有人可能会告诉你这样“隐藏”了依赖关系,但如果你把所有这些东西都放在一个地方——BaseController,那就没什么大不了了。

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

    结论:

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

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

    • ViewModel 是 View 的输入(ViewModel 可以直接作为您的业务模型,或者您可以使用 AutoMapper 创建“纯”ViewModel)

    【讨论】:

    • 您有基于上述架构师的示例项目吗?
    • 非常有用的答案。顺便说一句,我相信第三层被称为“应用层”。
    • @rouen 在 SomethingController 中而不是在 Repository 类中执行业务逻辑 (CustomerRepository.DoSomeBusinessLogicAndPersistenceAndStuff) *这赋予了存储库类 2 责任 * 如果有会更好BusinessLogic。所以架构看起来像这样controller -> businessLogic -> data
    【解决方案3】:

    您可以将您的 EF 实体视为数据对象,并有单独的 view-models 传递到视图中。来自 EF 对象的数据可用于填充视图模型(AutoMapper 之类的库在这里很有用)。这样,您的视图永远不会直接依赖于 EF 对象,而只会依赖于您的视图模型。

    【讨论】:

    • 我假设视图模型不是 MVC 中的 MV,对吧?视图模型与 EF 相关吗?
    • 视图模型是一个独立于您的数据访问库的标准类。它是一个包含视图将使用的数据的哑对象。
    • @Scottie - EF 中的数据对象特定于 EF(如果您想保持干净的代码分离),所以不要在数据层之外使用它们。
    猜你喜欢
    • 2015-04-10
    • 2011-12-21
    • 1970-01-01
    • 1970-01-01
    • 2012-08-25
    • 2018-10-06
    • 2011-04-06
    • 1970-01-01
    • 2014-08-23
    相关资源
    最近更新 更多