public Action <T, T> CopyAction <T>() { var key = typeof(T).FullName; if (_actions.TryGetValue(key, out var action)) { return(action as Action <T, T>); } var className = CopyProviderHelper.GetClassName(typeof(T), typeof(T)); var flags = BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod; if (!_comp.TryGetValue(className, out var comp)) { comp = GenerateCopyClass(typeof(T), typeof(T)); } // comp = GenerateCopyClass(typeof(T), typeof(TU)); var result = comp.InvokeMember("CopyAction", flags, null, null, null) as Action <T, T>; _actions.Add(key, result); return(result); }
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 void Copy <T, TU>(T source, TU target) { var className = CopyProviderHelper.GetClassName(source.GetType(), target.GetType()); if (!(_maps.TryGetValue(className, out var propMap))) { propMap = AddPropertyMap(source, target); } foreach (var prop in propMap) { var sourceValue = prop.SourceProperty.GetValue(source, null); prop.TargetProperty.SetValue(target, sourceValue, null); } }
public void CopyWithDom <T, TU>(T source, TU target) { var className = CopyProviderHelper.GetClassName(typeof(T), typeof(TU)); var flags = BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod; var args = new object[] { source, target }; if (!_comp.TryGetValue(className, out var comp)) { comp = GenerateCopyClass(source.GetType(), target.GetType()); } // comp = GenerateCopyClass(typeof(T), typeof(TU)); comp.InvokeMember("CopyProps", flags, null, null, args); }
/// <summary> /// Creates the copy action. /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="TU">The type of the u.</typeparam> /// <param name="key">The key.</param> /// <returns></returns> private Action <T, TU> CreateCopyAction <T, TU>(string key) { var className = CopyProviderHelper.GetClassName(typeof(T), typeof(TU)); const BindingFlags flags = BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod; if (!_comp.TryGetValue(className, out var comp)) { comp = GenerateCopyClass(typeof(T), typeof(TU)); } var result = comp.InvokeMember(CopyActionMethodName, flags, null, null, null) as Action <T, TU>; _actions.Add(key, result); return(result); }
/// <summary> /// Generates the copy class. /// </summary> /// <param name="sourceType">Type of the source.</param> /// <param name="targetType">Type of the target.</param> /// <returns></returns> public Type GenerateCopyClass(Type sourceType, Type targetType) { var className = CopyProviderHelper.GetClassName(sourceType, targetType); if (_comp.TryGetValue(className, out var type)) { return(type); } var unit = new CodeCompileUnit(); var ns = CreateNamespace(); unit.Namespaces.Add(ns); var targetClass = CreateClass(className); ns.Types.Add(targetClass); var copyMethod = CreateCopyMethod(sourceType, targetType); targetClass.Members.Add(copyMethod); var copyActionMethod = CreateCopyActionMethod(sourceType, targetType, copyMethod); targetClass.Members.Add(copyActionMethod); Debug.WriteLine(unit.ToString()); var results = BuildAssembly(unit, targetType.Assembly); // Compiler output foreach (var line in results.Output) { Debug.WriteLine(line); } var copierType = results.CompiledAssembly.GetType(NamespaceName + "." + className); _comp.Add(className, copierType); return(copierType); }
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); }