public IList <MemberMapping> ResolveMappings(IMappingImplementation impl) { var src = impl.Src; var dest = impl.Dest; var memberEvals = impl.GetMemberConfigurations() .ToLookup(x => ResolveMember(x.Item1), x => x.Item2); if (memberEvals.Any(g => g.Count() > 1)) { throw new NotSupportedException(); } var mappings = GetMappings(src, dest) .Where(x => !memberEvals[x.Item1].Any(eval => eval == null)) .Select(x => new MemberMapping { Target = x.Item1, Member = x.Item2, Lambda = memberEvals[x.Item1].FirstOrDefault() }) .ToList(); var voidMapping = mappings.FirstOrDefault(x => x.IsVoid()); if (voidMapping != null) { var memberType = voidMapping.Target.MemberType == MemberTypes.Field ? "Field" : "Property"; throw new MissingMemberException( $"{memberType} {dest.Name}.{voidMapping.Target.Name} has no corresponding member in {src.Name} type."); } return(mappings); }
internal bool BuildUp <TSource, TDest>(IMappingImplementation impl) { if (MapEssence <TSource, TDest> .MapFunc != null) { return(false); } var mapFactory = new MapFactory(new MemberMappingsResolver(), dynamicMemberResolver, new MapEmitter(typeof(TDest))); MapEssence <TSource, TDest> .MapFunc = mapFactory.BuildMapMethod <TSource, TDest>(impl); return(true); }
public DynamicBuilders ResolveBuilders(IMappingImplementation impl) { DynamicBuilders result; if (!cacheBuilders.TryGetValue(impl, out result)) { var dynType = DynamicModuleHost.NewMapperDynamicType(); var dynMethod = dynType.DefineMethod("Map", MethodAttributes.Static | MethodAttributes.Public, impl.Dest, new[] { impl.Src }); dynMethod.DefineParameter(1, ParameterAttributes.None, "x"); cacheBuilders[impl] = result = new DynamicBuilders(dynType, dynMethod); resolvedMappings.Add(impl); } return(result); }
public Func <TSource, TDest> BuildMapMethod <TSource, TDest>(IMappingImplementation mappingImplementation) { var memberMappings = memberMappingsResolver.ResolveMappings(mappingImplementation); var builders = dynamicMemberResolver.ResolveBuilders(mappingImplementation); var dynType = builders.Item1; var dynMethod = builders.Item2; var memberBindings = dynamicMemberResolver.ResolveMemberBindings(memberMappings, l => CreateLambdaMethod(l, dynType)); var gen = dynMethod.GetILGenerator(); var def = mappingImplementation.Default != null ? CreateDefaultMethod(mappingImplementation.Default, dynType) : null; emitter.Init(gen, typeof(TSource), def); if (mappingImplementation.Create != null) { var creator = CreateLambdaMethod(mappingImplementation.Create, dynType); emitter.Create(gen, creator); } else { emitter.Newobj(gen); } emitter.Map(gen, memberBindings); emitter.Return(gen); dynType.CreateType(); var methodToken = dynMethod.GetToken().Token; var methodInfo = (MethodInfo)DynamicModuleHost.Module.ResolveMethod(methodToken); return((Func <TSource, TDest>)Delegate.CreateDelegate(typeof(Func <TSource, TDest>), methodInfo)); }