I asked a question about duplicate validation in domain or application layer.

Now, I decided to put all the business rules in the domain layer.

I have a value object like this, it has a method for validate business rules.

public class OrderId : ValueObject<OrderId>
    public string Value { get; }
    public DateTime CreateAt { get; }

    public OrderId(string value, DateTime createAt)
        if (!CanCreate(value, createAt, out var errorMessages))
            throw new ArgumentException(nameof(value), string.Join(",", errorMessages));

        Value = value;
        CreateAt = createAt;

    public static bool CanCreate(string value, DateTime createAt, out List<string> errorMessages)
        errorMessages = new List<string>();

        if (string.IsNullOrWhiteSpace(value))
            errorMessages.Add("value can not be null or empty.");

        if (value?.Length > 50)
            errorMessages.Add("value should not be longer than 50 characters.");

        if (createAt > DateTime.UtcNow)
            errorMessages.Add("createAt can not be greater than now.");

        return errorMessages.Count == 0;

The command send by the client.

public class CreateInvoiceCommand : IRequest
    public OrderIdDto OrderId { get; set; }

public class OrderIdDto
    public string Value { get; set; }

    public DateTime CreateAt { get; set; }

And use FluentValidation to validate the command.

public class CreateInvoiceCommandValidator : AbstractValidator<CreateInvoiceCommand>
    public CreateInvoiceCommandValidator()
        RuleFor(c => c.OrderId).Custom((orderId, context) =>
            if (!OrderId.CanCreate(orderId.Value, orderId.CreateAt, out var errorMessages))
                foreach (var errorMessage in errorMessages)

This looks fine, but it has a problem, parameter name does not match.

The error message is:

createAt can not be greater than now.

The client expects is:

CreateAt can not be greater than now.

The parameter name is determined by the application layer, and may be CreateAt or CreateTime or other.

My question is, do I have to modify the value object to accept the parameter name to generate the correct error message?

Is it reasonable for the domain layer to be modified due to the application layer?

  • Your current/expected outcomes are the same (capitalization aside).
    – Flater
    Commented Aug 27, 2019 at 12:28
  • You're right, but I believe the name should be the same as the command, including capitalization. And the value object will not know the name of the command.
    – Libron
    Commented Aug 27, 2019 at 14:31


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.