Pregunta

Estoy tratando de hacer una implementación simple del patrón de especificación en mi capa de dominio.

Si tengo una clase estática completa de las especificaciones de esta manera:

public static class FooSpecifications
{
  public static Func<Foo, bool> IsSuperhuman
  {
    get
    {
      return foo => foo.CanShootLasersOutOfItsEyes && foo.CanFly;
    }
  }
}

A continuación, puedo hacer cosas maravillosas como esta:

IEnumerable<Foo> foos = GetAllMyFoos();
var superFoos = foos.Where(FooSpecifications.IsSuperhuman);

I también se puede añadir bool método para Foo para determinar si un caso particular cumple una especificación:

public bool Meets(Func<Foo, bool> specification)
{
  return specification.Invoke(this);
}

Dado que Foo, como todo hijo de entidades del dominio, se extiende DomainObject, ¿hay alguna manera de poner una implementación genérica de Cumple () en el DomainObject para salvar mi aplicación cumple () por separado en cada entidad?

¿Fue útil?

Solución

Algo como esto ...

    public abstract class DomainObj<T> // T - derived type
        where T : DomainObj<T>
    {
        public bool Meets(Func<T, bool> specification)
        {
            return specification.Invoke((T) this);
        }
    }

    public class Foo : DomainObj<Foo> {}

    public class Bar : DomainObj<Bar> {}       

        Func<Foo, bool> foospec = x => true;
        Func<Bar, bool> barspec = x => true;

        var foo = new Foo();
        var bar = new Bar();
        foo.Meets(foospec);
        foo.Meets(barspec); // won't compile because of mismatched types of spec and object instance

Editar

Tal vez será mejor traducir método se reúnen para la extensión. Esto eliminará la necesidad en el parámetro tipo.

    public abstract class DomainObj
    {
    }

    public static class DomainObjExtensions
    {
        public static bool Meets<T>(this T obj, Func<T, bool> f)
            where T : DomainObj
        {
            return f(obj);
        }
    }

    public class Foo : DomainObj {}

    public class Bar : DomainObj {}

    Func<Foo, bool> foospec = x => true;
    Func<Bar, bool> barspec = x => true;

    var foo = new Foo();
    var bar = new Bar();
    foo.Meets(foospec);
    foo.Meets(barspec); // error
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top