public IQualifiedMember RootSource <TSource, TTarget>()
        {
            var rootMember = _memberCache.GetOrAdd(
                QualifiedMemberKey.Keys <TSource, TTarget> .Source,
                k =>
            {
                var matchedTargetMember = RootTarget <TSource, TTarget>();

                var sourceMember = QualifiedMember
                                   .CreateRoot(Member.RootSource <TSource>(), _mapperContext)
                                   .SetContext(matchedTargetMember.Context);

                return(GetFinalSourceMember(sourceMember, matchedTargetMember));
            });

            return(rootMember);
        }
 public QualifiedMemberContext(
     MappingRuleSet ruleSet,
     Type sourceType,
     Type targetType,
     IQualifiedMember sourceMember,
     QualifiedMember targetMember,
     IQualifiedMemberContext parent,
     MapperContext mapperContext)
     : this(
         ruleSet,
         sourceType,
         targetType,
         targetMember,
         parent,
         mapperContext)
 {
     SourceMember = sourceMember.SetContext(this);
 }
        private static QualifiedMember CreateMember(
            Expression memberAccessExpression,
            Func <Type, Member> rootMemberFactory,
            Func <Type, IList <Member> > membersFactory,
            MapperContext mapperContext)
        {
            var expression     = memberAccessExpression;
            var memberAccesses = new List <Expression>();

            while (expression.NodeType != ExpressionType.Parameter)
            {
                var memberExpression = GetMemberAccess(expression);
                memberAccesses.Insert(0, memberExpression);
                expression = memberExpression.GetParentOrNull();
            }

            AdjustMemberAccessesIfRootedInMappingData(memberAccesses, ref expression);

            var rootMember   = rootMemberFactory.Invoke(expression.Type);
            var parentMember = rootMember;

            var memberChain = new Member[memberAccesses.Count + 1];

            memberChain[0] = rootMember;

            for (var i = 0; i < memberAccesses.Count; i++)
            {
                var memberAccess = memberAccesses[i];
                var memberName   = GetMemberName(memberAccess);
                var members      = membersFactory.Invoke(parentMember.Type);
                var member       = members.FirstOrDefault(m => m.Name == memberName);

                if (member == null)
                {
                    return(null);
                }

                memberChain[i + 1] = member;
                parentMember       = member;
            }

            return(QualifiedMember.From(memberChain, mapperContext));
        }
Example #4
0
        private QualifiedMember(Member member, QualifiedMember parent, MapperContext mapperContext)
            : this(member, mapperContext)
        {
            var memberMatchingNames = mapperContext.Naming.GetMatchingNamesFor(member);

            if (parent == null)
            {
                MemberChain  = new[] { member };
                JoinedNames  = memberMatchingNames;
                _pathFactory = () => MemberChain[0].JoiningName;
                return;
            }

            MemberChain = parent.MemberChain.Append(member);
            JoinedNames = parent.JoinedNames.ExtendWith(memberMatchingNames, mapperContext);

            _pathFactory = () => parent.GetPath() + member.JoiningName;
            IsRecursion  = DetermineRecursion();
        }
Example #5
0
        private static bool TargetMemberEverRepeatsWithin(QualifiedMember parentMember, IQualifiedMember subjectMember)
        {
            while (true)
            {
                var nonSimpleChildMembers = GetTargetMembers(parentMember.Type)
                                            .Filter(m => !m.IsSimple)
                                            .ToArray();

                if (nonSimpleChildMembers.None())
                {
                    return(false);
                }

                var sameTypedChildMembers = nonSimpleChildMembers
                                            .Filter(subjectMember, (sm, cm) => (cm.IsEnumerable ? cm.ElementType : cm.Type) == sm.Type)
                                            .ToArray();

                if (sameTypedChildMembers
                    .Project(parentMember, GetNonEnumerableChildMember)
                    .Any(cm => cm != subjectMember))
                {
                    return(true);
                }

                foreach (var childMember in nonSimpleChildMembers)
                {
                    var qualifiedChildMember = GetNonEnumerableChildMember(parentMember, childMember);

                    if (qualifiedChildMember.IsRecursion)
                    {
                        continue;
                    }

                    if (TargetMemberEverRepeatsWithin(qualifiedChildMember, subjectMember))
                    {
                        return(true);
                    }
                }

                return(false);
            }
        }
        private QualifiedMember(Member member, QualifiedMember parent, MapperContext mapperContext)
            : this(member, mapperContext)
        {
            if (parent == null)
            {
                MemberChain  = new[] { member };
                JoinedNames  = NamingSettings.RootMatchingNames;
                _pathFactory = m => m.LeafMember.JoiningName;
                return;
            }

            _parent     = parent;
            MemberChain = parent.MemberChain.Append(member);
            var memberMatchingNames = mapperContext.Naming.GetMatchingNamesFor(member, parent.Context);

            JoinedNames = parent.JoinedNames.ExtendWith(memberMatchingNames, mapperContext);

            _pathFactory = m => m._parent.GetPath() + m.LeafMember.JoiningName;
            IsRecursion  = DetermineRecursion();
        }
Example #7
0
        public static bool IsUnmappable(this QualifiedMember member, out string reason)
        {
            if (IsStructNonSimpleMember(member))
            {
                reason = member.Type.GetFriendlyName() + " member on a struct";
                return(true);
            }

            if (member.LeafMember.MemberType == MemberType.SetMethod)
            {
                reason = null;
                return(false);
            }

            if (!member.IsReadOnly)
            {
                reason = null;
                return(false);
            }

            if (member.Type.IsArray)
            {
                reason = "readonly array";
                return(true);
            }

            if (member.IsSimple || member.Type.IsValueType())
            {
                reason = "readonly " + ((member.IsComplex) ? "struct" : member.Type.GetFriendlyName());
                return(true);
            }

            if (member.IsEnumerable && member.Type.IsClosedTypeOf(typeof(ReadOnlyCollection <>)))
            {
                reason = "readonly " + member.Type.GetFriendlyName();
                return(true);
            }

            reason = null;
            return(false);
        }
Example #8
0
        private static QualifiedMember CreateMember(
            Expression memberAccessExpression,
            Func <Type, Member> rootMemberFactory,
            Func <Type, IList <Member> > membersFactory,
            Action <ExpressionType> nonMemberAction,
            MapperContext mapperContext)
        {
            var memberAccesses = memberAccessExpression.GetMemberAccessChain(nonMemberAction, out var rootExpression);

            if (memberAccesses.None())
            {
                return(null);
            }

            var rootMember   = rootMemberFactory.Invoke(rootExpression.Type);
            var parentMember = rootMember;

            var memberChain = new Member[memberAccesses.Count + 1];

            memberChain[0] = rootMember;

            for (var i = 0; i < memberAccesses.Count;)
            {
                var memberAccess = memberAccesses[i++];
                var memberName   = GetMemberName(memberAccess);
                var members      = membersFactory.Invoke(parentMember.Type);
                var member       = members.FirstOrDefault(memberName, (mn, m) => m.Name == mn);

                if (member == null)
                {
                    return(null);
                }

                memberChain[i] = member;
                parentMember   = member;
            }

            return(QualifiedMember.From(memberChain, mapperContext));
        }
Example #9
0
        public static bool HasCompatibleTypes <TOtherTypePair>(
            this ITypePair typePair,
            TOtherTypePair otherTypePair,
            IQualifiedMember sourceMember = null,
            QualifiedMember targetMember  = null)
            where TOtherTypePair : ITypePair
        {
            var sourceTypesMatch =
                typePair.IsForSourceType(otherTypePair.SourceType) ||
                (sourceMember?.HasCompatibleType(typePair.SourceType) == true);

            if (!sourceTypesMatch)
            {
                return(false);
            }

            var targetTypesMatch =
                (targetMember?.HasCompatibleType(typePair.TargetType) == true) ||
                otherTypePair.TargetType.IsAssignableTo(typePair.TargetType);

            return(targetTypesMatch);
        }
Example #10
0
        public static bool TargetMemberIsUnmappable <TTypePair>(
            this TTypePair typePair,
            QualifiedMember targetMember,
            Func <TTypePair, IEnumerable <ConfiguredDataSourceFactory> > configuredDataSourcesFactory,
            out string reason)
            where TTypePair : ITypePair
        {
            if (targetMember == QualifiedMember.All)
            {
                reason = null;
                return(false);
            }

            if ((typePair.TargetType != typePair.SourceType) &&
                targetMember.LeafMember.IsEntityId() &&
                configuredDataSourcesFactory.Invoke(typePair).None())
            {
                reason = "Entity key member";
                return(true);
            }

            return(targetMember.IsUnmappable(out reason));
        }
        public QualifiedMemberContext(
            MappingRuleSet ruleSet,
            Type sourceType,
            Type targetType,
            QualifiedMember targetMember,
            IQualifiedMemberContext parent,
            MapperContext mapperContext)
        {
            if (parent == null)
            {
                IsRoot = true;
            }
            else
            {
                _parent = parent;
            }

            SourceType    = sourceType;
            TargetType    = targetType;
            RuleSet       = ruleSet;
            MapperContext = mapperContext;
            TargetMember  = (targetMember?.SetContext(this)) ?? QualifiedMember.All;
        }
Example #12
0
        public static bool TargetMemberIsUnmappable <TTMapperData>(
            this TTMapperData mapperData,
            QualifiedMember targetMember,
            Func <TTMapperData, IEnumerable <ConfiguredDataSourceFactory> > configuredDataSourcesFactory,
            UserConfigurationSet userConfigurations,
            out string reason)
            where TTMapperData : IBasicMapperData
        {
            if (targetMember == QualifiedMember.All)
            {
                reason = null;
                return(false);
            }

            if (!targetMember.LeafMember.IsEntityId() ||
                userConfigurations.MapEntityKeys(mapperData) ||
                configuredDataSourcesFactory.Invoke(mapperData).Any())
            {
                return(targetMember.IsUnmappable(out reason));
            }

            // If we're here:
            //   1. TargetMember is an Entity key
            //   2. The rule set doesn't allow entity key mapping
            //   3. No configuration exists to allow Entity key Mapping
            //   4. No configured data sources exist

            if (mapperData.RuleSet.Settings.AllowCloneEntityKeyMapping &&
                (mapperData.SourceType == mapperData.TargetType))
            {
                return(targetMember.IsUnmappable(out reason));
            }

            reason = "Entity key member";
            return(true);
        }
Example #13
0
 public static bool IsConstructorParameter(this QualifiedMember member)
 => member.LeafMember.MemberType == MemberType.ConstructorParameter;
Example #14
0
 public static bool IsEnumerableElement(this QualifiedMember member) => member.LeafMember.IsEnumerableElement();
Example #15
0
 public static Expression GetAccess(this QualifiedMember member, IMemberMapperData mapperData)
 => member.GetAccess(mapperData.TargetInstance, mapperData);
Example #16
0
 public static Expression GetEmptyInstanceCreation(this QualifiedMember member)
 => member.Type.GetEmptyInstanceCreation(member.ElementType);
Example #17
0
 public bool CouldMatch(QualifiedMember otherMember)
 => _matchedTargetMemberJoinedNames.CouldMatch(otherMember.JoinedNames);
Example #18
0
 public bool CouldMatch(QualifiedMember otherMember)
 {
     throw new NotImplementedException();
 }
Example #19
0
 public static QualifiedMember GetElementMember(this QualifiedMember enumerableMember)
 => enumerableMember.Append(GetElementMember(enumerableMember.Type));
Example #20
0
 public ChildMemberMapperData(QualifiedMember targetMember, ObjectMapperData parent)
     : base(parent.RuleSet, parent.SourceType, parent.TargetType, targetMember, parent)
 {
     Parent  = parent;
     Context = new MapperDataContext(this);
 }
Example #21
0
 private QualifiedMember CreateFinalMember(QualifiedMember member)
 {
     return(member.IsTargetMember
         ? _mapperContext.QualifiedMemberFactory.GetFinalTargetMember(member)
         : member);
 }
 public bool CouldMatch(QualifiedMember otherMember) => JoinedNames.CouldMatch(otherMember.JoinedNames);
 public bool CouldMatch(QualifiedMember otherMember) => _matchedTargetMember.CouldMatch(otherMember);