C# MVC 3-控制器和视图模型-哪些应该包含大多数业务逻辑?

C# MVC 3-控制器和视图模型-哪些应该包含大多数业务逻辑?,c#,asp.net-mvc-3,model-view-controller,viewmodel,controllers,C#,Asp.net Mvc 3,Model View Controller,Viewmodel,Controllers,目前,在我的应用程序中,使用工作单元模式和通用存储库,我的所有控制器都包含所有业务逻辑。我正在把所有的东西都放在ViewModels上,而不是直线模型 虽然这是一个好主意,但现在出现了一个问题,可以在控制器中显著分离我的业务逻辑。对于控制器和视图模型,哪些应该包含大部分业务逻辑 我尝试了几种方法,使ViewModels实际上包含所有业务逻辑。但是,我必须在ViewModel的构造函数中有一个参数,它接受一个工作单元。这是个好主意吗 我的代码气味告诉我它是。然而,我只是有点担心这将如何与执行不需要

目前,在我的应用程序中,使用工作单元模式和通用存储库,我的所有控制器都包含所有业务逻辑。我正在把所有的东西都放在ViewModels上,而不是直线模型

虽然这是一个好主意,但现在出现了一个问题,可以在控制器中显著分离我的业务逻辑。对于控制器和视图模型,哪些应该包含大部分业务逻辑

我尝试了几种方法,使ViewModels实际上包含所有业务逻辑。但是,我必须在ViewModel的构造函数中有一个参数,它接受一个工作单元。这是个好主意吗

我的代码气味告诉我它是。然而,我只是有点担心这将如何与执行不需要ViewModels的操作的控制器保持一致。简单地说,不需要将模型/视图模型传递给视图的操作;这种情况发生在重定向到其他操作的操作上。这意味着,我的业务逻辑可以保留在该操作中,也可以将该业务逻辑分离为一个函数


这里的最佳实践是什么?

我不能说我的方法是最佳实践,但我更喜欢将任何业务逻辑放在单独的“服务”层中

我倾向于使用ViewModel只存储特定视图所需的属性。如果ViewModel上有任何方法,它们很可能只是检索与该视图相关的集合

我尽量将控制器限制为验证和重定向/显示视图,从而使控制器保持轻量级

所以,如果我有任何复杂的逻辑,我将有一个控制器动作调用到一个单独的服务,只是为了处理这个逻辑。通过这种方式,逻辑被隔离,这使得测试更容易,因为不再需要创建控制器或ViewModel来测试它。重用服务也比分离ViewModel更容易

希望这能有所帮助。祝你好运。

模型-视图-模型(MVVM)是一种用于构建用户界面的设计模式。视图模型是UI上数据和操作的纯代码表示。因此,它应该包含与该UI相关的逻辑

例如:

如果您正在实现一个列表编辑器,您的视图模型将是一个对象,其中包含一个项目列表,并公开用于添加和删除项目的方法

来自维基百科:

ViewModel:ViewModel是“视图的模型”,意思是它是一个 视图的抽象,该视图也用于 视图和模型。它可以被看作是什么的一个特殊方面 将是一个控制器(在MVC模式中),充当数据源 将模型信息更改为视图信息的活页夹/转换器 并将命令从视图传递到模型中。视图模型 公开公共属性、命令和抽象。视图模型 已被比作数据的概念状态,而不是 模型中数据的真实状态。[7]

对于控制器和视图模型,哪些应该包含大部分业务逻辑

这些都不是

我尝试了几种方法,使ViewModels实际上包含所有业务逻辑。但是,我必须在ViewModel的构造函数中有一个参数,它接受一个工作单元。这是个好主意吗

我觉得这是个很糟糕的主意。首先,你打破了几个坚实的原则。将所有代码捆绑到视图模型中会使测试变得困难。如果您想在另一个视图中使用一些业务逻辑,该怎么办?你重复那个密码吗

这里的最佳实践是什么

让我们先回到MVC模式。这是一个相当广泛的定义,但知道它应该给你一种感觉,你应该把什么地方

  • MVC中的“模型”实际上是用于将数据汇集在一起的所有东西。它可以是Web服务、业务层、存储库等

  • 视图是生成HTML的所有代码(因为我们谈论的是web)

  • 控制器应被视为模型和视图之间的粘合剂。因此,它应该从模型中获取信息,并将其转换为视图可用的内容

这种结构的问题是很容易将特定于层的信息“泄漏”到模式的其他部分。因此,微软在MVC的实现中引入了ViewModels

通过这种方式,我们可以从视图中删除所有渲染逻辑,并将其放入ViewModel中。不要在您的视图中这样做:

<span>@(model.Age == 0 ? "n/a" : model.Age)</span>
@(model.Age==0?“不适用”:model.Age)
您将该代码放在ViewModel中,只需调用
@model.Age
。这样,您就不必在使用视图模型的所有视图中复制该代码

关于ViewModel的问题的答案是,它应该只包含用于正确呈现“模型”中信息的逻辑

至于控制器,我也不会在其中加入任何业务逻辑。首先,这使得测试你的逻辑非常困难。然后,您向它添加了更多的责任(这样做会破坏SRP)。控制器中唯一有效的逻辑是从ViewModel获取信息,并将其转换为“模型”可用的内容,反之亦然

希望这能回答你的问题

更新

我将创建一个单独的项目并向其中添加类。然后只需从webproject中添加一个引用,并在控制器中调用这些类

我还将开始使用控制反转容器来自动创建这些依赖项

既可以为您发现服务(零配置),又可以将自身注入MVC

要遵循分离的接口模式,请创建以下项目:

  • YourProject.BusinessLayer
    SomeClass something = Uow.BLGoodName.DoSomeFancyStuff(params ..)
    ViewData.model = new ControllerActionViewModel(something);
    Return View();