Roman Roman - 3 months ago 20
C# Question

C# Specification pattern agregate checker

I have created class that intend to check is Generic T meets all the required specifications. Need help to agregate them and return boolean value.

Here is the base specification class

/// <summary>
/// Base spec
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class BaseSpecification<T>
{
public abstract Expression<Func<T, bool>> ToExpression();

/// <summary>
/// Meets
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public bool Meets(T entity)
{
Func<T, bool> predicate = ToExpression().Compile();
return predicate(entity);
}
}


And concrete specification that inhereits from base:

public class DeviceIsActiveSpecification : BaseSpecification<Device>
{
public override Expression<Func<Device, bool>> ToExpression()
{
//Устройство поддерживает выполнение команд (Активное)
return device => device.DeviceActivityType == DeviceActivityType.Active;
}
}


And the validator class that has to check is T meets all the cpecifications:

public class SpecificationValidator<T>
{
/// <summary>
/// Cpec list
/// </summary>
private readonly IList<BaseSpecification<T>> _specifications2Meet;

public SpecificationValidator()
{
_specifications2Meet = new List<BaseSpecification<T>>();
}

/// <summary>
/// Add cpec
/// </summary>
/// <typeparam name="TSecification"></typeparam>
/// <returns></returns>
public SpecificationValidator<T> Add<TSecification>() where TSecification : BaseSpecification<T>, new()
{
return Add(new TSecification());
}

/// <summary>
///
/// </summary>
/// <param name="specification"></param>
/// <returns></returns>
SpecificationValidator<T> Add(BaseSpecification<T> specification)
{
if (specification == null) throw new ArgumentNullException(nameof(specification));
_specifications2Meet.Add(specification);
return this;
}

/// <summary>
/// Meets all
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public bool MeetsAllSpecifications (T source)
{
??? Need help here to agregate "Meets"
}
}


Intended usage:

var validator = new SpecificationValidator<Device>()
.Add<DeviceIsActiveSpecification>()
.Add<CommunicationDeviceSpecification>()
.MeetsAllSpecifications(device);


Any help is appreciated! Thanks!

Answer

Maybe I missed something, but it seems you can simply use LINQ's All here:

public bool MeetsAllSpecifications (T source)
{
    return specifications2Meet.All(spec => spec.Meets(source));
}
Comments