diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/AssemblyPart.cs b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/AssemblyPart.cs
index d3b0f0fc8a..a091013710 100644
--- a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/AssemblyPart.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/AssemblyPart.cs
@@ -15,24 +15,8 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationParts
public class AssemblyPart :
ApplicationPart,
IApplicationPartTypeProvider,
- ICompilationReferencesProvider,
- IViewsProvider
+ ICompilationReferencesProvider
{
- ///
- /// Gets the suffix for the view assembly.
- ///
- public static readonly string PrecompiledViewsAssemblySuffix = ".PrecompiledViews";
-
- ///
- /// Gets the namespace for the type in the view assembly.
- ///
- public static readonly string ViewInfoContainerNamespace = "AspNetCore";
-
- ///
- /// Gets the type name for the view collection type in the view assembly.
- ///
- public static readonly string ViewInfoContainerTypeName = "__PrecompiledViewCollection";
-
///
/// Initalizes a new instance.
///
@@ -60,27 +44,6 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationParts
///
public IEnumerable Types => Assembly.DefinedTypes;
- ///
- public IEnumerable Views
- {
- get
- {
- var precompiledAssemblyName = new AssemblyName(Assembly.FullName);
- precompiledAssemblyName.Name = precompiledAssemblyName.Name + PrecompiledViewsAssemblySuffix;
-
- var typeName = $"{ViewInfoContainerNamespace}.{ViewInfoContainerTypeName},{precompiledAssemblyName}";
- var viewInfoContainerTypeName = Type.GetType(typeName);
-
- if (viewInfoContainerTypeName == null)
- {
- return null;
- }
-
- var precompiledViews = (ViewInfoContainer)Activator.CreateInstance(viewInfoContainerTypeName);
- return precompiledViews.ViewInfos;
- }
- }
-
///
public IEnumerable GetReferencePaths()
{
diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/IViewsProvider.cs b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/IViewsProvider.cs
deleted file mode 100644
index 862401593e..0000000000
--- a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/IViewsProvider.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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;
-
-namespace Microsoft.AspNetCore.Mvc.ApplicationParts
-{
- ///
- /// Exposes a sequence of views associated with an .
- ///
- public interface IViewsProvider
- {
- ///
- /// Gets the sequence of .
- ///
- IEnumerable Views { get; }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/ViewInfo.cs b/src/Microsoft.AspNetCore.Mvc.Razor/Compilation/ViewInfo.cs
similarity index 100%
rename from src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/ViewInfo.cs
rename to src/Microsoft.AspNetCore.Mvc.Razor/Compilation/ViewInfo.cs
diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/ViewInfoContainer.cs b/src/Microsoft.AspNetCore.Mvc.Razor/Compilation/ViewInfoContainer.cs
similarity index 100%
rename from src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/ViewInfoContainer.cs
rename to src/Microsoft.AspNetCore.Mvc.Razor/Compilation/ViewInfoContainer.cs
diff --git a/src/Microsoft.AspNetCore.Mvc.Razor/Compilation/ViewsFeatureProvider.cs b/src/Microsoft.AspNetCore.Mvc.Razor/Compilation/ViewsFeatureProvider.cs
index 360992886d..129df93ec5 100644
--- a/src/Microsoft.AspNetCore.Mvc.Razor/Compilation/ViewsFeatureProvider.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Razor/Compilation/ViewsFeatureProvider.cs
@@ -1,8 +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.
+using System;
using System.Collections.Generic;
using System.Linq;
+using System.Reflection;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
namespace Microsoft.AspNetCore.Mvc.Razor.Compilation
@@ -12,20 +14,53 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Compilation
///
public class ViewsFeatureProvider : IApplicationFeatureProvider
{
+ ///
+ /// Gets the suffix for the view assembly.
+ ///
+ public static readonly string PrecompiledViewsAssemblySuffix = ".PrecompiledViews";
+
+ ///
+ /// Gets the namespace for the type in the view assembly.
+ ///
+ public static readonly string ViewInfoContainerNamespace = "AspNetCore";
+
+ ///
+ /// Gets the type name for the view collection type in the view assembly.
+ ///
+ public static readonly string ViewInfoContainerTypeName = "__PrecompiledViewCollection";
+
///
public void PopulateFeature(IEnumerable parts, ViewsFeature feature)
{
- foreach (var provider in parts.OfType())
+ foreach (var assemblyPart in parts.OfType())
{
- var precompiledViews = provider.Views;
- if (precompiledViews != null)
+ var viewInfoContainerTypeName = GetViewInfoContainerType(assemblyPart);
+ if (viewInfoContainerTypeName == null)
{
- foreach (var viewInfo in precompiledViews)
- {
- feature.Views[viewInfo.Path] = viewInfo.Type;
- }
+ continue;
+ }
+
+ var viewContainer = (ViewInfoContainer)Activator.CreateInstance(viewInfoContainerTypeName);
+
+ foreach (var item in viewContainer.ViewInfos)
+ {
+ feature.Views[item.Path] = item.Type;
}
}
}
+
+ ///
+ /// Gets the type of for the specified .
+ ///
+ /// The .
+ /// The .
+ protected virtual Type GetViewInfoContainerType(AssemblyPart assemblyPart)
+ {
+ var precompiledAssemblyName = new AssemblyName(assemblyPart.Assembly.FullName);
+ precompiledAssemblyName.Name = precompiledAssemblyName.Name + PrecompiledViewsAssemblySuffix;
+
+ var typeName = $"{ViewInfoContainerNamespace}.{ViewInfoContainerTypeName},{precompiledAssemblyName}";
+ return Type.GetType(typeName);
+ }
}
}
diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Test/Compilation/ViewsFeatureProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Test/Compilation/ViewsFeatureProviderTest.cs
index 77250475e1..081ff63254 100644
--- a/test/Microsoft.AspNetCore.Mvc.Razor.Test/Compilation/ViewsFeatureProviderTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Razor.Test/Compilation/ViewsFeatureProviderTest.cs
@@ -1,9 +1,11 @@
// 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 System.Reflection;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
-using Moq;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Razor.Compilation
@@ -18,49 +20,89 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Compilation
applicationPartManager.ApplicationParts.Add(
new AssemblyPart(typeof(ViewsFeatureProviderTest).GetTypeInfo().Assembly));
applicationPartManager.FeatureProviders.Add(new ViewsFeatureProvider());
- var feature = new MetadataReferenceFeature();
+ var feature = new ViewsFeature();
// Act
applicationPartManager.PopulateFeature(feature);
// Assert
- Assert.Empty(feature.MetadataReferences);
+ Assert.Empty(feature.Views);
}
[Fact]
public void PopulateFeature_ReturnsViewsFromAllAvailableApplicationParts()
{
// Arrange
- var applicationPart1 = new Mock();
- var viewsProvider1 = applicationPart1
- .As()
- .SetupGet(p => p.Views)
- .Returns(new[]
- {
- new ViewInfo("/Views/test/Index.cshtml", typeof(object))
- });
- var applicationPart2 = new Mock();
- var viewsProvider2 = applicationPart2
- .As()
- .SetupGet(p => p.Views)
- .Returns(new[]
- {
- new ViewInfo("/Areas/Admin/Views/Index.cshtml", typeof(string)),
- new ViewInfo("/Areas/Admin/Views/About.cshtml", typeof(int))
- });
-
+ var part1 = new AssemblyPart(typeof(object).GetTypeInfo().Assembly);
+ var part2 = new AssemblyPart(GetType().GetTypeInfo().Assembly);
+ var featureProvider = new TestableViewsFeatureProvider(new Dictionary
+ {
+ { part1, typeof(ViewInfoContainer1) },
+ { part2, typeof(ViewInfoContainer2) },
+ });
var applicationPartManager = new ApplicationPartManager();
- applicationPartManager.ApplicationParts.Add(applicationPart1.Object);
- applicationPartManager.ApplicationParts.Add(applicationPart2.Object);
- applicationPartManager.FeatureProviders.Add(new ViewsFeatureProvider());
- var feature = new MetadataReferenceFeature();
+ applicationPartManager.ApplicationParts.Add(part1);
+ applicationPartManager.ApplicationParts.Add(part2);
+ applicationPartManager.FeatureProviders.Add(featureProvider);
+ var feature = new ViewsFeature();
// Act
applicationPartManager.PopulateFeature(feature);
// Assert
- Assert.Empty(feature.MetadataReferences);
+ Assert.Collection(feature.Views.OrderBy(f => f.Key, StringComparer.Ordinal),
+ view =>
+ {
+ Assert.Equal("/Areas/Admin/Views/About.cshtml", view.Key);
+ Assert.Equal(typeof(int), view.Value);
+ },
+ view =>
+ {
+ Assert.Equal("/Areas/Admin/Views/Index.cshtml", view.Key);
+ Assert.Equal(typeof(string), view.Value);
+ },
+ view =>
+ {
+ Assert.Equal("/Views/test/Index.cshtml", view.Key);
+ Assert.Equal(typeof(object), view.Value);
+ });
+ }
+
+ private class TestableViewsFeatureProvider : ViewsFeatureProvider
+ {
+ private readonly Dictionary _containerLookup;
+
+ public TestableViewsFeatureProvider(Dictionary containerLookup)
+ {
+ _containerLookup = containerLookup;
+ }
+
+ protected override Type GetViewInfoContainerType(AssemblyPart assemblyPart) =>
+ _containerLookup[assemblyPart];
+ }
+
+ private class ViewInfoContainer1 : ViewInfoContainer
+ {
+ public ViewInfoContainer1()
+ : base(new[]
+ {
+ new ViewInfo("/Views/test/Index.cshtml", typeof(object))
+ })
+ {
+ }
+ }
+
+ private class ViewInfoContainer2 : ViewInfoContainer
+ {
+ public ViewInfoContainer2()
+ : base(new[]
+ {
+ new ViewInfo("/Areas/Admin/Views/Index.cshtml", typeof(string)),
+ new ViewInfo("/Areas/Admin/Views/About.cshtml", typeof(int))
+ })
+ {
+ }
}
}
}