Skip to content

specifications

vijay@envivo edited this page Oct 21, 2023 · 6 revisions

Specifications

Use Specifications to encapsulate business rules. This technique is slightly involved, but it really improves the clarity of your domain model.

To create a Specification class, implement the ISpecification<T> interface. Here is an example for validating names:

using Envivo.Fresnel.DomainTypes.Interfaces;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace Acme.OnlineShopping.Contacts
{
    /// <summary>
    /// Checks to perform before setting a Name value
    /// </summary>
    public class ValidNameSpecification: ISpecification<string> //👈
    {
        public Assertion IsSatisfiedBy(string newFirstName)
        {
            var allExceptions = new List<Exception>();

            if (string.IsNullOrEmpty(newFirstName))
            {
                var error = new ValidationException("Name must be provided");
                allExceptions.Add(error);
            }

            var regex = new Regex(@"^[a-z ,.'-]+$", RegexOptions.IgnoreCase);
            if (!string.IsNullOrEmpty(newFirstName) &&
                !regex.IsMatch(newFirstName))
            {
                var error = new ValidationException("Name contains invalid characters");
                allExceptions.Add(error);
            }

            return allExceptions.Any() ?
                Assertion.Fail(allExceptions) :
                Assertion.Pass;
        }
    }
}

Specifications can be used anywhere in your model, and can be injected using either constructor or property injection.

Clone this wiki locally