Информация об изменениях

Сообщение Re: EntityFramework: (анти)паттерн Repository от 18.08.2017 9:26

Изменено 18.08.2017 11:56 igor-booch

Re: EntityFramework: (анти)паттерн Repository
Применение спецификаций не исключает использование Repository, можно и то и другое использовать. Только в этом случае спецификации должны быть инкапсулированы в Repository.
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"));            
        }                   

    }
}