【问题标题】:Business logic layer in ASP.NET MVC - ArchitectureASP.NET MVC 中的业务逻辑层 - 架构
【发布时间】:2017-01-10 08:35:49
【问题描述】:

我对 ASP.NET MVC 还很陌生。我真的对我的项目的架构感到困惑。让我向你们解释我的困惑:

在我的项目中,我们都知道三个部分。它们是:控制器、模型和视图。

控制器位于Controllers 文件夹中,视图位于Views 文件夹中,模型位于Models 文件夹中。

众所周知,模型有两种类型:数据模型和业务模型。数据模型具有项目中要使用的所有数据类型,业务模型确实具有与项目相关的附加逻辑。除此之外,还有一个与数据库对话的应用程序数据层。

我将为这个数据层创建一个与数据库对话的类库项目。此外,我的 MVC 项目的 Models 文件夹将仅包含数据模型,并且我还将为业务模型类创建一个不同的库。

现在我面临的问题是:

假设我的MVC项目名称是MVCProj,数据层项目名称是DataProj,业务层项目名称是BusinessProj。 如果我在MVCProj 的Models 文件夹中定义数据类型,我必须在BusinessProj 和DataProj 项目中包含它的引用。另外,我必须在我的MVCProj 中使用BusinesProj 类。因此我必须在MVCProj 中添加BusinessProj 的引用,这会导致循环依赖。

我不确定我所设想的架构是否正确。请帮我解决。

【问题讨论】:

  • 对于实体类型和接口等常见依赖项拥有一个共享项目是很常见的。这个项目在解决方案中通常没有任何自己的依赖项。
  • 如果我将数据类型移动到不同的项目,那么 MVC 项目中的 Models 文件夹将是空的。
  • MVCProj 应该有对BusinessProj 的引用,BusinessProj 不需要对MVCProj 的引用。这样你就不应该得到循环依赖。

标签: asp.net-mvc


【解决方案1】:

Arsen 的回答已经解释得很好,但我只是想发表自己的经历(评论太长了。)

您分离业务逻辑和 DataAcess 的想法很好。我从事的大多数项目都是以类似的方式组织的。

在你的情况下我会做的是:

1 - 为 DataAcess 创建一个项目:MVCProj.DataAcess

2 - 创建另一个项目仅包含您的数据库实体:MVCProj.Entities

3 - 在您的 MVCProj.DataAcessproject 中添加 MVCProj.Entities 的引用

4 - 为您的业务层创建一个项目:MVCProj.Business:

5 - 在您的MVCProj.Business 项目中添加MVCProj.Entities 和MVCProj.DataAcess 的引用(我假设业务层将调用数据库)

6 - 将 MVCProj.Entities 和 MVCProj.Business 的引用添加到您的 MVC 项目。

看到逻辑了吗?每一层都负责做“它的工作”。现在 MVC 控制器可以调用业务,调用数据库来保存记录。所有项目共享相同的实体。

MVC 项目中的“Models”文件夹只是团队提供的一个示例。在网络上的大多数示例中,您会看到人们直接在控制器内部调用数据库(主要使用实体框架)。这行得通,但从长远来看,维护起来非常糟糕。

大多数人做的另一件事是:您通常不想在控制器中返回数据库实体。也许它们包含比您需要的更多的属性等等。在这种情况下,您可以创建所谓的 ViewModel。考虑一个类似于实体类副本的 ViewModel,但仅包含与视图相关的字段。 ViewModel 特定于 MVC 项目,因此它们将保留在 MVC 项目内的文件夹中。您可以选择称它为 Models 或 ViewModels。

没有更进一步,但是通过我上面展示的项目分离,您可以明确地寻找一个依赖注入框架来为您处理类实例的所有创建。 :)

注意:这是隐含的,但除了 MVC 之外的所有项目都只是普通的旧类库。

希望这有助于澄清您的想法。

【讨论】:

    【解决方案2】:

    架构中没有灵丹妙药,这一切都不是必须的,而是取决于项目......

    应用程序中的层数很大程度上取决于要求。

    一方面,附加层将关注点分开(例如:从数据访问到业务逻辑),另一方面,每个级别都会增加工作量并降低性能

    关于你的问题,没关系,当一层依赖于另一层时,第三层依赖于第一层是不行的......

    在您的情况下,您选择 3 级,理想情况下应该是这样的

    DataAccess,其数据类位于单独的项目中

    BusinessLogic,另一个项目,调用数据访问,并将结果转换为它的数据类

    最后只在模型参考 BusinessLogic 上

    【讨论】:

    • 我应该在哪里定义要在 MVCProj 中使用的数据类型?为每个层定义单独的数据类型是否有效?假设我有数据类型“问题”,我在 MVC 项目内的一个类中定义它,业务层内的另一个类和数据层内的另一个类也是如此。有什么方法可以让我只定义一次该类吗?
    • 为了完全分离图层,是的,您应该为每个图层定义自己的数据类型...您可以使用 AutoMap 自动从一个数据复制到另一个...但同样取决于您是否不这样做想要增加你的工作,这不是项目必须的,你可以创建 project.data 保存所有数据,并从 DataAccess 返回,而不是在 BL 中操作
    【解决方案3】:

    我写了一篇文章,我认为我可以帮助你解决一些困惑:Entities are not Models。

    TL;DR 您在这里感到困惑的主要原因似乎是您认为您需要 MVC 项目的 Models 文件夹中的“数据模型”(实体)。这在两个方面是不正确的。首先,Models 文件夹毫无意义。您可以重命名它,删除它,等等。它根本不会影响您的应用程序。其次,正如我在帖子中提到的细节,实体不是模型。它们只是并且应该是表结构的表示,以便为您的 ORM(可能是实体框架)提供一些地方来填充它从数据库中检索到的数据。

    也就是说,典型的方法如下:

    1. “DAL”类库包含您的上下文和实体。这就是您要进行迁移的地方。
    2. 一个“业务”类库,它基本上包装了 DAL,并提供了一个 API,您的 MVC 项目可以使用该 API 来获取数据。根据您的应用程序的复杂性,这是最可替代的层,因为您经常需要在可能普遍适用于您的组织开发的任何应用程序的“业务逻辑”与“业务逻辑”之间划清界限" 这与您正在开发的特定应用程序有关。
    3. 您的 MVC 项目,它将利用 DAL/业务层。

    然后,在您的 MVC 项目中,您的 Model 文件夹基本上可以消失,或者您可以将其用于存储视图模型。但是,通常会专门为这些人创建一个ViewModels 文件夹。不过,这完全取决于您。

    最后一点。 “业务层”也可以由多个不同的类库组成。例如,在我的组织中,我们有一个专门用于处理 POS 系统的库、一个用于连接我们用于电子邮件列表的 API 的库、一个用于处理 Elasticsearch 的库等。我们的 Web 项目只包含他们需要的任何库使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-12
      • 1970-01-01
      • 2014-06-01
      • 2016-06-05
      • 2011-12-03
      • 2011-09-03
      • 2010-12-07
      • 2021-02-24
      相关资源
      最近更新 更多