Skip to content

Commit 2f0cf8d

Browse files
committed
Add support for views + SingleFileExe
1 parent 2d6fd45 commit 2f0cf8d

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

src/Mvc/Mvc.Core/src/ApplicationParts/RelatedAssemblyAttribute.cs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
55
using System.Collections.Generic;
66
using System.IO;
77
using System.Linq;
88
using System.Reflection;
9+
using System.Runtime.Loader;
910
using Microsoft.AspNetCore.Mvc.Core;
1011

1112
namespace Microsoft.AspNetCore.Mvc.ApplicationParts
@@ -16,7 +17,8 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationParts
1617
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
1718
public sealed class RelatedAssemblyAttribute : Attribute
1819
{
19-
private static readonly Func<string, Assembly> AssemblyLoadFileDelegate = Assembly.LoadFile;
20+
private static readonly Func<string, Assembly> LoadFromAssemblyPathDelegate =
21+
AssemblyLoadContext.GetLoadContext(typeof(RelatedAssemblyAttribute).Assembly).LoadFromAssemblyPath;
2022

2123
/// <summary>
2224
/// Initializes a new instance of <see cref="RelatedAssemblyAttribute"/>.
@@ -50,7 +52,7 @@ public static IReadOnlyList<Assembly> GetRelatedAssemblies(Assembly assembly, bo
5052
throw new ArgumentNullException(nameof(assembly));
5153
}
5254

53-
return GetRelatedAssemblies(assembly, throwOnError, File.Exists, AssemblyLoadFileDelegate);
55+
return GetRelatedAssemblies(assembly, throwOnError, File.Exists, LoadFromAssemblyPathDelegate);
5456
}
5557

5658
internal static IReadOnlyList<Assembly> GetRelatedAssemblies(
@@ -66,7 +68,7 @@ internal static IReadOnlyList<Assembly> GetRelatedAssemblies(
6668

6769
// MVC will specifically look for related parts in the same physical directory as the assembly.
6870
// No-op if the assembly does not have a location.
69-
if (assembly.IsDynamic || string.IsNullOrEmpty(assembly.Location))
71+
if (assembly.IsDynamic)
7072
{
7173
return Array.Empty<Assembly>();
7274
}
@@ -78,8 +80,10 @@ internal static IReadOnlyList<Assembly> GetRelatedAssemblies(
7880
}
7981

8082
var assemblyName = assembly.GetName().Name;
81-
var assemblyLocation = assembly.Location;
82-
var assemblyDirectory = Path.GetDirectoryName(assemblyLocation);
83+
// 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
84+
var assemblyDirectory = string.IsNullOrEmpty(assembly.Location) ?
85+
AppContext.BaseDirectory :
86+
Path.GetDirectoryName(assembly.Location);
8387

8488
var relatedAssemblies = new List<Assembly>();
8589
for (var i = 0; i < attributes.Length; i++)
@@ -91,6 +95,22 @@ internal static IReadOnlyList<Assembly> GetRelatedAssemblies(
9195
Resources.FormatRelatedAssemblyAttribute_AssemblyCannotReferenceSelf(nameof(RelatedAssemblyAttribute), assemblyName));
9296
}
9397

98+
var relatedAssemblyName = new AssemblyName(attribute.AssemblyFileName);
99+
Assembly relatedAssembly;
100+
try
101+
{
102+
// Perform a cursory check to determine if the Assembly has already been loaded
103+
// before going to disk. In the ordinary case, related parts that are part of
104+
// application's reference closure should already be loaded.
105+
relatedAssembly = Assembly.Load(relatedAssemblyName);
106+
relatedAssemblies.Add(relatedAssembly);
107+
continue;
108+
}
109+
catch (IOException)
110+
{
111+
// The assembly isn't already loaded. Patience, we'll attempt to load it from disk next.
112+
}
113+
94114
var relatedAssemblyLocation = Path.Combine(assemblyDirectory, attribute.AssemblyFileName + ".dll");
95115
if (!fileExists(relatedAssemblyLocation))
96116
{
@@ -106,7 +126,7 @@ internal static IReadOnlyList<Assembly> GetRelatedAssemblies(
106126
}
107127
}
108128

109-
var relatedAssembly = loadFile(relatedAssemblyLocation);
129+
relatedAssembly = loadFile(relatedAssemblyLocation);
110130
relatedAssemblies.Add(relatedAssembly);
111131
}
112132

src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,10 +720,12 @@ Copyright (c) .NET Foundation. All rights reserved.
720720
<AllPublishItemsFullPathWithTargetPath Include="@(RazorIntermediateAssembly->'%(FullPath)')">
721721
<TargetPath>%(Filename)%(Extension)</TargetPath>
722722
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
723+
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
723724
</AllPublishItemsFullPathWithTargetPath>
724725
<AllPublishItemsFullPathWithTargetPath Include="@(_RazorDebugSymbolsIntermediatePath->'%(FullPath)')">
725726
<TargetPath>%(Filename)%(Extension)</TargetPath>
726727
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
728+
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
727729
</AllPublishItemsFullPathWithTargetPath>
728730
</ItemGroup>
729731

0 commit comments

Comments
 (0)