From 2f0cf8d3e9283b3f481e5f29d7553a9fa5540e6d Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 14 Aug 2020 14:59:59 -0700 Subject: [PATCH] Add support for views + SingleFileExe --- .../RelatedAssemblyAttribute.cs | 34 +++++++++++++++---- .../Sdk.Razor.CurrentVersion.targets | 2 ++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/Mvc/Mvc.Core/src/ApplicationParts/RelatedAssemblyAttribute.cs b/src/Mvc/Mvc.Core/src/ApplicationParts/RelatedAssemblyAttribute.cs index 0c89c0e49d..5bdfb076c0 100644 --- a/src/Mvc/Mvc.Core/src/ApplicationParts/RelatedAssemblyAttribute.cs +++ b/src/Mvc/Mvc.Core/src/ApplicationParts/RelatedAssemblyAttribute.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; +using System.Runtime.Loader; using Microsoft.AspNetCore.Mvc.Core; namespace Microsoft.AspNetCore.Mvc.ApplicationParts @@ -16,7 +17,8 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationParts [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] public sealed class RelatedAssemblyAttribute : Attribute { - private static readonly Func AssemblyLoadFileDelegate = Assembly.LoadFile; + private static readonly Func LoadFromAssemblyPathDelegate = + AssemblyLoadContext.GetLoadContext(typeof(RelatedAssemblyAttribute).Assembly).LoadFromAssemblyPath; /// /// Initializes a new instance of . @@ -50,7 +52,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationParts throw new ArgumentNullException(nameof(assembly)); } - return GetRelatedAssemblies(assembly, throwOnError, File.Exists, AssemblyLoadFileDelegate); + return GetRelatedAssemblies(assembly, throwOnError, File.Exists, LoadFromAssemblyPathDelegate); } internal static IReadOnlyList GetRelatedAssemblies( @@ -66,7 +68,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationParts // MVC will specifically look for related parts in the same physical directory as the assembly. // No-op if the assembly does not have a location. - if (assembly.IsDynamic || string.IsNullOrEmpty(assembly.Location)) + if (assembly.IsDynamic) { return Array.Empty(); } @@ -78,8 +80,10 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationParts } var assemblyName = assembly.GetName().Name; - var assemblyLocation = assembly.Location; - var assemblyDirectory = Path.GetDirectoryName(assemblyLocation); + // Assembly.Location may be null for a single-file exe. In this case, attempt to look for related parts in the app's base directory + var assemblyDirectory = string.IsNullOrEmpty(assembly.Location) ? + AppContext.BaseDirectory : + Path.GetDirectoryName(assembly.Location); var relatedAssemblies = new List(); for (var i = 0; i < attributes.Length; i++) @@ -91,6 +95,22 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationParts Resources.FormatRelatedAssemblyAttribute_AssemblyCannotReferenceSelf(nameof(RelatedAssemblyAttribute), assemblyName)); } + var relatedAssemblyName = new AssemblyName(attribute.AssemblyFileName); + Assembly relatedAssembly; + try + { + // Perform a cursory check to determine if the Assembly has already been loaded + // before going to disk. In the ordinary case, related parts that are part of + // application's reference closure should already be loaded. + relatedAssembly = Assembly.Load(relatedAssemblyName); + relatedAssemblies.Add(relatedAssembly); + continue; + } + catch (IOException) + { + // The assembly isn't already loaded. Patience, we'll attempt to load it from disk next. + } + var relatedAssemblyLocation = Path.Combine(assemblyDirectory, attribute.AssemblyFileName + ".dll"); if (!fileExists(relatedAssemblyLocation)) { @@ -106,7 +126,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationParts } } - var relatedAssembly = loadFile(relatedAssemblyLocation); + relatedAssembly = loadFile(relatedAssemblyLocation); relatedAssemblies.Add(relatedAssembly); } diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets index 277c0f0021..24865730c8 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets @@ -720,10 +720,12 @@ Copyright (c) .NET Foundation. All rights reserved. %(Filename)%(Extension) PreserveNewest + true %(Filename)%(Extension) PreserveNewest + true