From 233c9df1d6485ebe93aa27df63c0077a27362ef8 Mon Sep 17 00:00:00 2001 From: Mole Date: Mon, 14 Nov 2022 11:37:55 +0100 Subject: [PATCH] V11: InMemory - only add models assembly as runtime view reference if it exists (#13390) * Only add models assembly as runtime view reference if it exists * Add in memory metadata reference properly compilations are readonly --- .../CollectibleRuntimeViewCompiler.cs | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/Umbraco.Web.Common/ModelsBuilder/InMemoryAuto/CollectibleRuntimeViewCompiler.cs b/src/Umbraco.Web.Common/ModelsBuilder/InMemoryAuto/CollectibleRuntimeViewCompiler.cs index 742e7ffc29..d266b51dd1 100644 --- a/src/Umbraco.Web.Common/ModelsBuilder/InMemoryAuto/CollectibleRuntimeViewCompiler.cs +++ b/src/Umbraco.Web.Common/ModelsBuilder/InMemoryAuto/CollectibleRuntimeViewCompiler.cs @@ -396,26 +396,30 @@ internal class CollectibleRuntimeViewCompiler : IViewCompiler private CSharpCompilation CreateCompilation(string compilationContent, string assemblyName) { IReadOnlyList refs = _referenceManager.CompilationReferences; - // We'll add the reference to the InMemory assembly directly, this means we don't have to hack around with assembly parts. - if (_loadContextManager.ModelsAssemblyLocation is null) - { - throw new InvalidOperationException("No InMemory assembly available, cannot compile views"); - } - - PortableExecutableReference inMemoryAutoReference = MetadataReference.CreateFromFile(_loadContextManager.ModelsAssemblyLocation); - var sourceText = SourceText.From(compilationContent, Encoding.UTF8); SyntaxTree syntaxTree = SyntaxFactory .ParseSyntaxTree(sourceText, _compilationOptionsProvider.ParseOptions) .WithFilePath(assemblyName); - return CSharpCompilation + CSharpCompilation compilation = CSharpCompilation .Create(assemblyName) .AddSyntaxTrees(syntaxTree) .AddReferences(refs) - .AddReferences(inMemoryAutoReference) .WithOptions(_compilationOptionsProvider.CSharpCompilationOptions); + + // We'll add the reference to the InMemory assembly directly, this means we don't have to hack around with assembly parts. + // We might be asked to compile views before the InMemory models assembly is created tho (if you replace the no-nodes for instance) + // In this case we'll just skip the InMemory models assembly reference + if (_loadContextManager.ModelsAssemblyLocation is null) + { + _logger.LogInformation("No InMemory models assembly available, skipping reference"); + return compilation; + } + + PortableExecutableReference inMemoryAutoReference = MetadataReference.CreateFromFile(_loadContextManager.ModelsAssemblyLocation); + compilation = compilation.AddReferences(inMemoryAutoReference); + return compilation; } private string GetNormalizedPath(string relativePath)