diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/AssemblyItem.cs b/src/Razor/Microsoft.NET.Sdk.Razor/src/AssemblyItem.cs
new file mode 100644
index 0000000000..1f57029bf0
--- /dev/null
+++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/AssemblyItem.cs
@@ -0,0 +1,14 @@
+// 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.
+
+namespace Microsoft.AspNetCore.Razor.Tasks
+{
+ public class AssemblyItem
+ {
+ public string Path { get; set; }
+
+ public bool IsSystemReference { get; set; }
+
+ public string AssemblyName { get; set; }
+ }
+}
diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj b/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj
index ca4b3e0593..436cad2245 100644
--- a/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj
+++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj
@@ -1,7 +1,7 @@
Razor is a markup syntax for adding server-side logic to web pages. This package contains MSBuild support for Razor.
- netcoreapp3.0;netstandard2.0;net46
+ netcoreapp3.0;net46
Microsoft.NET.Sdk.Razor.Tasks
$(MSBuildProjectName).nuspec
@@ -17,8 +17,9 @@
+
-
+
@@ -54,7 +55,10 @@
-
+
+
+
+
diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/ReferenceResolver.cs b/src/Razor/Microsoft.NET.Sdk.Razor/src/ReferenceResolver.cs
new file mode 100644
index 0000000000..657e9432cf
--- /dev/null
+++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/ReferenceResolver.cs
@@ -0,0 +1,169 @@
+// 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;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection.Metadata;
+using System.Reflection.PortableExecutable;
+
+namespace Microsoft.AspNetCore.Razor.Tasks
+{
+ ///
+ /// Resolves assemblies that reference one of the specified "targetAssemblies" either directly or transitively.
+ ///
+ public class ReferenceResolver
+ {
+ private readonly HashSet _mvcAssemblies;
+ private readonly Dictionary _lookup = new Dictionary(StringComparer.Ordinal);
+
+ public ReferenceResolver(IReadOnlyList targetAssemblies, IReadOnlyList assemblyItems)
+ {
+ _mvcAssemblies = new HashSet(targetAssemblies, StringComparer.Ordinal);
+
+ foreach (var item in assemblyItems)
+ {
+ var classifiedItem = new ClassifiedAssemblyItem(item);
+ _lookup[item.AssemblyName] = classifiedItem;
+ }
+ }
+
+ public IReadOnlyList ResolveAssemblies()
+ {
+ var applicationParts = new List();
+ foreach (var item in _lookup)
+ {
+ var classification = Resolve(item.Value);
+ if (classification == DependencyClassification.ReferencesMvc)
+ {
+ applicationParts.Add(item.Key);
+ }
+
+ // It's not interesting for us to know if a dependency has a classification of MvcReference.
+ // All applications targeting the Microsoft.AspNetCore.App will have have a reference to Mvc.
+ }
+
+ return applicationParts;
+ }
+
+ private DependencyClassification Resolve(ClassifiedAssemblyItem classifiedItem)
+ {
+ if (classifiedItem.DependencyClassification != DependencyClassification.Unknown)
+ {
+ return classifiedItem.DependencyClassification;
+ }
+
+ if (classifiedItem.AssemblyItem == null)
+ {
+ // We encountered a dependency that isn't part of this assembly's dependency set. We'll see if it happens to be an MVC assembly.
+ // This might be useful in scenarios where the app does not have a framework reference at the entry point,
+ // but the transitive dependency does.
+ classifiedItem.DependencyClassification = _mvcAssemblies.Contains(classifiedItem.Name) ?
+ DependencyClassification.MvcReference :
+ DependencyClassification.DoesNotReferenceMvc;
+
+ return classifiedItem.DependencyClassification;
+ }
+
+ if (classifiedItem.AssemblyItem.IsSystemReference)
+ {
+ // We do not allow transitive references to MVC via a framework reference to count.
+ // e.g. depending on Microsoft.AspNetCore.SomeThingNewThatDependsOnMvc would not result in an assembly being treated as
+ // referencing MVC.
+ classifiedItem.DependencyClassification = _mvcAssemblies.Contains(classifiedItem.Name) ?
+ DependencyClassification.MvcReference :
+ DependencyClassification.DoesNotReferenceMvc;
+
+ return classifiedItem.DependencyClassification;
+ }
+
+ if (_mvcAssemblies.Contains(classifiedItem.Name))
+ {
+ classifiedItem.DependencyClassification = DependencyClassification.MvcReference;
+ return classifiedItem.DependencyClassification;
+ }
+
+ var dependencyClassification = DependencyClassification.DoesNotReferenceMvc;
+ foreach (var assemblyItem in GetReferences(classifiedItem.AssemblyItem.Path))
+ {
+ var classification = Resolve(assemblyItem);
+ if (classification == DependencyClassification.MvcReference || classification == DependencyClassification.ReferencesMvc)
+ {
+ dependencyClassification = DependencyClassification.ReferencesMvc;
+ break;
+ }
+ }
+
+ classifiedItem.DependencyClassification = dependencyClassification;
+ return dependencyClassification;
+ }
+
+ protected virtual IReadOnlyList GetReferences(string file)
+ {
+ try
+ {
+ using var peReader = new PEReader(File.OpenRead(file));
+ if (!peReader.HasMetadata)
+ {
+ return Array.Empty(); // not a managed assembly
+ }
+
+ var metadataReader = peReader.GetMetadataReader();
+
+ var assemblyItems = new List();
+ foreach (var handle in metadataReader.AssemblyReferences)
+ {
+ var reference = metadataReader.GetAssemblyReference(handle);
+ var referenceName = metadataReader.GetString(reference.Name);
+
+ if (_lookup.TryGetValue(referenceName, out var classifiedItem))
+ {
+ assemblyItems.Add(classifiedItem);
+ }
+ else
+ {
+ // A dependency references an item that isn't referenced by this project.
+ // We'll construct an item for so that we can calculate the classification based on it's name.
+ assemblyItems.Add(new ClassifiedAssemblyItem(referenceName));
+ }
+ }
+
+ return assemblyItems;
+ }
+ catch (BadImageFormatException)
+ {
+ // not a PE file, or invalid metadata
+ }
+
+ return Array.Empty(); // not a managed assembly
+ }
+
+ protected enum DependencyClassification
+ {
+ Unknown,
+ DoesNotReferenceMvc,
+ ReferencesMvc,
+ MvcReference,
+ }
+
+ protected class ClassifiedAssemblyItem
+ {
+ public ClassifiedAssemblyItem(AssemblyItem classifiedItem)
+ : this(classifiedItem.AssemblyName)
+ {
+ AssemblyItem = classifiedItem;
+ }
+
+ public ClassifiedAssemblyItem(string name)
+ {
+ Name = name;
+ }
+
+ public string Name { get; }
+
+ public AssemblyItem AssemblyItem { get; }
+
+ public DependencyClassification DependencyClassification { get; set; }
+ }
+ }
+}
diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/ResolveAssemblyWithReferences.cs b/src/Razor/Microsoft.NET.Sdk.Razor/src/ResolveAssemblyWithReferences.cs
new file mode 100644
index 0000000000..3727e01088
--- /dev/null
+++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/ResolveAssemblyWithReferences.cs
@@ -0,0 +1,55 @@
+// 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.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+
+namespace Microsoft.AspNetCore.Razor.Tasks
+{
+ public class FindAssembliesWithReferencesTo : Task
+ {
+ [Required]
+ public ITaskItem[] TargetAssemblyNames { get; set; }
+
+ [Required]
+ public ITaskItem[] Assemblies { get; set; }
+
+ [Output]
+ public string[] ResolvedAssemblies { get; set; }
+
+ public override bool Execute()
+ {
+ var referenceItems = new List();
+ foreach (var item in Assemblies)
+ {
+ const string FusionNameKey = "FusionName";
+ var fusionName = item.GetMetadata(FusionNameKey);
+ if (string.IsNullOrEmpty(fusionName))
+ {
+ Log.LogError($"Missing required metadata '{FusionNameKey}' for '{item.ItemSpec}.");
+ return false;
+ }
+
+ var assemblyName = new AssemblyName(fusionName).Name;
+ referenceItems.Add(new AssemblyItem
+ {
+ AssemblyName = assemblyName,
+ IsSystemReference = item.GetMetadata("IsSystemReference") == "true",
+ Path = item.ItemSpec,
+ });
+ }
+
+ var targetAssemblyNames = TargetAssemblyNames.Select(s => s.ItemSpec).ToList();
+
+ var provider = new ReferenceResolver(targetAssemblyNames, referenceItems);
+ var assemblyNames = provider.ResolveAssemblies();
+
+ ResolvedAssemblies = assemblyNames.ToArray();
+
+ return !Log.HasLoggedErrors;
+ }
+ }
+}
diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.MvcApplicationPartsDiscovery.targets b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.MvcApplicationPartsDiscovery.targets
new file mode 100644
index 0000000000..43a1fbc8db
--- /dev/null
+++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.MvcApplicationPartsDiscovery.targets
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+ true
+
+
+ _DiscoverMvcApplicationParts;
+ $(CoreCompileDependsOn);
+
+
+ <_MvcApplicationPartAttributeGeneratedFile>$(IntermediateOutputPath)$(TargetName).MvcApplicationPartsAssemblyInfo$(DefaultLanguageSourceExtension)
+
+
+
+
+
+ <_MvcAssemblyName Include="Microsoft.AspNetCore.Mvc" />
+ <_MvcAssemblyName Include="Microsoft.AspNetCore.Mvc.Abstractions" />
+ <_MvcAssemblyName Include="Microsoft.AspNetCore.Mvc.ApiExplorer" />
+ <_MvcAssemblyName Include="Microsoft.AspNetCore.Mvc.Core" />
+ <_MvcAssemblyName Include="Microsoft.AspNetCore.Mvc.Cors" />
+ <_MvcAssemblyName Include="Microsoft.AspNetCore.Mvc.DataAnnotations" />
+ <_MvcAssemblyName Include="Microsoft.AspNetCore.Mvc.Formatters.Json" />
+ <_MvcAssemblyName Include="Microsoft.AspNetCore.Mvc.Formatters.Xml" />
+ <_MvcAssemblyName Include="Microsoft.AspNetCore.Mvc.Localization" />
+ <_MvcAssemblyName Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" />
+ <_MvcAssemblyName Include="Microsoft.AspNetCore.Mvc.Razor" />
+ <_MvcAssemblyName Include="Microsoft.AspNetCore.Mvc.RazorPages" />
+ <_MvcAssemblyName Include="Microsoft.AspNetCore.Mvc.TagHelpers" />
+ <_MvcAssemblyName Include="Microsoft.AspNetCore.Mvc.ViewFeatures" />
+
+
+
+
+
+
+
+ <_MvcApplicationPartAttribute Include="Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute">
+ <_Parameter1>%(_ApplicationPartAssemblyNames.Identity)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 15d1fb8165..0a4d6a4a62 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
@@ -25,7 +25,7 @@ Copyright (c) .NET Foundation. All rights reserved.
$(MSBuildThisFileDirectory)..\..\
$(RazorSdkDirectoryRoot)tasks\
- <_RazorSdkTasksTFM Condition=" '$(MSBuildRuntimeType)' == 'Core'">netstandard2.0
+ <_RazorSdkTasksTFM Condition=" '$(MSBuildRuntimeType)' == 'Core'">netcoreapp3.0
<_RazorSdkTasksTFM Condition=" '$(_RazorSdkTasksTFM)' == ''">net46
$(RazorSdkBuildTasksDirectoryRoot)$(_RazorSdkTasksTFM)\Microsoft.NET.Sdk.Razor.Tasks.dll
@@ -335,6 +335,8 @@ Copyright (c) .NET Foundation. All rights reserved.
+
+
-
diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/test/ReferenceResolverTest.cs b/src/Razor/Microsoft.NET.Sdk.Razor/test/ReferenceResolverTest.cs
new file mode 100644
index 0000000000..7a24101947
--- /dev/null
+++ b/src/Razor/Microsoft.NET.Sdk.Razor/test/ReferenceResolverTest.cs
@@ -0,0 +1,181 @@
+// 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;
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Tasks
+{
+ public class ReferenceResolverTest
+ {
+ internal static readonly string[] MvcAssemblies = new[]
+ {
+ "Microsoft.AspNetCore.Mvc",
+ "Microsoft.AspNetCore.Mvc.Abstractions",
+ "Microsoft.AspNetCore.Mvc.ApiExplorer",
+ "Microsoft.AspNetCore.Mvc.Core",
+ "Microsoft.AspNetCore.Mvc.Cors",
+ "Microsoft.AspNetCore.Mvc.DataAnnotations",
+ "Microsoft.AspNetCore.Mvc.Formatters.Json",
+ "Microsoft.AspNetCore.Mvc.Formatters.Xml",
+ "Microsoft.AspNetCore.Mvc.Localization",
+ "Microsoft.AspNetCore.Mvc.NewtonsoftJson",
+ "Microsoft.AspNetCore.Mvc.Razor",
+ "Microsoft.AspNetCore.Mvc.RazorPages",
+ "Microsoft.AspNetCore.Mvc.TagHelpers",
+ "Microsoft.AspNetCore.Mvc.ViewFeatures",
+ };
+
+ [Fact]
+ public void Resolve_ReturnsEmptySequence_IfNoAssemblyReferencesMvc()
+ {
+ // Arrange
+ var resolver = new TestReferencesToMvcResolver(new[]
+ {
+ CreateAssemblyItem("Microsoft.AspNetCore.Blazor"),
+ CreateAssemblyItem("Microsoft.AspNetCore.Components"),
+ CreateAssemblyItem("Microsoft.JSInterop"),
+ CreateAssemblyItem("System.Net.Http"),
+ CreateAssemblyItem("System.Runtime"),
+ });
+
+ resolver.Add("Microsoft.AspNetCore.Blazor", "Microsoft.AspNetCore.Components", "Microsoft.JSInterop");
+ resolver.Add("Microsoft.AspNetCore.Components", "Microsoft.JSInterop", "System.Net.Http", "System.Runtime");
+ resolver.Add("System.Net.Http", "System.Runtime");
+
+ // Act
+ var assemblies = resolver.ResolveAssemblies();
+
+ // Assert
+ Assert.Empty(assemblies);
+ }
+
+ [Fact]
+ public void Resolve_ReturnsEmptySequence_IfNoDependencyReferencesMvc()
+ {
+ // Arrange
+ var resolver = new TestReferencesToMvcResolver(new[]
+ {
+ CreateAssemblyItem("MyApp.Models"),
+ CreateAssemblyItem("Microsoft.AspNetCore.Mvc", isSystemReference: true),
+ CreateAssemblyItem("Microsoft.AspNetCore.Hosting", isSystemReference: true),
+ CreateAssemblyItem("Microsoft.AspNetCore.HttpAbstractions", isSystemReference: true),
+ CreateAssemblyItem("Microsoft.AspNetCore.KestrelHttpServer", isSystemReference: true),
+ CreateAssemblyItem("Microsoft.AspNetCore.StaticFiles", isSystemReference: true),
+ CreateAssemblyItem("Microsoft.Extensions.Primitives", isSystemReference: true),
+ CreateAssemblyItem("System.Net.Http", isSystemReference: true),
+ CreateAssemblyItem("Microsoft.EntityFrameworkCore"),
+ });
+
+ resolver.Add("MyApp.Models", "Microsoft.EntityFrameworkCore");
+ resolver.Add("Microsoft.AspNetCore.Mvc", "Microsoft.AspNetCore.HttpAbstractions");
+ resolver.Add("Microsoft.AspNetCore.KestrelHttpServer", "Microsoft.AspNetCore.Hosting", "Microsoft.AspNetCore.HttpAbstractions");
+ resolver.Add("Microsoft.AspNetCore.StaticFiles", "Microsoft.AspNetCore.HttpAbstractions", "Microsoft.Extensions.Primitives");
+ resolver.Add("Microsoft.AspNetCore.Hosting", "Microsoft.AspNetCore.HttpAbstractions");
+ resolver.Add("Microsoft.AspNetCore.HttpAbstractions", "Microsoft.Extensions.Primitives");
+
+ // Act
+ var assemblies = resolver.ResolveAssemblies();
+
+ // Assert
+ Assert.Empty(assemblies);
+ }
+
+ [Fact]
+ public void Resolve_ReturnsReferences_ThatReferenceMvc()
+ {
+ // Arrange
+ var resolver = new TestReferencesToMvcResolver(new[]
+ {
+ CreateAssemblyItem("Microsoft.AspNetCore.Mvc", isSystemReference: true),
+ CreateAssemblyItem("Microsoft.AspNetCore.Mvc.TagHelpers", isSystemReference: true),
+ CreateAssemblyItem("MyTagHelpers"),
+ CreateAssemblyItem("MyControllers"),
+ CreateAssemblyItem("MyApp.Models"),
+ CreateAssemblyItem("Microsoft.AspNetCore.Hosting", isSystemReference: true),
+ CreateAssemblyItem("Microsoft.AspNetCore.HttpAbstractions", isSystemReference: true),
+ CreateAssemblyItem("Microsoft.AspNetCore.KestrelHttpServer", isSystemReference: true),
+ CreateAssemblyItem("Microsoft.AspNetCore.StaticFiles", isSystemReference: true),
+ CreateAssemblyItem("Microsoft.Extensions.Primitives", isSystemReference: true),
+ CreateAssemblyItem("Microsoft.EntityFrameworkCore"),
+ });
+
+ resolver.Add("MyTagHelpers", "Microsoft.AspNetCore.Mvc.TagHelpers");
+ resolver.Add("MyControllers", "Microsoft.AspNetCore.Mvc");
+ resolver.Add("MyApp.Models", "Microsoft.EntityFrameworkCore");
+ resolver.Add("Microsoft.AspNetCore.Mvc", "Microsoft.AspNetCore.HttpAbstractions", "Microsoft.AspNetCore.Mvc.TagHelpers");
+ resolver.Add("Microsoft.AspNetCore.KestrelHttpServer", "Microsoft.AspNetCore.Hosting", "Microsoft.AspNetCore.HttpAbstractions");
+ resolver.Add("Microsoft.AspNetCore.StaticFiles", "Microsoft.AspNetCore.HttpAbstractions", "Microsoft.Extensions.Primitives");
+ resolver.Add("Microsoft.AspNetCore.Hosting", "Microsoft.AspNetCore.HttpAbstractions");
+ resolver.Add("Microsoft.AspNetCore.HttpAbstractions", "Microsoft.Extensions.Primitives");
+
+ // Act
+ var assemblies = resolver.ResolveAssemblies();
+
+ // Assert
+ Assert.Equal(new[] { "MyControllers", "MyTagHelpers" }, assemblies.OrderBy(a => a));
+ }
+
+ [Fact]
+ public void Resolve_ReturnsItemsThatTransitivelyReferenceMvc()
+ {
+ // Arrange
+ var resolver = new TestReferencesToMvcResolver(new[]
+ {
+ CreateAssemblyItem("MyCMS"),
+ CreateAssemblyItem("MyCMS.Core"),
+ CreateAssemblyItem("Microsoft.AspNetCore.Mvc.ViewFeatures", isSystemReference: true),
+ });
+
+ resolver.Add("MyCMS", "MyCMS.Core");
+ resolver.Add("MyCMS.Core", "Microsoft.AspNetCore.Mvc.ViewFeatures");
+
+
+ // Act
+ var assemblies = resolver.ResolveAssemblies();
+
+ // Assert
+ Assert.Equal(new[] { "MyCMS", "MyCMS.Core" }, assemblies.OrderBy(a => a));
+ }
+
+ public AssemblyItem CreateAssemblyItem(string name, bool isSystemReference = false)
+ {
+ return new AssemblyItem
+ {
+ AssemblyName = name,
+ IsSystemReference = isSystemReference,
+ Path = name,
+ };
+ }
+
+ private class TestReferencesToMvcResolver : ReferenceResolver
+ {
+ private readonly Dictionary> _references = new Dictionary>();
+ private readonly Dictionary _lookup;
+
+ public TestReferencesToMvcResolver(AssemblyItem[] referenceItems)
+ : base(MvcAssemblies, referenceItems)
+ {
+ _lookup = referenceItems.ToDictionary(r => r.AssemblyName, r => new ClassifiedAssemblyItem(r));
+ }
+
+ public void Add(string assembly, params string[] references)
+ {
+ var assemblyItems = references.Select(r => _lookup[r]).ToList();
+ _references[assembly] = assemblyItems;
+ }
+
+ protected override IReadOnlyList GetReferences(string file)
+ {
+ if (_references.TryGetValue(file, out var result))
+ {
+ return result;
+ }
+
+ return Array.Empty();
+ }
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.ApplicationParts/ApplicationPartAttribute.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.ApplicationParts/ApplicationPartAttribute.cs
new file mode 100644
index 0000000000..136cb7cba6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Mvc.ApplicationParts/ApplicationPartAttribute.cs
@@ -0,0 +1,13 @@
+// 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;
+
+namespace Microsoft.AspNetCore.Mvc.ApplicationParts
+{
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
+ public class ApplicationPartAttribute : Attribute
+ {
+ public ApplicationPartAttribute(string assemblyName) {}
+ }
+}
diff --git a/src/Razor/test/testassets/Directory.Build.props b/src/Razor/test/testassets/Directory.Build.props
index 3f73654c48..4250269a09 100644
--- a/src/Razor/test/testassets/Directory.Build.props
+++ b/src/Razor/test/testassets/Directory.Build.props
@@ -23,6 +23,11 @@
false
+
+
+ <_MvcAssemblyName Include="Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib" />
+
+
diff --git a/src/Razor/test/testassets/LargeProject/LargeProject.csproj b/src/Razor/test/testassets/LargeProject/LargeProject.csproj
index 364466f735..b2b6b1019a 100644
--- a/src/Razor/test/testassets/LargeProject/LargeProject.csproj
+++ b/src/Razor/test/testassets/LargeProject/LargeProject.csproj
@@ -10,7 +10,6 @@
-->
true
- <_ReferencesAspNetCoreApp>true