在 MVC 架构中将业务逻辑保留在哪里?

Posted

技术标签:

【中文标题】在 MVC 架构中将业务逻辑保留在哪里?【英文标题】:Where to keep business logics in MVC architecture? 【发布时间】:2013-10-19 18:28:01 【问题描述】:

在我的公司,我们最近开始开发 MVC 应用程序。我们的任务是编写业务逻辑层,并且将来它应该减少维护。

我们有几个网络服务来添加/更新/删除用户信息。

现在我们必须添加如下业务逻辑:

如果页面上的 Field1 是 'xxxx' 那么 field2 应该在 1000 到 2000 的范围内 如果 field3 是某个部门,那么 field4 应该只在某些子部门中。

所以我们必须设计层,以便将来我们的管理员(没有编程知识)可以进入并更改逻辑以使其正常工作。请给我一些建议。

到目前为止,我得到的是:在模型中编写所有这些条件并在用户单击保存按钮时验证它们。

提前致谢。

【问题讨论】:

最好的方法是 this 示例的一些变体。但是有更简单的方法来进行基本验证,例如 DataAnnotations。 如果您希望非开发人员能够配置业务逻辑,那么我可能会考虑 rules engine 【参考方案1】:

业务逻辑应保留在模型中。你的目标应该是拥有一个大模型和一个小控制器。

阅读this,您可能会觉得这很有趣。

同时检查 Where does the “business logic layer” fit in to an MVC application?

【讨论】:

你的意思是我必须通过 if else 条件硬编码所有这些条件并将它们保留在模型中 您可以在模型内部创建一个完整的类层次结构,以清晰地表达您的业务逻辑。 如何使我公司中的非开发人员可以编辑此内容?我没有技术知识的管理员也应该能够在我们将其部署到生产并离开公司后进行编辑。 所以您希望任何人都可以更改您的业务层?好像不是很有趣! ;) 不是层,而是逻辑?我告诉我的经理这是不可能的。但他坚持要这样做。【参考方案2】:

将其保存在不了解您的 ui 层的单独程序集中。您的模型可以在这里执行业务规则。我个人喜欢在 Csla 框架之上构建业务层,它可以让您构建具有强大规则的丰富模型。它面向 ntier 开发,但我相信它也与 ddd 兼容。

【讨论】:

【参考方案3】:

您可以使用DataAnnotations 来执行此操作 - 事实上,数据注释不仅可以在服务器端强制执行模型有效性。他们还可以为实体框架和客户端脚本提供提示,以便进行数据库/客户端验证,并将元数据添加到 MVC 可以检查的方法和属性中

例如对于模型:

class PersonDetailsModel

    [Required("Please enter a name")] // Don't allow no value, show the message when the rule is broken (if client side validation is enabled it shows when you tab off the control)
    [DisplayName("Full Name")] // Hint for MVC - show this when using the helper methods e.g. in MVC4 Razor syntax @html.LabelFor(model => model.Name)
    public string Name  get; set; 

是的,在业务层(模型)中保留尽可能多的业务逻辑。除了横切关注点之外,您的组件应该尽可能松散耦合。这样就可以在一个中心位置进行更改,您的代码更具可测试性和可维护性,还可以帮助您保持编程的一致性(这有助于项目新手快速上手)

如果你有更复杂的规则,你可以编写 EF 验证器。

http://msdn.microsoft.com/en-gb/data/gg193959.aspx

如果您不使用实体框架,那么您可能需要考虑它 - 如果您使用的是另一个 ORM,那么显然使用支持它的工具。如果您不使用 ORM,那么还有其他选择,但您必须编写一些管道代码

【讨论】:

对 ef 和业务模型使用同一个类并不是一个好主意。 没说,只是举个验证的例子:P【参考方案4】:

业务逻辑应该在Model层,我不认为没有编程知识的人可以改变业务逻辑,他至少要有基本的编程知识

【讨论】:

【参考方案5】:

我喜欢使用 Entity Framework 和 Fluent Validation 来创建一个包含模型和验证器的领域层。设置如下所示:

public abstract class DomainEntity

    private IValidator validator;

    protected DomainEntity(IValidator validator)
    
        this.validator = validator;
    

    public bool IsValid
    
        get  return validator.IsValid; 
    

    public ValidationResult Validate()
    
        return validator.Validate();
    


public class Person : DomainEntity

    public int Id  get; set; 
    public string Name  get; set; 

    public Person() : base(new PersonValidator())


public class PersonValidator() : AbstractValidator<Person>

    public PersonValidator()
    
         ... validation logic
    

使用此设置,我的模型和验证器位于同一层,但我不会用业务逻辑混淆我的模型类。

【讨论】:

【参考方案6】:

当您谈论layering 时,您的业务层 应该与表示层 分开。 ASP.NET MVC 是一种表示技术;因此,您的业务层将在不同的程序集中。此外,您的业务模型不会直接在您的视图中使用;您可以使用 ViewModel 验证用户输入,当一切正常时,将 ViewModel 数据传输到业务实体。

如果您有兴趣获得有关企业级应用程序分层的更多信息,我推荐您Microsoft Spain - Domain Oriented N-Layered .NET 4.0 Sample App。

【讨论】:

微软西班牙 - 面向领域的 N 层 .NET 4.0 示例应用程序 - microsoftnlayerapp.codeplex.com - 链接已失效 @mvark,作者在blogs.msdn.com/b/cesardelatorre/archive/2010/03/26/…提供了一些新信息

以上是关于在 MVC 架构中将业务逻辑保留在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

MVC:把业务逻辑放在哪里? [关闭]

使用具有 3 层架构的 MVC 模式

架构中MVC模型和业务逻辑层的区别

MVC5 网站开发之四 业务逻辑层的架构和基本功能

Java Web 开发时的 MVC 模型和软件的3层架构(表现层,业务逻辑层,数据访问层)都有哪些区别和联系?

c# 中的解决方案架构,其中 winforms 和 asp.mvc 共享业务逻辑和数据访问 [关闭]