如何在 C# 中使用定义的对象而不是字符串?

How to Use defined Object instead of a string in C#?

我有几个型号 类,我注意到 Name 属性(例如:CountryName、BranchName、StateName、 等)有应用程序中的相同规则,例如它必须是强制性的并且不能超过一定数量的字符。在下面的例子中 BranchAddClass.cs.


问题:


  1. 如何定义自定义对象并在 Model Class 代码中重新使用而不是声明为字符串(请参阅 BranchAddModel.cs 中的 BranchName 属性)。
  2. 如何在 NameField.cs 中实施 FluentValidation 规则。目前,正在重复验证(参见 BranchAddModel.cs class)。

NameField.cs

我想创建一个对象class并在这个class中执行验证,这样我就不会破坏DRY原则。但是我无法实现它。如果您有更好的方法来实现我正在努力实现的目标,我们将不胜感激!

public class NameField
    {
        private readonly string _value;

        private NameField(string value)
        {
            _value = value;
        }
    }

如果 NameField class 有效,那么我希望我可以在应用程序的其余部分使用它,请参见示例

BranchAddModel.cs

namespace Application
{
    [Validator(typeof(BranchAddModelValidator))]
    public class BranchAddModel
    {
        public byte ServiceTypeId { get; set; }
        public string BranchName { get; set; }  //this could be replaced when NameField issue is solved.
        public NameField PreferredBranchName { get; set; }   //Reference to NameField class
        public short BaseCurrencyId { get; set; }
        public short TimezoneId { get; set; }
    }

    public class BranchAddModelValidator : AbstractValidator<BranchAddModel>
    {
        public BranchAddModelValidator()
        {
            //trying to avoid writing this validation.
            RuleFor(x => x.BranchName)
                .NotEmpty()
                .Length(0, 128);

            RuleFor(x => x.ServiceTypeId)
                .NotEmpty();

            RuleFor(x => x.BaseCurrencyId)
                .NotEmpty();

            RuleFor(x => x.TimezoneId)
                .NotEmpty();
        }
    }
}

注意:如果您觉得问题不清楚,请告诉我。

除了包装 class,您还可以这样做:

var param = Expression.Parameter(typeof(BranchAddModel));
var items = typeof(BranchAddModel).GetProperties()
    .Where(p => p.PropertyType == typeof(string))
    .Select(r => Expression.Lambda<Func<BranchAddModel, string>>(Expression.PropertyOrField(param, r.Name), param));

foreach (var item in items)
{
    RuleFor(item)
        .NotEmpty()
        .Length(0, 128);
}

这将构建一个 Expression<Func<BranchAddModel, string>> 的可枚举对象,然后您可以对其进行循环并传递给 RuleFor

我会尝试使用泛型。这样您就可以轻松地将其添加到其他模型和属性(CountryName、StateName)中。

public class BranchAddModelValidator : AbstractValidator<BranchAddModel>
{
    public BranchAddModelValidator()
    {
        this.AddDefaultNameValidation(x => x.BranchName);

        RuleFor(x => x.ServiceTypeId)
            .NotEmpty();

        RuleFor(x => x.BaseCurrencyId)
            .NotEmpty();

        RuleFor(x => x.TimezoneId)
            .NotEmpty();
    }
}

public static class AbstractValidatorExtensions
{
    public static void AddDefaultNameValidation<T>(this AbstractValidator<T> validator, Expression<Func<T, string>> property)
    {
        validator.RuleFor(property)
            .NotEmpty()
            .Length(0, 128);
    }
}

注意:它可以编译,但我没有测试验证是否真的有效。 Fluent Validation 包对我来说是新的,我现在没有时间研究它,但看起来值得记住。