为了呼应 Dima - 您可以考虑再次将您的 DTO 映射到ViewModel
专门为视图定制的自定义类(否则,您可能会发现自己不得不使用ViewBag
etc 将其他数据填充到视图中)。
还要确认 MVC 的“M”实际上是系统的整个后端(DAL、BLL、服务层、DTO、实体等)。我们通常删除 asp.net MVC 项目中的 Model 文件夹,因为其他层位于单独的程序集中并被引用/注入。我假设您的 MVC 前端是您系统的“主要”用户界面(即同一团队正在开发 MVC 前端和后端)。
一个有争议的问题是服务层 - 至少有以下 2 个选项。
- 您可以认为服务层仅适用于“外部”系统消费者,并允许您的控制器直接与您的 BLL 交互,甚至(CQRS 样式)直接与 DAL/存储库进行查询(即服务层 = 暴露的集成接口外观) . (但是您自己的前端 Ajax 调用等应该调用 MVC 控制器方法,而不是服务层 IMO)
- 采取更传统的严格分层的方式,把服务层当作你的业务层的网关(即你的MVC前端根本不是服务的特殊消费者,必须经过服务层)。
使用选项 1,您可能需要在 Controller 中复制服务问题(安全性、事务边界、日志记录等)。通常控制器无论如何都需要这些问题。
使用选项 2,例如,如果您使用 WCF,您应该尽可能避免额外的网络(和序列化/反序列化)开销。因此,如果您发现可以将 MVC 前端和服务层在进程中部署到同一物理服务器,例如,您可以配置 IoC(或类工厂)以将 WCF 服务合同的实例直接注入您的控制器(即,您仍然通过定义的 WCF 合同通过服务层,但没有开销)。
同样使用选项 2,如果您确实有其他系统在使用您的服务(除了您自己的前端),建议您将界面形式化,例如通过为外部消费者提供额外的外观/映射。否则,每次您为自己的前端向 WCF 服务添加新属性或方法时,您都会违反外部消费者的合同。WCFMessageContract
对于外部系统接口很有用,因为您可以更好地控制消息格式。