/// <summary>
        /// Creates the copy method.
        /// </summary>
        /// <param name="sourceType">Type of the source.</param>
        /// <param name="targetType">Type of the target.</param>
        /// <returns></returns>
        private static CodeMemberMethod CreateCopyMethod(Type sourceType, Type targetType)
        {
            var copyMethod = new CodeMemberMethod
            {
                Attributes = MemberAttributes.Public | MemberAttributes.Static,
                Name       = CopyMethodName
            };

            var source = new CodeParameterDeclarationExpression(sourceType, "source");
            var target = new CodeParameterDeclarationExpression(targetType, "target");

            copyMethod.Parameters.Add(source);
            copyMethod.Parameters.Add(target);

            var map = CopyProviderHelper.GetMatchingProperties(sourceType, targetType);

            foreach (var item in map)

            {
                var targetReference =
                    new CodeFieldReferenceExpression(new CodeVariableReferenceExpression(target.Name),
                                                     item.TargetProperty.Name);
                var sourceReference =
                    new CodeFieldReferenceExpression(new CodeVariableReferenceExpression(source.Name),
                                                     item.SourceProperty.Name);
                copyMethod.Statements.Add(new CodeAssignStatement(targetReference, sourceReference));
            }

            return(copyMethod);
        }
        public void AddPropertyMap <T, TU>()

        {
            var props = CopyProviderHelper.GetMatchingProperties(typeof(T), typeof(TU));

            var className = CopyProviderHelper.GetClassName(typeof(T), typeof(TU));

            _maps.Add(className, props.ToArray());
        }
        public PropertyMap[] AddPropertyMap(object source, object target)

        {
            var props     = CopyProviderHelper.GetMatchingProperties(source.GetType(), target.GetType());
            var className = CopyProviderHelper.GetClassName(source.GetType(), target.GetType());
            var array     = props.ToArray();

            _maps.Add(className, array);
            return(array);
        }
        public Type GenerateCopyClass(Type sourceType, Type targetType)

        {
            var className = CopyProviderHelper.GetClassName(sourceType, targetType);

            if (_comp.TryGetValue(className, out var type))
            {
                return(type);
            }

            var builder = new StringBuilder();

            builder.Append("namespace CopyHelper {\r\n");

            builder.Append("    using System;\r\n");

            builder.Append("    public class ");

            builder.Append(className);

            builder.Append("   {\r\n");

            builder.Append("        public static Action<" + sourceType.FullName + ", " + targetType.FullName +
                           "> CopyAction()");

            builder.Append("        {\r\n");

            builder.Append("            return CopyProps;");

            builder.Append("        }\r\n");

            builder.Append("        public static void CopyProps(");

            builder.Append(sourceType.FullName);

            builder.Append(" source, ");

            builder.Append(targetType.FullName);

            builder.Append(" target) {\r\n");

            var map = CopyProviderHelper.GetMatchingProperties(sourceType, targetType);

            foreach (var item in map)

            {
                builder.Append("            target.");

                builder.Append(item.TargetProperty.Name);

                builder.Append(" = ");

                builder.Append("source.");

                builder.Append(item.SourceProperty.Name);

                builder.Append(";\r\n");
            }

            builder.Append("        }\r\n   }\r\n}");

            // Write out method body

            Debug.WriteLine(builder.ToString());

            var codeCompiler = CodeDomProvider.CreateProvider("CSharp");

            var compilerParameters = new CompilerParameters();

            compilerParameters.ReferencedAssemblies.Add(typeof(TestObject).Assembly.Location);

            compilerParameters.GenerateInMemory = true;

            var results = codeCompiler.CompileAssemblyFromSource(compilerParameters, builder.ToString());

            // Compiler output

            foreach (var line in results.Output)
            {
                Debug.WriteLine(line);
            }

            var copierType = results.CompiledAssembly.GetType("CopyHelper." + className);

            _comp.Add(className, copierType);

            return(copierType);
        }