【问题标题】:Where view models inside Web project of n-tier application should be placed?n 层应用程序的 Web 项目中的视图模型应该放在哪里?
【发布时间】:2015-06-08 11:52:09
【问题描述】:

假设我们有一个具有以下层的 ASP.NET MVC Web 应用程序:

  • 业务逻辑
  • 实体(业务领域和数据库 POCO)
  • 通用(资源、常量)
  • 数据访问(数据库 EF 查询、EDMX EF 模型等)
  • Web 应用程序(MVC Web 应用程序)

我们正在使用视图模型方法。当前视图模型放置在实体层中。数据访问查询返回视图模型(由于效率问题,所以我们避免使用映射器)。

Web 层引用所有其他层。 数据访问引用 Common 和 Entity 层。 业务逻辑引用实体层和公共层,未来还会引用数据访问层。

有一个想法将视图模型移动到 Web 层。为什么?因为它们实际上与特定技术 (MVC) 和 UI 实现绑定在一起。 但是我们这里遇到了一个问题,因为在这个场景中数据访问层必须引用Web,Web引用数据访问,所以我们有循环依赖的问题。

此外,当某些视图模型验证需要引用数据访问层时,我们会遇到这种情况。我们将在视图模型中保留验证方法。目前我们希望通过构造函数将数据库上下文类(在数据访问层中)注入到视图模型中来实现它。

您知道如何避免它吗?将视图模型保留在我们的 Web 层中是个好主意吗?

【问题讨论】:

  • 如何避免使用视图模型映射对象?为什么 Web 项目必须引用数据访问项目?还有为什么视图模型必须引用数据访问项目进行验证?
  • @gerdi 避免映射对象是通过返回视图模型来实现的。所以 EF 查询最后有“select new SomeVM { fields = sth }”行。 Web 引用数据访问,因为 DAL 公开了用于查询控制器中使用的数据库的方法。视图模型必须注入对数据访问项目的引用,因为某些验证方法必须检查数据库中的某些内容以验证视图模型(我们在视图模型中有 Validation 方法)。
  • 你没有说明你是否使用依赖注入,这听起来像是一个 IoC 容器。
  • 我们没有使用 DI,因为我们架构的某些其他方面使其难以实施。我说的是注入,但实际上我们正在创建访问基本控制器中的 db(假设是我们的工作单元对象)的对象。然后我们在视图模型构造函数中传递引用,以便它可以在其验证方法中使用它。无论如何 - IoC 不是答案,因为我们不能使用它。
  • 那将是避免跑来跑去的一种方法。但老实说,我认为视图模型在哪个项目中并不太重要。在默认的 asp mvc 项目中,它们位于“web”部分。因为 VM 纯粹是 UI 层的新实体。将它们放在 Web 项目中可能更符合关注点分离。

标签: .net asp.net-mvc architecture


【解决方案1】:

我不确定如何在网络应用程序中使用 ViewModel。 AFAIK 由于它的数据绑定性质,它比桌面应用程序更难。

但是,您的 Web 层直接引用了数据层(或者更确切地说,直接访问)。除非它用于帮助简化 UI 而不是业务流程,否则它也破坏了 N 层的目的。

要保持设计简洁,您需要做的是制作 2 个不同的模型。 One for Entities model (Domain/data/business model) and another for view model。您的视图模型放置在 web 层,当收到域模型时,它被映射到 web 层。你不能避免在这里映射。

【讨论】:

  • AFAIK 使用视图模型方法而不是模型的目的是避免使用 ViewBag 并简化视图。使用领域模型并不总是适合视图的需要。正如我在这里的另一条评论中所写,我们决定返回视图模型而不是域模型以避免映射开销。我知道从架构的角度来看它并不“干净”,但它太慢了。谢谢你的回答,这确保了我在我们的方法中不可能在 web 项目中拥有视图模型(我认为是这样,但我的团队不确定)。
  • @Landeeyo 不幸的是。如果您追求性能,则很难保持干净的架构,反之亦然。但是,通常映射并不像您想象的那么昂贵。
  • 对我们来说,使用 AutoMapper 完成相同的工作需要大约 10 倍的时间。虽然我不确定我们是不是做错了什么......
  • 您是否尝试过使用传统的代码映射? AFAIK AutoMapper 使用反射并且比传统的代码映射更慢。
  • @Landeeyo 我同意。这时候代码生成工具就派上用场了
猜你喜欢
  • 2011-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-22
  • 1970-01-01
  • 2021-05-10
  • 2013-08-03
  • 2023-04-09
相关资源
最近更新 更多