In meinem Projekt; Ich habe spezifische Musterklassen eingeschlossen, die unten angegeben sind. Ich weiß nicht, wie ich das umsetzen soll. Diese Codes sind von früheren Entwicklern enthalten.Wie wird das Spezifikationsmuster implementiert?
public interface ISpecification<T>
{
Expression<Func<T, bool>> SpecExpression { get; }
bool IsSatisfiedBy(T obj);
}
public static class IExtensions
{
public static ISpecification<T> And<T>(
this ISpecification<T> left,
ISpecification<T> right)
{
return new And<T>(left, right);
}
public static ISpecification<T> Or<T>(
this ISpecification<T> left,
ISpecification<T> right)
{
return new Or<T>(left, right);
}
public static ISpecification<T> Negate<T>(this ISpecification<T> inner)
{
return new Negated<T>(inner);
}
}
public abstract class SpecificationBase<T> : ISpecification<T>
{
private Func<T, bool> _compiledExpression;
private Func<T, bool> CompiledExpression
{
get { return _compiledExpression ?? (_compiledExpression = SpecExpression.Compile()); }
}
public abstract Expression<Func<T, bool>> SpecExpression { get; }
public bool IsSatisfiedBy(T obj)
{
return CompiledExpression(obj);
}
}
public class And<T> : SpecificationBase<T>
{
ISpecification<T> left;
ISpecification<T> right;
public And(
ISpecification<T> left,
ISpecification<T> right)
{
this.left = left;
this.right = right;
}
// AndSpecification
public override Expression<Func<T, bool>> SpecExpression
{
get
{
var objParam = Expression.Parameter(typeof(T), "obj");
var newExpr = Expression.Lambda<Func<T, bool>>(
Expression.AndAlso(
Expression.Invoke(left.SpecExpression, objParam),
Expression.Invoke(right.SpecExpression, objParam)
),
objParam
);
return newExpr;
}
}
}
public class Or<T> : SpecificationBase<T>
{
ISpecification<T> left;
ISpecification<T> right;
public Or(
ISpecification<T> left,
ISpecification<T> right)
{
this.left = left;
this.right = right;
}
// OrSpecification
public override Expression<Func<T, bool>> SpecExpression
{
get
{
var objParam = Expression.Parameter(typeof(T), "obj");
var newExpr = Expression.Lambda<Func<T, bool>>(
Expression.OrElse(
Expression.Invoke(left.SpecExpression, objParam),
Expression.Invoke(right.SpecExpression, objParam)
),
objParam
);
return newExpr;
}
}
}
public class Negated<T> : SpecificationBase<T>
{
private readonly ISpecification<T> _inner;
public Negated(ISpecification<T> inner)
{
_inner = inner;
}
// NegatedSpecification
public override Expression<Func<T, bool>> SpecExpression
{
get
{
var objParam = Expression.Parameter(typeof(T), "obj");
var newExpr = Expression.Lambda<Func<T, bool>>(
Expression.Not(
Expression.Invoke(this._inner.SpecExpression, objParam)
),
objParam
);
return newExpr;
}
}
}
Wie die obige Spezifikation mit einem einfachen Beispiel implementieren? Was nützt diese Spezifikation?
Dies ist das Spezifikationsmuster, das mit Hilfe von "Expression" implementiert wurde. Der Anwendungsfall dafür hängt von Ihrem Domänenmodell ab. –
@Ofir Winegarten Kannst du ein kleines Beispiel mit obigen Klassen geben? Wie man es benutzt? – Pradees