diff --git a/Directory.Build.targets b/Directory.Build.targets
index 3909b2ee75..9f6393d132 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -98,6 +98,10 @@
true
+
+
+
+
diff --git a/src/Framework/test/TargetingPackTests.cs b/src/Framework/test/TargetingPackTests.cs
index d1c7baf893..3d3fedc85a 100644
--- a/src/Framework/test/TargetingPackTests.cs
+++ b/src/Framework/test/TargetingPackTests.cs
@@ -5,6 +5,10 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Reflection;
+using System.Reflection.Metadata;
+using System.Reflection.PortableExecutable;
+using System.Runtime.CompilerServices;
using Newtonsoft.Json.Linq;
using Xunit;
using Xunit.Abstractions;
@@ -24,6 +28,36 @@ namespace Microsoft.AspNetCore
_targetingPackRoot = Path.Combine(TestData.GetTestDataValue("TargetingPackLayoutRoot"), "packs", "Microsoft.AspNetCore.App.Ref", TestData.GetTestDataValue("TargetingPackVersion"));
}
+ [Fact]
+ public void AssembliesAreReferenceAssemblies()
+ {
+ IEnumerable dlls = Directory.GetFiles(_targetingPackRoot, "*.dll", SearchOption.AllDirectories);
+ Assert.NotEmpty(dlls);
+
+ // Workaround https://github.com/aspnet/AspNetCore/issues/11206
+ dlls = dlls.Where(d => !d.Contains("System.IO.Pipelines"));
+
+ Assert.All(dlls, path =>
+ {
+ var assemblyName = AssemblyName.GetAssemblyName(path);
+ using var fileStream = File.OpenRead(path);
+ using var peReader = new PEReader(fileStream, PEStreamOptions.Default);
+ var reader = peReader.GetMetadataReader(MetadataReaderOptions.Default);
+ var assemblyDefinition = reader.GetAssemblyDefinition();
+ var hasRefAssemblyAttribute = assemblyDefinition.GetCustomAttributes().Any(attr =>
+ {
+ var attribute = reader.GetCustomAttribute(attr);
+ var attributeConstructor = reader.GetMemberReference((MemberReferenceHandle)attribute.Constructor);
+ var attributeType = reader.GetTypeReference((TypeReferenceHandle)attributeConstructor.Parent);
+ return reader.StringComparer.Equals(attributeType.Namespace, typeof(ReferenceAssemblyAttribute).Namespace)
+ && reader.StringComparer.Equals(attributeType.Name, nameof(ReferenceAssemblyAttribute));
+ });
+
+ Assert.True(hasRefAssemblyAttribute, $"{path} should have {nameof(ReferenceAssemblyAttribute)}");
+ Assert.Equal(ProcessorArchitecture.None, assemblyName.ProcessorArchitecture);
+ });
+ }
+
[Fact]
public void PlatformManifestListsAllFiles()
{
diff --git a/src/Mvc/Mvc.Analyzers/test/Mvc.Analyzers.Test.csproj b/src/Mvc/Mvc.Analyzers/test/Mvc.Analyzers.Test.csproj
index 1854d54a9d..94f546a1cd 100644
--- a/src/Mvc/Mvc.Analyzers/test/Mvc.Analyzers.Test.csproj
+++ b/src/Mvc/Mvc.Analyzers/test/Mvc.Analyzers.Test.csproj
@@ -22,7 +22,7 @@
-
+
diff --git a/src/Mvc/Mvc.Api.Analyzers/test/Mvc.Api.Analyzers.Test.csproj b/src/Mvc/Mvc.Api.Analyzers/test/Mvc.Api.Analyzers.Test.csproj
index c81ef1db1d..285dfc7866 100644
--- a/src/Mvc/Mvc.Api.Analyzers/test/Mvc.Api.Analyzers.Test.csproj
+++ b/src/Mvc/Mvc.Api.Analyzers/test/Mvc.Api.Analyzers.Test.csproj
@@ -20,7 +20,7 @@
-
+
diff --git a/src/Shared/ReferenceAssemblyInfo.cs b/src/Shared/ReferenceAssemblyInfo.cs
new file mode 100644
index 0000000000..5906a89a12
--- /dev/null
+++ b/src/Shared/ReferenceAssemblyInfo.cs
@@ -0,0 +1,10 @@
+// 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.
+
+// Reference assemblies should have the ReferenceAssemblyAttribute.
+[assembly:System.Runtime.CompilerServices.ReferenceAssembly]
+
+// Reference assemblies should have the 0x70 flag which prevents them from loading.
+// This flag sets AssemblyName.ProcessorArchitecture to None. There is no public API for this.
+// Cref https://github.com/dotnet/coreclr/blob/64ca544ecf55490675e72b853e98ebc8cc75a4fe/src/System.Private.CoreLib/src/System/Reflection/AssemblyName.CoreCLR.cs#L74
+[assembly:System.Reflection.AssemblyFlags((System.Reflection.AssemblyNameFlags)0x70)]