8000 Add support for updating specifications. · Issue #250 · ardalis/Specification · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Add support for updating specifications. #250
Closed
@fiseni

Description

@fiseni

In the current design, we have virtual protected signature for the specification builder (Query). Users, if necessary, can create their own base specification, override the builder, and so on (I doubt that anyone is overriding the builder). The intention with such a design was to keep the specifications immutable in some sense. Users write all their rules within the constructor. They should not further modify the specification once it is created, since that would leak custom querying logic throughout the code. And that's exactly what we're trying to prevent with this library.

But, that's just our opinion, and confining the users how they want to use the library is not a very open-minded approach :) We had a lot of requests to allow further modifications of the specs. I gave a thought to this, and instead of exposing the specification state for mutation, let's just expose the specification builder publicly. Thus, we'll still keep the state encapsulated in some form and we'll have the opportunity to validate the inputs if necessary. So, users would be able to do this:

var spec = new CustomerSpec();

// Add additional logic to existing spec
spec.Query.Where(x => x.Name == "Something");

A lot of folks have asked for composite specifications (that's the main reason for this proposal). Once we do this change, users will have the opportunity to write extensions and create their custom composition rules.

namespace Ardalis.Specification
{
  public static class MySpecExtensions
  {
    public static ISpecification<T> Combine<T>(this ISpecification<T> spec, ISpecification<T> otherSpec)
    {
      // Add Where expressions to the original spec
      foreach (var whereExpressionInfo in otherSpec.WhereExpressions)
      {
        spec.Query.Where(whereExpressionInfo.Filter);
      }

      // Similarly, add other expressions/states, whatever your rule is for combining.

      return spec;
    }
  }
}

The usage would be:

var spec1 = new CustomerSpec();
var spec2 = new CustomerSpec();

// The spec2 state is added to spec1
spec1.Combine(spec2);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0