Skip to content

Instantly share code, notes, and snippets.

@einari
Last active January 12, 2017 09:06
Show Gist options
  • Save einari/af31c36a0274751841251d1ffe24214d to your computer and use it in GitHub Desktop.
Save einari/af31c36a0274751841251d1ffe24214d to your computer and use it in GitHub Desktop.
Validation Queries

An implementation of a validation query would need to implement a similar interface:

public interface IValidationQuery<oout TDelegate>
{
  T Query { get; }
}

Two projects: ValidationQueries.Contracts - which can be used by any projects - it has no dependencies to anything but potentially the Concepts project.

ValidationQueries - the implementation of the contracts. It could have a dependency to the Read side - the Read project

In your ValidationQueries.Contracts project

public namespace ValidationQueries.Contracts
{
  // Do not allow for same work being requested for same area
  public delegate bool TicketMustBeUniquePerAreaAndWork(Area area, WorkType workType);
}

The implementation of this would then be:

public class TicketMustBeUniquePerAreaAndWork : IValidationQuery<Contracts.TicketMustBeUniquePerAreaAndWork>
{  
  public Contracts.TicketMustBeUniquePerAreaAndWork Query
  {
    return (area, workType) => {
      // Lambda performing the query - or just return a method in the class that is the same signature as the delegate
    }
  }
}

Hooking this up by convention would mean using a type discovery system, like the one we have in Bifrost:

public class ValidationQueries
{
  public ValidationQueries(IInstancesOf<IValidationQuery<>> validationQueries, IContainer container)
  {
    foreach( var query in validationQueries ) 
    {
      container.Bind(query.GetType().GetTypeInfo().BaseType.GenericArguments[0], query.Query);
    }  
  }
}

You would then just need to get an instance of the ValidationQueries during startup to do it - in Bifrost terms; after configure is done or by creating a convention for it. The point is just to get the bindings right for the delegates.

In a validator - say, a CommandInputValidator, you would just then take a dependency to it:

public class RegisterTicketInputValidator : CommandBusinessValidator<RegisterTicket>
{
  public RegisterTicketInputValidator(TicketMustBeUniquePerAreaAndWork ticketMustBeUniquePerAreaAndWork)
  {
    ModelRule().Must(ticketMustBeUniquePerAreaAndWork);
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment