private static void AddReferences(CodeToAssemblyGenerator generator, List <Type> allTypes, TypeToTypeWrapperOptions options, Type originalType)
        {
            generator.ReferenceAssemblyContainingType <Action>();
            generator.ReferenceAssemblyContainingType <DelegateCache>();
            generator.ReferenceAssemblyContainingType <DelegateToTypeWrapper>();

            foreach (var allType in allTypes)
            {
                generator.ReferenceAssembly(allType.Assembly);
            }

            if (options?.AdditionalReferences?.Any() == true)
            {
                foreach (var additionalReference in options.AdditionalReferences)
                {
                    generator.ReferenceAssembly(additionalReference);
                }
            }

            if (options?.TypeAttributesGenerator != null)
            {
                var attrs = options.TypeAttributesGenerator(options, originalType);

                foreach (var attribute in attrs)
                {
                    generator.ReferenceAssembly(attribute.GetType().Assembly);
                }
            }

            if (options?.Inherits != null)
            {
                generator.ReferenceAssembly(options.Inherits.Assembly);
            }
        }
Example #2
0
        private static void AddReferences(CodeToAssemblyGenerator generator, List <Type> allTypes)
        {
            generator.ReferenceAssemblyContainingType <Action>();
            generator.ReferenceAssemblyContainingType <DelegateCache>();
            generator.ReferenceAssemblyContainingType <DelegateToTypeWrapper>();

            foreach (var allType in allTypes)
            {
                generator.ReferenceAssembly(allType.Assembly);
            }
        }
        public Task <Assembly> CreateAssembly()
        {
            try
            {
                var generator = new CodeToAssemblyGenerator();
                generator.ReferenceAssemblyContainingType <Action>();

                if (_options.AdditionalReferences?.Any() == true)
                {
                    foreach (var assembly in _options.AdditionalReferences)
                    {
                        generator.ReferenceAssembly(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;");

                if (_options.AdditionalNamespaces?.Any() == true)
                {
                    foreach (var ns in _options.AdditionalNamespaces)
                    {
                        code.AppendLine($"using {ns};");
                    }
                }

                code.AppendLine(_code);
                var assemblySourceCode = code.ToString();

                var result = generator.Generate(assemblySourceCode);

                return(Task.FromResult(result));
            }
            catch (Exception e)
            {
                throw new InvalidCodeException("Failed to create assembly from regular code. Code: " + _code, e);
            }
        }
        public async Task <Assembly> CreateAssembly(AssemblyLoadContext loadContext)
        {
            try
            {
                var returnType = await GetReturnType();

                var parameters = await GetParameters();

                var updatedScript = await RemoveProperties(_code);

                var generator = new CodeToAssemblyGenerator();
                generator.ReferenceAssemblyContainingType <Action>();

                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;");
                code.AppendLine("using System.Reflection;");
                code.AppendLine("[assembly: AssemblyFileVersion(\"1.0.0.0\")]");

                if (_options.AdditionalNamespaces?.Any() == true)
                {
                    foreach (var ns in _options.AdditionalNamespaces)
                    {
                        code.AppendLine($"using {ns};");
                    }
                }

                code.AppendLine($"namespace {_options.NamespaceNameGenerator(_options)}");
                code.AppendLine("{");
                code.AppendLine($"public class {_options.TypeNameGenerator(_options)}");
                code.AppendLine("{");
                if (returnType == null)
                {
                    if (_options.ReturnsTask)
                    {
                        code.AppendLine($"public async Task {_options.MethodNameGenerator(_options)}({GetParametersString(parameters)})");
                    }
                    else
                    {
                        code.AppendLine($"public void {_options.MethodNameGenerator(_options)}({GetParametersString(parameters)})");
                    }
                }
                else
                {
                    if (_options.ReturnsTask)
                    {
                        code.AppendLine($"public async Task<{returnType.FullName}> {_options.MethodNameGenerator(_options)}({GetParametersString(parameters)})");
                    }
                    else
                    {
                        code.AppendLine($"public {returnType.FullName} {_options.MethodNameGenerator(_options)}({GetParametersString(parameters)})");
                    }
                }

                code.AppendLine("{"); // Start method
                code.AppendLine(updatedScript);
                code.AppendLine("}"); // End method
                code.AppendLine("}"); // End class
                code.AppendLine("}"); // End namespace

                var assemblySourceCode = code.ToString();

                var result = generator.GenerateAssembly(assemblySourceCode, loadContext);

                return(result);
            }
            catch (Exception e)
            {
                throw new InvalidCodeException("Failed to create assembly from script. Code: " + _code, e);
            }
        }
        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);
        }