【问题标题】:Sharing domain validation logic in application layer by using FluentValidation使用 FluentValidation 在应用层共享域验证逻辑
【发布时间】:2018-07-03 02:38:50
【问题描述】:

在我们的域中,我们有 Student ,每个学生都有名字、姓氏和学号。学号的业务规则是,学号可以是1到99999之间的任意数字。由于这个验证属于领域层,我为此写了一个类,比如;

public class StudentNumber : ValueObject
    {
        public StudentNumber(int value)
        {
            if (value <= 0 || value > 99999)
            {
                throw new ArgumentOutOfRangeException(
                    nameof(value),
                    "Student number must be in range of (0,9999]");
            }

            Value = value;
        }


        public int Value { get; private set; }

        public static implicit operator StudentNumber(int value)
        {
            return new StudentNumber(value);
        }
    }

但是,最好在应用层验证输入。因此,我最终得到了一个可以在下面找到的验证类(通过使用 FluentValidation 库);

public class CreateStudentCommandValidator : AbstractValidator<CreateStudentCommand>
    {
        public CreateStudentCommandValidator()
        {
            RuleFor(m => m.StudentNumber)
                .ExclusiveBetween(0, 100000)
                .WithMessage(ErrorCodes.InvalidStudentNo);
        }
    }

在 CreateStudentCommand 中,StudentNumber 属性数据类型为整数。

这个验证器有效,但是它违反了 DRY 规则。因为我在域层和应用程序中重复验证逻辑。

问题是;在 FluentValidation 验证器类中使用域验证代码的最佳做法是什么?

【问题讨论】:

  • 关于模式和其他设计问题的讨论并不适合 stackoverflow,它们是主观的,无法量化(通常),并且本质上只是基于意见,甚至更糟糕的是,基于其他人的意见跨度>

标签: c# domain-driven-design fluentvalidation


【解决方案1】:

这两个数字实际上属于不同的模型——请求模型和域模型。在重新阅读问题和我的原始答案时,我想我在这里看到了不匹配。

前端验证应仅限于基本数据类型。如果您需要一个整数,请确保调用者发送了一个整数,日期是日期,字符串是字符串。这是控制器(或直接从用户接收请求)的责任。如果用户发送了一个无效的整数,它在这个级别被拒绝。这里没有进行范围检查,我们只检查以确保请求格式正确。

然后控制器创建一个命令。命令的作用是将用户的愿望传达给领域逻辑,领域逻辑执行业务逻辑来执行该愿望。我们假设用户确实想用给定的数字创建一个学生,因此命令应该将这种愿望传达给域,即命令中不应该有范围的验证。命令验证通常只使用适当类型的构造函数参数完成。

域逻辑尝试执行用户的愿望并创建一个无效号码的新学生。域决定这不是一个有效的数字,并在这个级别抛出异常,使命令执行失败。控制器感知失败的命令执行并向调用者返回适当的失败(或者,如果命令执行是异步的,则以适当的方式处理错误)。

您最初的直觉是正确的,您违反了 DRY。这可以通过更改业务规则以允许更广泛的范围来显示。这个单一的业务规则更改将需要两次代码更改,从而证明您是在重复自己。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 2020-07-28
    • 1970-01-01
    • 2015-04-20
    • 2020-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多