protected void ProcessAutoProperties() { var getFields = typeof(T).GetFields(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public); var setFields = typeof(TN).GetFields(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public); var getProps = typeof(T).GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public); var setProps = typeof(TN).GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public); var sourceMembers = getFields.Cast <MemberInfo>().Union(getProps); var destMembers = setFields.Cast <MemberInfo>().Union(setProps); foreach (var prop in sourceMembers) { if (IgnoreMemberList.Contains(prop.Name) || CustomPropertyCache.ContainsKey(prop.Name)) { continue; } var setprop = destMembers.FirstOrDefault(x => string.Equals(x.Name, prop.Name, StringComparison.OrdinalIgnoreCase)); var propertyInfo = setprop as PropertyInfo; if ((propertyInfo == null && setprop == null) || (propertyInfo != null && (!propertyInfo.CanWrite || !propertyInfo.GetSetMethod(true).IsPublic))) { IgnoreMemberList.Add(prop.Name); continue; } AutoMembers[prop] = setprop; AutoMapProperty(prop, setprop); } }
private void CreateQueryableProjection() { try { foreach (var customMember in CustomMembers) { ProcessProjectingMember(customMember.Value, customMember.Key.Member as PropertyInfo); } foreach (var flattenedMember in FlattenMembers) { ProcessProjectingMember(flattenedMember.Value, flattenedMember.Key.Member as PropertyInfo); } foreach (var autoMember in AutoMembers) { if (_bindingExpressions.ContainsKey(autoMember.Value.Name) || IgnoreMemberList.Contains(autoMember.Value.Name)) { continue; } var destination = autoMember.Value as PropertyInfo; var propertyOrField = Expression.PropertyOrField(SourceParameter, autoMember.Key.Name); ProcessProjectingMember(propertyOrField, destination); } QueryableExpression = Expression.Lambda <Func <T, TN> >( Expression.MemberInit(Expression.New(typeof(TN)), _bindingExpressions.Values), SourceParameter); } catch (Exception ex) { Debug.WriteLine("Queryable projection is not supported for such mapping. Exception: {0}", ex); } }
protected override void CompileInternal() { if (ResultMapFunction != null) { return; } var destVariable = GetDestionationVariable(); ProcessCustomMembers(); ProcessCustomFunctionMembers(); ProcessFlattenedMembers(); ProcessAutoProperties(); CreateQueryableProjection(); var expressions = new List <Expression> { destVariable }; if (BeforeMapHandler != null) { Expression <Action <T, TN> > beforeExpression = (src, dest) => BeforeMapHandler(src, dest); var beforeInvokeExpr = Expression.Invoke(beforeExpression, SourceParameter, destVariable.Left); expressions.Add(beforeInvokeExpr); } expressions.AddRange(PropertyCache.Values); var customProps = CustomPropertyCache.Where(k => !IgnoreMemberList.Contains(k.Key)).Select(k => k.Value); expressions.AddRange(customProps); if (AfterMapHandler != null) { Expression <Action <T, TN> > afterExpression = (src, dest) => AfterMapHandler(src, dest); var afterInvokeExpr = Expression.Invoke(afterExpression, SourceParameter, destVariable.Left); expressions.Add(afterInvokeExpr); } ResultExpressionList.AddRange(expressions); expressions.Add(destVariable.Left); var variables = new List <ParameterExpression>(); var finalExpression = Expression.Block(variables, expressions); var destExpression = destVariable.Left as ParameterExpression; var substituteParameterVisitor = new PreciseSubstituteParameterVisitor( new KeyValuePair <ParameterExpression, ParameterExpression>(SourceParameter, SourceParameter), new KeyValuePair <ParameterExpression, ParameterExpression>(destExpression, destExpression)); var resultExpression = substituteParameterVisitor.Visit(finalExpression) as BlockExpression; var expression = Expression.Lambda <Func <T, TN, TN> >(resultExpression, SourceParameter, DestFakeParameter); ResultMapFunction = expression.Compile(); }
protected void ProcessAutoProperties() { var getFields = typeof(T).GetInfo() .GetFields(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public); var setFields = typeof(TN).GetInfo() .GetFields(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public); var getProps = typeof(T).GetInfo() .GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public); var setProps = typeof(TN).GetInfo() .GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public); var sourceMembers = getFields.Cast <MemberInfo>().Union(getProps); var destMembers = setFields.Cast <MemberInfo>().Union(setProps); var stringComparison = GetStringCase(); var comparer = CultureInfo.CurrentCulture.CompareInfo.GetStringComparer(CompareOptions.OrdinalIgnoreCase); //var comparer = StringComparer.Create(CultureInfo.CurrentCulture, // stringComparison == StringComparison.OrdinalIgnoreCase); foreach (var prop in sourceMembers) { if (IgnoreMemberList.Contains(prop.Name, comparer) || CustomPropertyCache.Keys.Contains(prop.Name, comparer)) { continue; } var notUniqueDestMembers = destMembers.Where(x => string.Equals(x.Name, prop.Name, stringComparison)); var notUniqueSrcMembers = sourceMembers.Where(x => string.Equals(x.Name, prop.Name, stringComparison)); var getprop = GetTopMostMemberOfHierarchy(notUniqueSrcMembers); if (AutoMembers.ContainsKey(getprop)) { continue; } var setprop = GetTopMostMemberOfHierarchy(notUniqueDestMembers); var propertyInfo = setprop as PropertyInfo; if ((propertyInfo == null && setprop == null) || (propertyInfo != null && (!propertyInfo.CanWrite || !propertyInfo.GetSetMethod(true).IsPublic))) { IgnoreMemberList.Add(getprop.Name); continue; } AutoMembers[getprop] = setprop; AutoMapProperty(getprop, setprop); } }
public virtual void Ignore <TMember>(Expression <Func <TN, TMember> > left) { var memberExpression = left.Body as MemberExpression; IgnoreMemberList.Add(memberExpression.Member.Name); }
public void Ignore(PropertyInfo left) { IgnoreMemberList.Add(left.Name); }