Exemple #1
0
        /// <summary>
        /// Compile the actions using C# compiler.
        /// Important: Essential references for subject and executor types are added to the configuration automagically
        /// </summary>
        /// <param name="configuration">Compiler configuration</param>
        /// <returns>Executor object</returns>
        public IExecutor <S> Compile(ICompilerConfiguration <S> configuration)
        {
            ValidateConfiguration(configuration);

            AddTemplateReferences(configuration);

            // generate code
            var codeGenerator = new CSharpExecutorTemplate(configuration);

            var session = new TextTemplatingSession();

            codeGenerator.Session = session;
            codeGenerator.Initialize();

            var code = codeGenerator.TransformText();

            var executorTypeName = $"{configuration.GetNamespace()}.{configuration.GetClassName()}";

            CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");

            CompilerParameters parameters = new CompilerParameters
            {
                GenerateExecutable = false,
                CompilerOptions    = "/t:library"
            };

            foreach (var reference in configuration.References)
            {
                var referenceAssembly = reference.Assembly.GetName().Name;
                if (!parameters.ReferencedAssemblies.Contains(referenceAssembly))
                {
                    parameters.ReferencedAssemblies.Add(referenceAssembly);
                }
            }

            var results = codeProvider.CompileAssemblyFromSource(parameters, code);

            ValidateCompilationResults(results);

            var executorType = results.CompiledAssembly.GetType(executorTypeName);

            var executorInstanceHandle = Activator.CreateInstance(executorType);

            return((IExecutor <S>)executorInstanceHandle);
        }
Exemple #2
0
        /// <summary>
        /// Compile the actions using C# compiler.
        /// Important: Essential references for subject and executor types are added to the configuration automagically
        /// </summary>
        /// <param name="configuration">Compiler configuration</param>
        /// <returns>Executor object</returns>
        public IExecutor <S> Compile(ICompilerConfiguration <S> configuration)
        {
            ValidateConfiguration(configuration);

            AddTemplateReferences(configuration);

            // generate code
            var codeGenerator = new CSharpExecutorTemplate(configuration);

            codeGenerator.Initialize();
            var code = codeGenerator.TransformText();

            var executorClassName = $"{configuration.GetNamespace()}.{configuration.GetClassName()}";

            SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(text: code);

            Compilation compilation = CSharpCompilation.Create(
                assemblyName: $"Assembly_{Guid.NewGuid().ToString().Replace("-", string.Empty)}",
                syntaxTrees: new[] { syntaxTree },
                references: GenerateRequiredReferences(configuration),
                options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
                );

            // Emit the image of this assembly
            byte[] image = null;
            using (var ms = new MemoryStream())
            {
                var emitResult = compilation.Emit(ms);
                ValidateCompilationResults(emitResult);
                image = ms.ToArray();
            }

            using var stream = new MemoryStream(image);

            var assembly = AssemblyLoadContext.Default.LoadFromStream(stream);

            var executorClassType = assembly.GetType(executorClassName);

            var executorInstanceHandle = Activator.CreateInstance(executorClassType);

            return((IExecutor <S>)executorInstanceHandle);
        }