private void WriteDelegate(object obj, ObjectHeader header) { bool multi = obj is MulticastDelegate; this.writer.Write(multi); if (!multi) { Delegate objAsDelegate = obj as Delegate; this.WriteObjectData(objAsDelegate.GetMethodInfo()); this.WriteObjectData(objAsDelegate.Target); } else { MulticastDelegate objAsDelegate = obj as MulticastDelegate; Delegate[] invokeList = objAsDelegate.GetInvocationList(); this.WriteObjectData(objAsDelegate.GetMethodInfo()); this.WriteObjectData(objAsDelegate.Target); this.WriteObjectData(invokeList); } }
private void WriteDelegate(XElement element, object obj, ObjectHeader header) { bool multi = obj is MulticastDelegate; // Write the delegates type if (multi) { element.SetAttributeValue("multi", XmlConvert.ToString(multi)); } if (!multi) { XElement methodElement = new XElement("method"); XElement targetElement = new XElement("target"); element.Add(methodElement); element.Add(targetElement); Delegate objAsDelegate = obj as Delegate; this.WriteObjectData(methodElement, objAsDelegate.GetMethodInfo()); this.WriteObjectData(targetElement, objAsDelegate.Target); } else { XElement methodElement = new XElement("method"); XElement targetElement = new XElement("target"); XElement invocationListElement = new XElement("invocationList"); element.Add(methodElement); element.Add(targetElement); element.Add(invocationListElement); MulticastDelegate objAsDelegate = obj as MulticastDelegate; Delegate[] invokeList = objAsDelegate.GetInvocationList(); this.WriteObjectData(methodElement, objAsDelegate.GetMethodInfo()); this.WriteObjectData(targetElement, objAsDelegate.Target); this.WriteObjectData(invocationListElement, invokeList); } }
public Type CreateType(MulticastDelegate multicastDelegate, DelegateToTypeWrapperOptions options = default) { var methodInfo = multicastDelegate.GetMethodInfo(); if (methodInfo == null) { throw new Exception("Couldn't get method info from delegate"); } var parameters = methodInfo.GetParameters(); var returnType = methodInfo.ReturnType; var id = DelegateCache.Add(multicastDelegate); var allTypes = GetRequiredTypes(parameters, returnType); var generator = new CodeToAssemblyGenerator(); AddReferences(generator, allTypes); var code = new StringBuilder(); AddNamespaces(code, allTypes); var constructorParameterNames = new List <string>(); var methodParameterNamesWithTypes = new List <string>(); var constructorParameterNamesWithTypes = new List <string>(); var constructorFielsNamesWithTypes = new List <string>(); var propertyNamesWithTypes = new List <string>(); var delegateMethodParameters = new List <string>(); var conversionRules = options?.ConversionRules; if (conversionRules == null) { conversionRules = new List <ParameterConversionRule>(); } DoConversions(parameters, conversionRules, constructorParameterNames, constructorParameterNamesWithTypes, constructorFielsNamesWithTypes, delegateMethodParameters, propertyNamesWithTypes, methodParameterNamesWithTypes); code.AppendLine(); code.AppendLine($"namespace {GetNamespace(options)}"); code.AppendLine("{"); code.AppendLine($"public class {GetTypeName(options)}"); code.AppendLine("{"); CreateConstructor(options, constructorParameterNames, constructorFielsNamesWithTypes, code, constructorParameterNamesWithTypes); CreateProperties(propertyNamesWithTypes, code); CreateDelegateWrapperMethod(options, returnType, code, methodParameterNamesWithTypes, id, delegateMethodParameters); code.AppendLine("}"); // Close class code.AppendLine("}"); // Close namespace var s = code.ToString(); var assembly = generator.GenerateAssembly(s); var result = assembly.GetExportedTypes().Single(); return(result); }
/* ^ */ private static string GetDescName(MulticastDelegate @delegate) { var _methodInfo = @delegate.GetMethodInfo(); return(_methodInfo.Name); }
public Assembly CreateAssembly(MulticastDelegate multicastDelegate, DelegatePluginCatalogOptions options) { var id = DelegateCache.Add(multicastDelegate); var generator = new CodeToAssemblyGenerator(); generator.ReferenceAssemblyContainingType <Action>(); generator.ReferenceAssemblyContainingType <DelegateCache>(); generator.ReferenceAssemblyContainingType <DelegateToAssemblyConverter>(); var methodInfo = multicastDelegate.GetMethodInfo(); if (methodInfo == null) { throw new Exception("Couldn't get method info from delegate"); } var parameters = methodInfo.GetParameters(); var returnType = methodInfo.ReturnType; var allTypes = new List <Type>(); allTypes.AddRange(parameters.Select(x => x.ParameterType)); allTypes.Add(returnType); var genTypes = new List <Type>(); foreach (var type in allTypes) { genTypes = GetGenericTypes(type, genTypes); } foreach (var genType in genTypes) { allTypes.Add(genType); } foreach (var allType in allTypes) { generator.ReferenceAssembly(allType.Assembly); } var code = new StringBuilder(); code.AppendLine("using System;"); code.AppendLine("using System.Diagnostics;"); code.AppendLine("using System.Threading.Tasks;"); code.AppendLine("using System.Text;"); code.AppendLine("using System.Collections;"); code.AppendLine("using System.Collections.Generic;"); foreach (var t in allTypes) { code.AppendLine($"using {t.Namespace};"); } var constructorParameterNames = new List <string>(); var methodParameterNamesWithTypes = new List <string>(); var constructorParameterNamesWithTypes = new List <string>(); var constructorFielsNamesWithTypes = new List <string>(); var propertyNamesWithTypes = new List <string>(); // var propertyNames = new List<string>(); var delegateMethodParameters = new List <string>(); var conversionRules = options?.ConversionRules; if (conversionRules == null) { conversionRules = new List <DelegateConversionRule>(); } for (var index = 0; index < parameters.Length; index++) { var parameterInfo = parameters[index]; var parameterType = parameterInfo.ParameterType; var parameterName = parameterInfo.Name ?? $"param{Guid.NewGuid().ToString().ToLowerInvariant().Replace("-", "")}"; var handled = false; foreach (var conversionRule in conversionRules) { var canHandle = conversionRule.CanHandle(parameterInfo); if (canHandle) { var conversionResult = conversionRule.Handle(parameterInfo); if (!string.IsNullOrWhiteSpace(conversionResult.Name)) { parameterName = conversionResult.Name; } if (conversionResult.ToConstructor) { constructorParameterNames.Add(parameterName); constructorParameterNamesWithTypes.Add($"{GetFriendlyName(parameterType)} {parameterName}"); var fieldName = $"_{parameterName}"; constructorFielsNamesWithTypes.Add($"{GetFriendlyName(parameterType)} {fieldName}"); delegateMethodParameters.Add(fieldName); handled = true; break; } if (conversionResult.ToPublicProperty) { var propertyName = $"{CultureInfo.InvariantCulture.TextInfo.ToTitleCase(parameterName)}"; if (string.Equals(parameterName, propertyName)) { propertyName = $"{propertyName}Prop"; } propertyNamesWithTypes.Add($"{GetFriendlyName(parameterType)} {propertyName}"); delegateMethodParameters.Add(propertyName); handled = true; break; } methodParameterNamesWithTypes.Add($"{GetFriendlyName(parameterType)} {parameterName}"); delegateMethodParameters.Add(parameterName); handled = true; break; } } if (handled) { continue; } methodParameterNamesWithTypes.Add($"{GetFriendlyName(parameterType)} {parameterName}"); delegateMethodParameters.Add(parameterName); } code.AppendLine(); code.AppendLine($"namespace {GetNamespace(options)}"); code.AppendLine("{"); code.AppendLine($"public class {GetTypeName(options)}"); code.AppendLine("{"); if (constructorParameterNames?.Any() == true) { foreach (var fieldNameWithType in constructorFielsNamesWithTypes) { code.AppendLine($"private {fieldNameWithType};"); } code.AppendLine($"public {GetTypeName(options)}({string.Join(", ", constructorParameterNamesWithTypes)})"); code.AppendLine("{"); foreach (var constructorParameterName in constructorParameterNames) { code.AppendLine($"_{constructorParameterName} = {constructorParameterName};"); } code.AppendLine("}"); // Close constructor } if (propertyNamesWithTypes?.Any() == true) { code.AppendLine(); foreach (var fieldNameWithType in propertyNamesWithTypes) { code.AppendLine($"public {fieldNameWithType} {{get; set;}}"); } code.AppendLine(); } if (typeof(void) != returnType) { code.AppendLine( $"public {GetFriendlyName(returnType)} {GetMethodName(options)} ({string.Join(", ", methodParameterNamesWithTypes)})"); } else { code.AppendLine( $"public void Run ({string.Join(", ", methodParameterNamesWithTypes)})"); } code.AppendLine("{"); code.AppendLine($"var deleg = Weikio.PluginFramework.Catalogs.Delegates.DelegateCache.Get(System.Guid.Parse(\"{id.ToString()}\"));"); if (typeof(void) != returnType) { code.AppendLine( $"return ({GetFriendlyName(returnType)}) deleg.DynamicInvoke({string.Join(", ", delegateMethodParameters)});"); } else { code.AppendLine( $"deleg.DynamicInvoke({string.Join(", ", delegateMethodParameters)});"); } code.AppendLine("}"); // Close method code.AppendLine("}"); // Close class code.AppendLine("}"); // Close namespace var s = code.ToString(); var result = generator.Generate(s); return(result); }