代码之家  ›  专栏  ›  技术社区  ›  taudep

将FAT控制器管理到业务服务层的一些ASP.NET MVC2最佳实践

  •  6
  • taudep  · 技术社区  · 14 年前

    我的控制器越来越大,越来越失控。

    典型的控制器执行以下操作:

    • 它确定给定用户是否有权访问给定资源。
    • 它验证了ViewModel。
    • 它将视图模型转换为用于持久性的DTomodel。
    • 它调用存储库来更新/创建新对象和关联的其他新对象。
    • 它访问多个存储库助手类中的数据
    • 它检查用户是否收到通知。
    • 它调用助手发送电子邮件
    • 它通过其他存储库对象将数据记录到数据库中
    • 等。。。

    总之,他们安排了很多事情。我想把所有东西都转移到服务层中,但在我喜欢的代码示例中还没有真正看到任何实现的模式。我看过一些开源项目,比如kigg、oxite、codecampserver等等,但它们都不能真正解决缩小控制器的问题。我想避免传递大量的httpContext内容,但这可能是不可能的。

    是否还有其他项目,最佳实践我可以看?我正在构建一个大型的工作流/数据输入应用程序。

    感谢您提供一些链接和建议

    5 回复  |  直到 14 年前
        1
  •  3
  •   KallDrexx    14 年前

    我不知道有什么真正的例子可以在我的头脑中炫耀,因为我认为我提出了我的MVC应用程序的控制器——服务——基于随机的问题和答案的存储库分层方案。

    但是,我可以给您举一个例子,说明如何组织您列出的项目符号,使其与我构建服务层的方式相匹配。这可能不是最好的方法,但这是我如何做我的大规模MVC应用程序。这应该让您了解如何在自己的应用程序中构造它。

    我的服务层为每个业务单元组合一个服务类。因此,如果我的应用程序有项目,并且每个项目都有一个人,那么我将拥有一个ProjectService类和一个PersonService类。

    根据您对控制器工作方式的描述,我的控制器的操作按以下方式工作。

    1)获取当前用户的信息,调用相应的服务类的授权方法。因此,如果用户试图修改项目的详细信息,我将把用户ID和项目ID传递给ProjectService的authorizeuser方法。这意味着,如果我改变了我为项目授权用户的方式,我只需要更改授权方法,而不是每个控制器。

    2)视图模型在服务层中创建、保存和销毁。服务层获取ViewModel,对其进行验证(如果失败则引发异常或验证结果),然后将其转换为数据对象,然后将其传递给存储库进行保存。它还从存储库请求数据对象,将其转换为视图模型并将其返回给控制器。

    3)在服务层中记录所有操作。这可以根据正在显示的操作(尝试将对象保存到数据库)自动进行,或者控制器可以显式调用服务层来记录该操作。

    这一点的关键是将通用功能整合到一个易于维护的层中。如果您更改了ViewModel转换为DTO的方式,那么很容易知道在哪里进行更改并进行一次更改。如果您需要更改日志记录、用户访问权限,或者即使您想更改从存储库中检索某些数据的方式,也只需更改一个简单的区域,而不必搜索所有控制器并直接修改它们。

    编辑 :这使控制器保持较小,因为它们实际上只包含对服务层的一些调用,即(授权、执行操作、显示视图)。 结束编辑

    最后,ASP.NET网站有一个在服务层中执行验证的教程。可以找到那个教程 here .

        2
  •  3
  •   Ryan    14 年前

    你应该看看这个关于 Putting Your Controllers On A Diet .

        3
  •  1
  •   Nick Larsen    14 年前

    在我看来,你依赖你的控制器来扮演太多的角色。

    在设计控制器时,我通常认为它控制对单一类型资源的访问。这意味着,例如,如果我正在创建您正在阅读的这个页面,您可以在其中发布答案和评论,我将有两个控制器,一个用于答案,另一个用于评论。我将避免为无关的资源访问向问题控制器添加两个操作。这是有例外的,但他们是很少的。

    此外,每个控制器的基本功能是,它应该验证输入(即使在浏览器中验证输入,因为任何人都可以编辑请求),将输入转换为传递到服务层(或业务逻辑)所需的对象,并在将输入转换回可用的对象之前验证服务层的响应。Y视图并返回给用户。其他一切都应该在服务层中处理,保持控制器的精简和可预测性。

        4
  •  0
  •   Tejo    14 年前

    我公司共有5个项目:

    • 视图
    • 控制器,在wich中,我们只放了动作方法的逻辑,它是帮助者。
    • 在业务逻辑中,我们为操作放置特定的逻辑,在您的情况下,这将是电子邮件、业务验证的帮助者,以及我们调用存储库来更新和创建对象的地方。
    • 数据访问,我们把查询和数据操作的存储库放在这里。
    • ORM,我们将数据库模型和类放在这里,以便在每一层之间交换数据。

    在这种情况下,所有项目都有一个对ORM的引用,然后视图有一个对控制器的引用,控制器有一个对业务逻辑的引用,业务逻辑有一个对数据访问的引用。

        5
  •  0
  •   ThatSteveGuy    14 年前

    好吧,其中一些取决于你所说的“控制器是”。如果您使用数据注释进行验证,并使用操作过滤器进行日志记录,那么这是非常好的。那里的控制器没有任何逻辑。您使用的是视图模型和强类型视图吗?您的控制器使用的模型似乎已经是简化的DTO,而不是拥有完整的实体并创建一个要发送回的DTO。我很难想象控制器会发送电子邮件,或者检查它是否已发送。应该交给服务层。我也会仔细观察一个在“关联对象”上运行的控制器。它应该在处理该问题的存储库上调用一个方法。

    我还没有打开过书呆子的晚餐,所以我不能发誓里面有什么,但它可能值得检查?