Coder Absolute Coder Absolute - 1 month ago 6
C# Question

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

I have few Model Classes and I noticed the

Name
property (eg: CountryName, BranchName, StateName, etc) has the same rule across the application, like it must be mandatory and cannot exceed certain number of characters. In the following example of
BranchAddClass.cs
.




Question:





  1. How to define the custom object and re-use in the
    Model Class
    code instead of declaring as string (see the
    BranchName
    property in
    BranchAddModel.cs
    ).

  2. How to implement the
    FluentValidation
    rules within NameField.cs. At the moment, the validation is being repeated (see
    BranchAddModel.cs
    class).



NameField.cs

I was thinking to create an object class and perform the validation in this class, so that I don't break the
DRY
principle. But am unable to achieve it. If you have a better way to implement what am trying to achieve would be welcomed!

public class NameField
{
private readonly string _value;

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


If the NameField class works then am hoping that I could use that in the rest of the application, see the example

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();
}
}
}


Note: If you think the question is unclear, please let me know.

Answer

I would try to use generics. This way you can easily add it to other models and properties (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);
    }
}

NOTE: It compiles, but I didn't test if the validation actually works. Fluent Validation package is new for me and I don't have time now to investigate it, but looks worth to remember.

Comments