Сообщение Re: EntityFramework: (анти)паттерн Repository от 18.08.2017 9:26
Изменено 18.08.2017 11:58 igor-booch
Re: EntityFramework: (анти)паттерн Repository
Применение спецификаций не исключает использование Repository, можно и то и другое использовать. Только в этом случае спецификации должны быть инкапсулированы в Repository.
Вместо магии с перегрузкой операторов достаточно несколько экстеншен методов, тащить всякие дполнительные библеотеки смысла не вижу.
Написал только что, не тестировал:
Вместо магии с перегрузкой операторов достаточно несколько экстеншен методов, тащить всякие дполнительные библеотеки смысла не вижу.
Написал только что, не тестировал:
using System;
using System.Linq.Expressions;
namespace IBCode.Core.Common.ExtentionMethods
{
public static partial class ExtensionMethods
{
class ReplaceParameterWithParameterVisitor : ExpressionVisitor
{
readonly ParameterExpression _replacement;
public ReplaceParameterWithParameterVisitor(ParameterExpression replacement)
{
_replacement = replacement;
}
public ParameterExpression Parameter { get; set; }
protected override Expression VisitParameter(ParameterExpression node)
{
return base.VisitParameter(node == Parameter ? _replacement : node);
}
}
public static Expression<Func<TParameter, bool>> And<TParameter>(
this Expression<Func<TParameter, bool>> left,
Expression<Func<TParameter, bool>> right)
{
ParameterExpression parameterExpression = Expression.Parameter(typeof (TParameter), "parameter");
ReplaceParameterWithParameterVisitor replaceParameterWithParameterVisitor = new ReplaceParameterWithParameterVisitor(parameterExpression);
replaceParameterWithParameterVisitor.Parameter = left.Parameters[0];
left = (Expression<Func<TParameter, bool>>) replaceParameterWithParameterVisitor.Visit(left);
replaceParameterWithParameterVisitor.Parameter = right.Parameters[0];
right = (Expression<Func<TParameter, bool>>) replaceParameterWithParameterVisitor.Visit(right);
return Expression.Lambda<Func<TParameter, bool>>(Expression.And(left.Body, right.Body), parameterExpression);
}
public static Expression<Func<TParameter, bool>> Or<TParameter>(
this Expression<Func<TParameter, bool>> left,
Expression<Func<TParameter, bool>> right)
{
ParameterExpression parameterExpression = Expression.Parameter(typeof (TParameter), "parameter");
ReplaceParameterWithParameterVisitor replaceParameterWithParameterVisitor = new ReplaceParameterWithParameterVisitor(parameterExpression);
replaceParameterWithParameterVisitor.Parameter = left.Parameters[0];
left = (Expression<Func<TParameter, bool>>) replaceParameterWithParameterVisitor.Visit(left);
replaceParameterWithParameterVisitor.Parameter = right.Parameters[0];
right = (Expression<Func<TParameter, bool>>) replaceParameterWithParameterVisitor.Visit(right);
return Expression.Lambda<Func<TParameter, bool>>(Expression.Or(left.Body, right.Body), parameterExpression);
}
public static Expression<Func<TParameter, bool>> And<TParameter>(
this Expression<Func<TParameter, bool>> left,
Expression<Func<bool>> right)
{
ParameterExpression parameterExpression = Expression.Parameter(typeof (TParameter), "parameter");
ReplaceParameterWithParameterVisitor replaceParameterWithParameterVisitor = new ReplaceParameterWithParameterVisitor(parameterExpression);
replaceParameterWithParameterVisitor.Parameter = left.Parameters[0];
left = (Expression<Func<TParameter, bool>>) replaceParameterWithParameterVisitor.Visit(left);
return Expression.Lambda<Func<TParameter, bool>>(Expression.And(left.Body, right.Body), parameterExpression);
}
public static Expression<Func<TParameter, bool>> Or<TParameter>(
this Expression<Func<TParameter, bool>> left,
Expression<Func<bool>> right)
{
ParameterExpression parameterExpression = Expression.Parameter(typeof (TParameter), "parameter");
ReplaceParameterWithParameterVisitor replaceParameterWithParameterVisitor = new ReplaceParameterWithParameterVisitor(parameterExpression);
replaceParameterWithParameterVisitor.Parameter = left.Parameters[0];
left = (Expression<Func<TParameter, bool>>) replaceParameterWithParameterVisitor.Visit(left);
return Expression.Lambda<Func<TParameter, bool>>(Expression.Or(left.Body, right.Body), parameterExpression);
}
public static Expression<Func<TParameter, bool>> And<TParameter>(
this Expression<Func<bool>> left,
Expression<Func<TParameter, bool>> right)
{
ParameterExpression parameterExpression = Expression.Parameter(typeof (TParameter), "parameter");
ReplaceParameterWithParameterVisitor replaceParameterWithParameterVisitor = new ReplaceParameterWithParameterVisitor(parameterExpression);
replaceParameterWithParameterVisitor.Parameter = right.Parameters[0];
right = (Expression<Func<TParameter, bool>>) replaceParameterWithParameterVisitor.Visit(right);
return Expression.Lambda<Func<TParameter, bool>>(Expression.And(left.Body, right.Body), parameterExpression);
}
public static Expression<Func<TParameter, bool>> Or<TParameter>(
this Expression<Func<bool>> left,
Expression<Func<TParameter, bool>> right)
{
ParameterExpression parameterExpression = Expression.Parameter(typeof (TParameter), "parameter");
ReplaceParameterWithParameterVisitor replaceParameterWithParameterVisitor = new ReplaceParameterWithParameterVisitor(parameterExpression);
replaceParameterWithParameterVisitor.Parameter = right.Parameters[0];
right = (Expression<Func<TParameter, bool>>) replaceParameterWithParameterVisitor.Visit(right);
return Expression.Lambda<Func<TParameter, bool>>(Expression.Or(left.Body, right.Body), parameterExpression);
}
public static Expression<Func<TParameter, bool>> Not<TParameter>(
this Expression<Func<TParameter, bool>> expression)
{
return Expression.Lambda<Func<TParameter, bool>>(Expression.Not(expression.Body), expression.Parameters);
}
public static Expression<Func<TParameter, bool>> Not<TParameter>(
this Expression<Func<bool>> expression)
{
return Expression.Lambda<Func<TParameter, bool>>(Expression.Not(expression.Body), Expression.Parameter(typeof (TParameter), "parameter"));
}
}
}
Re: EntityFramework: (анти)паттерн Repository
Применение спецификаций не исключает использование Repository, можно и то и другое использовать. Только в этом случае спецификации должны быть инкапсулированы в Repository.