我的控制器越来越大,无法控制。
典型的控制器执行以下操作:
简而言之,他们对很多事情进行了修改。我想将所有内容都移到一个服务层,但我还没有真正看到我喜欢的代码示例中的任何实现模式。我看过一些像KiGG,Oxite,codecampserver等开源项目......但是它们都没有真正解决缩小我的控制器的问题。我想避免传递很多HTTPContext的东西,但也许这是不可能的。
还有其他一些项目,我可以关注的最佳实践吗?我正在构建一个大型工作流/数据输入应用程序。
感谢您提供一些链接和建议
答案 0 :(得分:3)
我不知道有什么真实的例子可以展示我的头脑,因为我想我想出了我的MVC应用程序的控制器 - >服务 - >我通过浏览SO找到了基于随机问题和答案的存储库分层方案。
但是,我能给你的是一个如何组织你列出的项目符号的例子,它是如何适应我构建服务层的方式。这可能不是最好的方法,但这就是我正在做我的大型mvc应用程序的方式。这应该让您了解如何在自己的应用程序中构建它
我的服务层为每个业务单元组合一个服务类。因此,如果我的应用程序有项目,并且每个项目都有一个人,那么我将拥有一个ProjectService类和一个PersonService类。
根据您对控制器工作方式的描述,我的控制器的操作以下列方式工作。
1)获取当前用户的信息并调用相应的服务类的授权方法。因此,如果用户试图修改项目的详细信息,我会将用户ID和项目ID传递给ProjectService的AuthorizeUser方法。这意味着如果我改变了为项目授权用户的方式,我只需要更改授权方法而不是每个控制器。
2)在服务层中创建,保存和销毁视图模型。服务层获取视图模型,验证它(如果失败则引发异常或验证结果),然后将其转换为数据对象,然后将其传递到存储库以进行保存。它还从存储库请求数据对象,将其转换为viewmodel并将其返回给控制器。
3)所有操作的记录都发生在服务层中。这可以基于所呈现的操作(尝试将对象保存到数据库)自动执行,或者您的控制器可以显式调用服务层来记录操作。
这一点的重点是将常用功能整合到易于维护的层中。如果您更改了视图模型转换为DTO的方式,那么很容易知道在何处进行更改并进行一次更改。如果您需要更改日志记录,用户访问权限,或者即使您想要更改从存储库中检索某些数据的方式,也只需更改一个简单的区域,而不必直接搜索所有控制器并直接修改它们。
编辑:这会使控制器变小,因为它们实际上只包含对服务层的一些调用,而这就是它(授权,执行操作,显示视图)。 结束编辑
最后,asp.net网站提供了一个在服务层执行验证的教程。可以找到该教程here。
答案 1 :(得分:3)
你应该查看关于Putting Your Controllers On A Diet的这个伟大的MVCConf会话。
答案 2 :(得分:1)
在我看来,你依靠你的控制器扮演太多角色。
在设计控制器时,我通常将其视为控制对单一类型资源的访问。这意味着,例如,如果我正在创建您正在阅读的页面,您可以在其中发布答案和评论,我将有2个控制器,一个用于答案,另一个用于评论。我会避免向我的问题控制器添加两个动作以获取不相关的资源访问权限。这有例外,但它们很少,而且很少。
此外,每个控制器的基本功能是它应该验证输入(即使它在浏览器中验证,因为任何人都可以编辑请求),将输入转换为传递到服务层所需的对象(或业务逻辑)并在将服务层转换回视图可用的对象之前验证服务层的响应并返回给用户。其他所有内容都应该在服务层中处理,保持控制器的精简和可预测性。
答案 3 :(得分:0)
在我公司,我们共有5个项目:
在这种情况下,所有项目都引用了ORM,然后,视图具有对控制器的引用,对业务逻辑的控制器以及对数据访问的业务逻辑。
答案 4 :(得分:0)
嗯,其中一些取决于你所说的“控制器是什么”。如果您使用数据注释进行验证和操作过滤器进行日志记录,那就完全没问题了。控制器中没有任何逻辑。您使用的是ViewModel和强类型视图吗?看起来你的控制器正在使用的模型应该是简化的DTO,而不是拥有完整的实体并创建一个DTO来发回。我无法想象控制器会发送电子邮件或检查它是否已发送的情况。应将其移交给服务层。我也会仔细研究一个在“关联对象”上运行的控制器。它可能应该在处理它的存储库上调用单个方法。
我没有打开书呆子晚餐,所以我不能发誓那里的东西,但是值得研究一下?