Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/react-native/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 4.0 如何实现规范模式?_C# 4.0_Specification Pattern - Fatal编程技术网

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
。当检查需要实体/聚合中不存在的数据时,有一个专门的规范类是有意义的。否则,它可能只是一种方法。