Validation of a couple of model classes using FluentValidator A couple of model classes are doing the validation using FluentValidator. These model classes are used to Add and Edit the branch data and they are working well but I have no idea how to remove the code smell (duplication).

Problem: Notice the duplicate validations being written in BranchEditModel class as well. I have marked in the code itself what I think is being duplicated I thought it would be easier for you to read it.

BranchAddModel

using FluentValidation;
using FluentValidation.Attributes;

namespace Application //sample namespace
{
    [Validator(typeof(BranchAddModelValidator))]
    public class BranchAddModel
    {
        public string BranchName { get; set; }
        public byte ServiceTypeId { get; set; }
        public short TimezoneId { get; set; }
    }

    public class BranchAddModelValidator : AbstractValidator&lt;BranchAddModel&gt;
    {
        public BranchAddModelValidator()
        {
            RuleFor(x =&gt; x.BranchName)
                .NotEmpty()
                .Length(0, 128);  //up to 128 length of string is allowed.

            RuleFor(x =&gt; x.ServiceTypeId)
                .NotEmpty();  //mandatory

            RuleFor(x =&gt; x.TimezoneId)
                .NotEmpty();  //mandatory
        }
    }
}


BranchEditModel

BranchEditModel is inheriting the model from BranchAddModel. And, it has 2 extra properties.

namespace Application //sample namespace
{
    [Validator(typeof(BranchEditModelValidator))]
    public sealed class BranchEditModel : BranchAddModel
    {
        public int BranchId { get; set; }
        public bool IsActive { get; set; }
    }

    public class BranchEditModelValidator: AbstractValidator&lt;BranchEditModel&gt;
    {
        public BranchEditModelValidator()
        {
            RuleFor(x =&gt; x.BranchName) // code repeated
                .NotEmpty()
                .Length(0, 128);

            RuleFor(x =&gt; x.ServiceTypeId) // code repeated
                .NotEmpty();  

            RuleFor(x =&gt; x.TimezoneId) // code repeated
                .NotEmpty();

            RuleFor(x =&gt; x.BranchId) 
                .NotEmpty();

            RuleFor(x =&gt; x.IsActive)
                .NotEmpty();
        }
    }
}
I see two possibilities here.

1. Use extension methods

You can define a static class BranchModelValidationRules with extension methods for AbstractValidator&lt;T&gt; with methods like this:

public static void ValidateBranchName&lt;T&gt;(this AbstractValidator&lt;T&gt; validator)
    where T : BranchAddModel
{
    validator.RuleFor(x =&gt; x.BranchName)
        .NotEmpty()
        .Length(0, 128);
}


2. Extract a common base class

Create a class BranchModelValidatorBase:

public abstract class BranchModelValidatorBase&lt;T&gt; : AbstractValidator&lt;T&gt; 
    where T : BranchAddModel
{
    public BranchModelValidatorBase()
    {
        RuleFor(x =&gt; x.BranchName)
            .NotEmpty()
            .Length(0, 128);  //up to 128 length of string is allowed.

        RuleFor(x =&gt; x.ServiceTypeId)
            .NotEmpty();  //mandatory

        RuleFor(x =&gt; x.TimezoneId)
            .NotEmpty();  //mandatory
    }
}


Create concrete validators by extending the base class:

public class BranchAddModelValidator
    : BranchModelValidatorBase&lt;BranchAddModel&gt; 
{
    public BranchAddModelValidator()
    {
        // Create future add-specific rules here.
    }
}

public class BranchEditModelValidator
    : BranchModelValidatorBase&lt;BranchEditModel&gt; 
{
    public BranchEditModelValidator()
    {
        RuleFor(x =&gt; x.BranchId) 
            .NotEmpty();

        RuleFor(x =&gt; x.IsActive)
            .NotEmpty();
    }
}


Update

Regarding your comment about a more generic Name property: define an interface, for example like this:

public interface IModelWithName
{
    string Name { get; set; }
}


A matching extension method class might then look like this:

public static class ModelValidationRules
{
    public static void ValidateModelName&lt;T&gt;(this AbstractValidator&lt;T&gt; validator)
        where T : IModelWithName
    {
        validator.RuleFor(x =&gt; x.Name)
            .NotEmpty()
            .Length(0, 128);
    }
}


You can then reuse this method in any validator class that validates models implementing the interface. Alternatively you could create a validator for IModelWithName with just a single rule. Then use a matching set of validators for actual model validation.