public static CollectionEqualityRule <TProperty, TKey> Create <T>(Expression <Func <T, IEnumerable <TProperty> > > expression, Expression <Func <TProperty, TKey> > keyExpression, Func <CascadeMode> cascadeModeThunk) { var member = expression.GetMember(); var compiled = AccessorCache <T> .GetCachedAccessor(member, expression); return(new CollectionEqualityRule <TProperty, TKey>(keyExpression, member, compiled.CoerceToNonGeneric(), expression, cascadeModeThunk, typeof(TProperty), typeof(T))); }
private static Tuple <string, TProperty> GetPropertyTuple3 <T, TProperty>( T entity, Expression <Func <T, TProperty> > expression) { var member = expression.GetMember(); var propertyValue = AccessorCache <T> .GetCachedAccessor(member, expression)(entity); return(Tuple.Create(member.Name, propertyValue)); }
public void No_error_when_accessing_same_property_via_different_collection_type_when_using_different_cache_prefix() { Expression <Func <Person, IEnumerable <Order> > > expr1 = x => x.Orders; Expression <Func <Person, IList <Order> > > expr2 = x => x.Orders; var accessor1 = AccessorCache <Person> .GetCachedAccessor(typeof(Person).GetProperty("Orders"), expr1, false, "Prefix1"); var accessor2 = AccessorCache <Person> .GetCachedAccessor(typeof(Person).GetProperty("Orders"), expr2, false, "Prefix2"); Assert.NotEqual(accessor1, accessor2); }
public CollectionEqualityRule(Expression <Func <TProperty, TKey> > keyExpression, MemberInfo member, Func <object, object> propertyFunc, LambdaExpression expression, Func <CascadeMode> cascadeModeThunk, Type typeToValidate, Type containerType) : base(member, propertyFunc, expression, cascadeModeThunk, typeToValidate, containerType) { if (keyExpression == null) { throw new ArgumentNullException(nameof(keyExpression)); } var keyMember = keyExpression.GetMember(); _keyMemberName = keyMember.Name; _keyExpressionCompiled = AccessorCache <TProperty> .GetCachedAccessor(member, keyExpression); }
public void Gets_accessor() { Expression <Func <Person, int> > expr1 = x => 1; var compiled1 = expr1.Compile(); var compiled2 = expr1.Compile(); Assert.NotEqual(compiled1, compiled2); var compiled3 = AccessorCache <Person> .GetCachedAccessor(typeof(Person).GetProperty("Id"), expr1); var compiled4 = AccessorCache <Person> .GetCachedAccessor(typeof(Person).GetProperty("Id"), expr1); Assert.Equal(compiled3, compiled4); }
/// <summary> /// When using the ValidatableProperty type, use this method to avoid needing to supply the ".Value" /// which is needed when using RuleForProp. /// </summary> /// <typeparam name="TType"></typeparam> /// <param name="expression"></param> /// <returns></returns> public IRuleBuilderInitial <T, TType> RuleForProp <TType>(Expression <Func <T, ValidatableProperty <TType> > > expression, CascadeMode cascadeMode = CascadeMode.Continue) { var lambdaExpression = (MemberExpression)expression.Body; var propName = lambdaExpression.Member.Name; var originalPropertyType = typeof(T).GetRuntimeProperty(propName); var actualPropertyToValidate = typeof(ValidatableProperty <TType>).GetRuntimeProperty("Value"); var generatedExpression = Expression.Parameter(typeof(T), "a"); var navigationPropertyAccess = Expression.MakeMemberAccess(generatedExpression, originalPropertyType); var lambdaNameMemberAccess = Expression.MakeMemberAccess(navigationPropertyAccess, actualPropertyToValidate); var lambdaAccess = Expression.Lambda <Func <T, TType> >(lambdaNameMemberAccess, new List <ParameterExpression>() { generatedExpression }); var generatedMember = lambdaAccess.GetMember(); var compiled = generatedMember == null || ValidatorOptions.DisableAccessorCache ? lambdaAccess.Compile() : AccessorCache <T> .GetCachedAccessor(generatedMember, lambdaAccess); var rule = new PropertyRule(generatedMember, compiled.CoerceToNonGeneric(), lambdaAccess, () => cascadeMode, typeof(TType), typeof(T)); AddRule(rule); IRuleBuilderOptions <T, TType> ruleBuilder = new RuleBuilder <T, TType>(rule, this); ruleBuilder = ruleBuilder.WithName(propName); return((IRuleBuilderInitial <T, TType>)ruleBuilder); }
public IRuleBuilderInitial <T, TType> RuleForProp <TType>(Expression <Func <T, ValidatableProperty <TType> > > expression) { var propName = expression.Body.ToString().Split(new char[] { '.' })[1]; var param = Expression.Parameter(typeof(T), "a"); var navigationProperty = typeof(T).GetRuntimeProperty(propName); var name = typeof(ValidatableProperty <TType>).GetRuntimeProperty("Value"); var navigationPropertyAccess = Expression.MakeMemberAccess(param, navigationProperty); var nameAccess = Expression.MakeMemberAccess(navigationPropertyAccess, name); var lambdaAccess = Expression.Lambda <Func <T, TType> >(nameAccess, new List <ParameterExpression>() { param }); var member = lambdaAccess.GetMember(); var compiled = member == null || ValidatorOptions.DisableAccessorCache ? lambdaAccess.Compile() : AccessorCache <T> .GetCachedAccessor(member, lambdaAccess); var rule = new PropertyRule(member, compiled.CoerceToNonGeneric(), lambdaAccess, () => CascadeMode.Continue, typeof(TType), typeof(T)); AddRule(rule); IRuleBuilderOptions <T, TType> ruleBuilder = new RuleBuilder <T, TType>(rule); ruleBuilder = ruleBuilder.WithName(propName); return((IRuleBuilderInitial <T, TType>)ruleBuilder); }