C# 4.0 如何实现规范模式?
在我的项目中;我已经包括了下面给出的特定模式类。我不知道如何实现这一点。这些代码由以前的开发人员提供C# 4.0 如何实现规范模式?,c#-4.0,specification-pattern,C# 4.0,Specification Pattern,在我的项目中;我已经包括了下面给出的特定模式类。我不知道如何实现这一点。这些代码由以前的开发人员提供 public interface ISpecification<T> { Expression<Func<T, bool>> SpecExpression { get; } bool IsSatisfiedBy(T obj); } public static class IExtensions { public static ISpe
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;
}
}
}
公共接口规范
{
表达式SpecExpression{get;}
布尔是满意的(T obj);
}
公共静态类IExtensions
{
公共静态规范和(
这是我留下的,
(指定权)
{
返回新的和(左、右);
}
公共静态规范或(
这是我留下的,
(指定权)
{
返回新的或(左、右);
}
公共静态IsSpecification否定(此IsSpecification内部)
{
返回新的否定(内部);
}
}
公共抽象类规范库:ISpecification
{
私有函数编译表达式;
私有Func编译表达式
{
获取{return\u compiledExpression???(\u compiledExpression=SpecExpression.Compile());}
}
公共抽象表达式SpecExpression{get;}
公共事业部满足(T obj)
{
返回编译表达式(obj);
}
}
公共类和:规范库
{
左边是种;
具体化权;
公共和(
左边是规格,
(指定权)
{
this.left=左;
这个。右=右;
}
//和规格
公共重写表达式SpecExpression
{
得到
{
var objParam=表达式参数(typeof(T),“obj”);
var newExpr=Expression.Lambda(
安达尔索(
Expression.Invoke(left.SpecExpression,objParam),
Expression.Invoke(right.SpecExpression,objParam)
),
奥巴杰帕兰
);
返回newExpr;
}
}
}
公共类或:规范库
{
左边是种;
具体化权;
公共或(
左边是规格,
(指定权)
{
this.left=左;
这个。右=右;
}
//或规格
公共重写表达式SpecExpression
{
得到
{
var objParam=表达式参数(typeof(T),“obj”);
var newExpr=Expression.Lambda(
奥莱尔斯酒店(
Expression.Invoke(left.SpecExpression,objParam),
Expression.Invoke(right.SpecExpression,objParam)
),
奥巴杰帕兰
);
返回newExpr;
}
}
}
已否定公共类:SpecificationBase
{
私有只读指定\u内部;
公共否定(内部指定)
{
_内部=内部;
}
//否定规范
公共重写表达式SpecExpression
{
得到
{
var objParam=表达式参数(typeof(T),“obj”);
var newExpr=Expression.Lambda(
表情,不是(
Expression.Invoke(this.\u inner.SpecExpression,objParam)
),
奥巴杰帕兰
);
返回newExpr;
}
}
}
如何用一个简单的例子来实现上述规范?此规范的用途是什么?正如我在评论中所写,这是借助
表达式实现的规范模式
假设我们有以下域模型:
public class Person
{
public string Name { get; set; }
public DateTime BirthDate { get; set; }
public string Country { get; set; }
}
此外,我们还有一份清单:
List<Person> persons; // <-- initialized elsewhere
现在我们可以用它来查找2000年之前出生的所有人:
ISpecification spec = new SpainSpec();
persons.Where (spec.IsSatisfiedBy);
ISpecification spec = new SpainSpec().And(new BornBefore2000());
persons.Where (spec.IsSatisfiedBy);
当然,你可以把它们串起来,让那些2000年以前出生的西班牙人:
ISpecification spec = new SpainSpec();
persons.Where (spec.IsSatisfiedBy);
ISpecification spec = new SpainSpec().And(new BornBefore2000());
persons.Where (spec.IsSatisfiedBy);
这是一个非常简单的场景,根据您的模型和需要,您可以拥有更多
使用规范时要小心,以免失去对规范的控制,导致类过多,或发现自己正在重新发明轮子。这是借助Expression
实现的规范模式。它的使用案例取决于您的域模型。@Ofir Winegarten您能举一个以上类的小例子吗?如何使用它?虽然规范模式对于将领域知识保持在领域层中非常有用,但您应该始终考虑规则是否应该是实体本身的一部分。例如,如果您可以在客户
实体本身中有一个方法,为什么要有一个客户可用于促销规范
:bool isligibleforpromotion
。当检查需要实体/聚合中不存在的数据时,有一个专门的规范类是有意义的。否则,它可能只是一种方法。