public bool Compile() { string newAssemblyNamespace = $"{_configurationSourceAssembly.GetName().Name.Replace("-", "_")}.Functions"; IFunctionCompilerMetadata functionCompilerMetadata = null; IFunctionAppConfiguration configuration = ConfigurationLocator.FindConfiguration(_configurationSourceAssembly); if (configuration == null) { functionCompilerMetadata = ConfigurationLocator.FindCompilerMetadata(_configurationSourceAssembly); if (functionCompilerMetadata == null) { _compilerLog.Error($"The assembly {_configurationSourceAssembly.GetName().Name} does not contain a public class implementing the IFunctionAppConfiguration interface"); return(false); } } else { FunctionHostBuilder builder = new FunctionHostBuilder(_serviceCollection, _commandRegistry, false); configuration.Build(builder); new PostBuildPatcher().Patch(builder, newAssemblyNamespace); if (!VerifyCommandAndResponseTypes(builder)) { return(false); } functionCompilerMetadata = new FunctionCompilerMetadata { FunctionDefinitions = builder.FunctionDefinitions, OpenApiConfiguration = builder.OpenApiConfiguration, OutputAuthoredSourceFolder = builder.OutputAuthoredSourceFolder }; } IReadOnlyCollection <string> externalAssemblies = GetExternalAssemblyLocations(functionCompilerMetadata.FunctionDefinitions); OpenApiOutputModel openApi = _openApiCompiler.Compile(functionCompilerMetadata.OpenApiConfiguration, functionCompilerMetadata.FunctionDefinitions, _outputBinaryFolder); _jsonCompiler.Compile(functionCompilerMetadata.FunctionDefinitions, openApi, _outputBinaryFolder, newAssemblyNamespace); return(_assemblyCompiler.Compile(functionCompilerMetadata.FunctionDefinitions, configuration?.GetType() ?? functionCompilerMetadata.BacklinkReferenceType, configuration != null ? null : functionCompilerMetadata.BacklinkPropertyInfo, newAssemblyNamespace, externalAssemblies, _outputBinaryFolder, $"{newAssemblyNamespace}.dll", openApi, _compileTarget, functionCompilerMetadata.OutputAuthoredSourceFolder)); }
private bool CompileAssembly(IReadOnlyCollection <SyntaxTree> syntaxTrees, IReadOnlyCollection <string> externalAssemblyLocations, OpenApiOutputModel openApiOutputModel, string outputBinaryFolder, string outputAssemblyName, string assemblyNamespace, CompileTargetEnum compileTarget, bool isFSharpProject) { IReadOnlyCollection <string> locations = BuildCandidateReferenceList(externalAssemblyLocations, compileTarget, isFSharpProject); const string manifestResourcePrefix = "FunctionMonkey.Compiler.references.netstandard2._0."; // For each assembly we've found we need to check and see if it is already included in the output binary folder // If it is then its referenced already by the function host and so we add a reference to that version. List <string> resolvedLocations = ResolveLocationsWithExistingReferences(outputBinaryFolder, locations); string[] manifestResoureNames = GetType().Assembly.GetManifestResourceNames() .Where(x => x.StartsWith(manifestResourcePrefix)) .Select(x => x.Substring(manifestResourcePrefix.Length)) .ToArray(); List <PortableExecutableReference> references = BuildReferenceSet(resolvedLocations, manifestResoureNames, manifestResourcePrefix, compileTarget); CSharpCompilation compilation = CSharpCompilation.Create(outputAssemblyName) .WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)) .AddReferences(references) .AddSyntaxTrees(syntaxTrees) ; List <ResourceDescription> resources = null; if (openApiOutputModel != null) { resources = new List <ResourceDescription>(); Debug.Assert(openApiOutputModel.OpenApiSpecification != null); resources.Add(new ResourceDescription($"{assemblyNamespace}.OpenApi.{openApiOutputModel.OpenApiSpecification.Filename}", () => new MemoryStream(Encoding.UTF8.GetBytes(openApiOutputModel.OpenApiSpecification.Content)), true)); if (openApiOutputModel.SwaggerUserInterface != null) { foreach (OpenApiFileReference fileReference in openApiOutputModel.SwaggerUserInterface) { OpenApiFileReference closureCapturedFileReference = fileReference; resources.Add(new ResourceDescription($"{assemblyNamespace}.OpenApi.{closureCapturedFileReference.Filename}", () => new MemoryStream(Encoding.UTF8.GetBytes(closureCapturedFileReference.Content)), true)); } } } string outputFilename = Path.Combine(outputBinaryFolder, outputAssemblyName); EmitResult compilationResult = compilation.Emit(outputFilename, manifestResources: resources); if (!compilationResult.Success) { IEnumerable <Diagnostic> failures = compilationResult.Diagnostics.Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error); foreach (Diagnostic diagnostic in failures) { _compilerLog.Error($"Error compiling function: {diagnostic.ToString()}"); } } return(compilationResult.Success); }
public bool Compile() { string newAssemblyNamespace = $"{_configurationSourceAssembly.GetName().Name.Replace("-", "_")}.Functions"; IFunctionCompilerMetadata functionCompilerMetadata = null; IFunctionAppConfiguration configuration = null; FunctionAppHostBuilder appHostBuilder = null; IFunctionAppHost appHost = ConfigurationLocator.FindFunctionAppHost(_configurationSourceAssembly); if (appHost != null) { appHostBuilder = new FunctionAppHostBuilder(); appHost.Build(appHostBuilder); if (appHostBuilder.FunctionAppConfiguration != null) { configuration = (IFunctionAppConfiguration)Activator.CreateInstance(appHostBuilder.FunctionAppConfiguration); } } if (configuration == null) { configuration = ConfigurationLocator.FindConfiguration(_configurationSourceAssembly); } if (configuration == null) { functionCompilerMetadata = ConfigurationLocator.FindCompilerMetadata(_configurationSourceAssembly); if (functionCompilerMetadata == null) { _compilerLog.Error($"The assembly {_configurationSourceAssembly.GetName().Name} does not contain a public class implementing the IFunctionAppConfiguration interface"); return(false); } } else { FunctionHostBuilder builder = new FunctionHostBuilder(_serviceCollection, _commandRegistry, false); if (appHostBuilder != null) { builder.Options = appHostBuilder.Options; } configuration.Build(builder); DefaultMediatorSettings.SetDefaultsIfRequired(builder); if (!ValidateCommandTypes(builder)) { return(false); } IMediatorResultTypeExtractor extractor = CreateMediatorResultTypeExtractor(builder.Options.MediatorResultTypeExtractor); if (extractor == null) { return(false); } new PostBuildPatcher(extractor).Patch(builder, newAssemblyNamespace); if (!VerifyCommandAndResponseTypes(builder)) { return(false); } if (!VerifyOutputBindings(builder)) { return(false); } functionCompilerMetadata = new FunctionCompilerMetadata { FunctionDefinitions = builder.FunctionDefinitions, OpenApiConfiguration = builder.OpenApiConfiguration, OutputAuthoredSourceFolder = builder.Options.OutputSourceTo, CompilerOptions = builder.Options }; } PostBuildPatcher.EnsureFunctionsHaveUniqueNames(functionCompilerMetadata.FunctionDefinitions); IReadOnlyCollection <string> externalAssemblies = GetExternalAssemblyLocations(functionCompilerMetadata.FunctionDefinitions); ITargetCompiler targetCompiler = functionCompilerMetadata.CompilerOptions.HttpTarget == CompileTargetEnum.AzureFunctions ? (ITargetCompiler) new AzureFunctionsCompiler(_compilerLog) : new AspNetCoreCompiler(_compilerLog); return(targetCompiler.CompileAssets(functionCompilerMetadata, newAssemblyNamespace, configuration, externalAssemblies, _outputBinaryFolder)); }