Skip to content
This repository was archived by the owner on Dec 14, 2018. It is now read-only.

Commit 8d9c161

Browse files
committed
Fix #6479 - remove IFileProvider constructor
The RazorProject implementation used by MVC at runtime has a constructor that takes an IFileProvider (used by tests). This causes ambiguities when a user registers an IFileProvider in DI. Cleaning up tests to use a mock instead of the file provider directly
1 parent a23307e commit 8d9c161

File tree

9 files changed

+82
-48
lines changed

9 files changed

+82
-48
lines changed

samples/MvcSandbox/Startup.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
using Microsoft.AspNetCore.Antiforgery;
66
using Microsoft.AspNetCore.Builder;
77
using Microsoft.AspNetCore.Hosting;
8+
using Microsoft.AspNetCore.Mvc.Razor.Internal;
9+
using Microsoft.AspNetCore.Razor.Language;
810
using Microsoft.Extensions.DependencyInjection;
11+
using Microsoft.Extensions.FileProviders;
912
using Microsoft.Extensions.Logging;
1013
using Microsoft.Extensions.Options;
1114

@@ -17,6 +20,7 @@ public class Startup
1720
public void ConfigureServices(IServiceCollection services)
1821
{
1922
services.AddMvc();
23+
services.AddSingleton<IFileProvider>(new PhysicalFileProvider(Path.GetFullPath(".")));
2024

2125
services.Insert(0, ServiceDescriptor.Singleton(
2226
typeof(IConfigureOptions<AntiforgeryOptions>),

src/Microsoft.AspNetCore.Mvc.Razor/Internal/FileProviderRazorProject.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ public class FileProviderRazorProject : RazorProject
1515
private readonly IFileProvider _provider;
1616

1717
public FileProviderRazorProject(IRazorViewEngineFileProviderAccessor accessor)
18-
: this(accessor.FileProvider)
1918
{
20-
}
19+
if (accessor == null)
20+
{
21+
throw new ArgumentNullException(nameof(accessor));
22+
}
2123

22-
public FileProviderRazorProject(IFileProvider provider)
23-
{
24-
_provider = provider;
24+
_provider = accessor.FileProvider;
2525
}
2626

2727
public override RazorProjectItem GetItem(string path)

test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/CompilerFailedExceptionFactoryTest.cs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Microsoft.AspNetCore.Razor.Language;
88
using Microsoft.CodeAnalysis;
99
using Microsoft.CodeAnalysis.Text;
10+
using Moq;
1011
using Xunit;
1112

1213
namespace Microsoft.AspNetCore.Mvc.Razor.Internal
@@ -19,9 +20,12 @@ public void GetCompilationFailedResult_ReadsRazorErrorsFromPage()
1920
// Arrange
2021
var viewPath = "/Views/Home/Index.cshtml";
2122
var razorEngine = RazorEngine.Create();
23+
2224
var fileProvider = new TestFileProvider();
2325
fileProvider.AddFile(viewPath, "<span name=\"@(User.Id\">");
24-
var razorProject = new FileProviderRazorProject(fileProvider);
26+
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);
27+
28+
var razorProject = new FileProviderRazorProject(accessor);
2529

2630
var templateEngine = new MvcRazorTemplateEngine(razorEngine, razorProject);
2731
var codeDocument = templateEngine.CreateCodeDocument(viewPath);
@@ -48,13 +52,16 @@ public void GetCompilationFailedResult_UsesPhysicalPath()
4852
// Arrange
4953
var viewPath = "/Views/Home/Index.cshtml";
5054
var physicalPath = @"x:\myapp\views\home\index.cshtml";
51-
var razorEngine = RazorEngine.Create();
55+
5256
var fileProvider = new TestFileProvider();
5357
var file = fileProvider.AddFile(viewPath, "<span name=\"@(User.Id\">");
5458
file.PhysicalPath = physicalPath;
55-
var razorProject = new FileProviderRazorProject(fileProvider);
59+
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);
5660

61+
var razorEngine = RazorEngine.Create();
62+
var razorProject = new FileProviderRazorProject(accessor);
5763
var templateEngine = new MvcRazorTemplateEngine(razorEngine, razorProject);
64+
5865
var codeDocument = templateEngine.CreateCodeDocument(viewPath);
5966

6067
// Act
@@ -82,9 +89,11 @@ public void GetCompilationFailedResult_ReadsContentFromSourceDocuments()
8289
var razorEngine = RazorEngine.Create();
8390
var fileProvider = new TestFileProvider();
8491
fileProvider.AddFile(viewPath, fileContent);
85-
var razorProject = new FileProviderRazorProject(fileProvider);
92+
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);
8693

94+
var razorProject = new FileProviderRazorProject(accessor);
8795
var templateEngine = new MvcRazorTemplateEngine(razorEngine, razorProject);
96+
8897
var codeDocument = templateEngine.CreateCodeDocument(viewPath);
8998

9099
// Act
@@ -105,13 +114,14 @@ public void GetCompilationFailedResult_ReadsContentFromImports()
105114
var fileContent = "@ ";
106115
var importsContent = "@(abc";
107116

108-
var razorEngine = RazorEngine.Create();
109117
var fileProvider = new TestFileProvider();
110118
fileProvider.AddFile(viewPath, fileContent);
111119
var importsFile = fileProvider.AddFile("/Views/_MyImports.cshtml", importsContent);
112120
importsFile.PhysicalPath = importsFilePath;
113-
var razorProject = new FileProviderRazorProject(fileProvider);
121+
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);
114122

123+
var razorEngine = RazorEngine.Create();
124+
var razorProject = new FileProviderRazorProject(accessor);
115125
var templateEngine = new MvcRazorTemplateEngine(razorEngine, razorProject)
116126
{
117127
Options =

test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/FileProviderRazorProjectTest.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Linq;
55
using Microsoft.Extensions.FileProviders;
6+
using Moq;
67
using Xunit;
78

89
namespace Microsoft.AspNetCore.Mvc.Razor.Internal
@@ -18,7 +19,9 @@ public void EnumerateFiles_ReturnsEmptySequenceIfNoCshtmlFilesArePresent()
1819
var file2 = fileProvider.AddFile("File2.js", "content");
1920
fileProvider.AddDirectoryContent("/", new IFileInfo[] { file1, file2 });
2021

21-
var razorProject = new FileProviderRazorProject(fileProvider);
22+
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);
23+
24+
var razorProject = new FileProviderRazorProject(accessor);
2225

2326
// Act
2427
var razorFiles = razorProject.EnumerateItems("/");
@@ -37,7 +40,9 @@ public void EnumerateFiles_ReturnsCshtmlFiles()
3740
var file3 = fileProvider.AddFile("File3.cshtml", "content");
3841
fileProvider.AddDirectoryContent("/", new IFileInfo[] { file1, file2, file3 });
3942

40-
var razorProject = new FileProviderRazorProject(fileProvider);
43+
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);
44+
45+
var razorProject = new FileProviderRazorProject(accessor);
4146

4247
// Act
4348
var razorFiles = razorProject.EnumerateItems("/");
@@ -76,7 +81,9 @@ public void EnumerateFiles_IteratesOverAllCshtmlUnderRoot()
7681
fileProvider.AddDirectoryContent("/Level1-Dir2", new IFileInfo[] { file5 });
7782
fileProvider.AddDirectoryContent("/Level1/Level2", new IFileInfo[0]);
7883

79-
var razorProject = new FileProviderRazorProject(fileProvider);
84+
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);
85+
86+
var razorProject = new FileProviderRazorProject(accessor);
8087

8188
// Act
8289
var razorFiles = razorProject.EnumerateItems("/");
@@ -117,7 +124,9 @@ public void EnumerateFiles_IteratesOverAllCshtmlUnderPath()
117124
fileProvider.AddDirectoryContent("/Level1-Dir2", new IFileInfo[] { file5 });
118125
fileProvider.AddDirectoryContent("/Level1/Level2", new IFileInfo[0]);
119126

120-
var razorProject = new FileProviderRazorProject(fileProvider);
127+
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);
128+
129+
var razorProject = new FileProviderRazorProject(accessor);
121130

122131
// Act
123132
var razorFiles = razorProject.EnumerateItems("/Level1-Dir1");

test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/RazorViewCompilerProviderTest.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,19 @@ public void GetCompiler_ThrowsIfNullFileProvider()
2222
$"not be empty. At least one '{typeof(IFileProvider).FullName}' is required to locate a view for " +
2323
"rendering.";
2424
var fileProvider = new NullFileProvider();
25-
var accessor = new Mock<IRazorViewEngineFileProviderAccessor>();
26-
var applicationManager = new ApplicationPartManager();
25+
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);
26+
27+
var partManager = new ApplicationPartManager();
2728
var options = new TestOptionsManager<RazorViewEngineOptions>();
28-
var referenceManager = new DefaultRazorReferenceManager(applicationManager, options);
29-
accessor.Setup(a => a.FileProvider).Returns(fileProvider);
29+
30+
var referenceManager = new DefaultRazorReferenceManager(partManager, options);
31+
3032
var provider = new RazorViewCompilerProvider(
31-
applicationManager,
32-
new RazorTemplateEngine(RazorEngine.Create(), new FileProviderRazorProject(fileProvider)),
33-
accessor.Object,
33+
partManager,
34+
new RazorTemplateEngine(
35+
RazorEngine.Create(),
36+
new FileProviderRazorProject(accessor)),
37+
accessor,
3438
new CSharpCompiler(referenceManager, options),
3539
options,
3640
NullLoggerFactory.Instance);

test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/RazorViewCompilerTest.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using Microsoft.AspNetCore.Razor.Language;
1111
using Microsoft.CodeAnalysis;
1212
using Microsoft.Extensions.Logging.Abstractions;
13+
using Moq;
1314
using Xunit;
1415

1516
namespace Microsoft.AspNetCore.Mvc.Razor.Internal
@@ -526,6 +527,8 @@ private static TestRazorViewCompiler GetViewCompiler(
526527
IList<CompiledViewDescriptor> precompiledViews = null)
527528
{
528529
fileProvider = fileProvider ?? new TestFileProvider();
530+
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);
531+
529532
compilationCallback = compilationCallback ?? (_ => { });
530533
var options = new TestOptionsManager<RazorViewEngineOptions>();
531534
if (referenceManager == null)
@@ -540,7 +543,7 @@ private static TestRazorViewCompiler GetViewCompiler(
540543

541544
precompiledViews = precompiledViews ?? Array.Empty<CompiledViewDescriptor>();
542545

543-
var projectSystem = new FileProviderRazorProject(fileProvider);
546+
var projectSystem = new FileProviderRazorProject(accessor);
544547
var templateEngine = new RazorTemplateEngine(RazorEngine.Create(), projectSystem)
545548
{
546549
Options =

test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorViewEngineTest.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -934,7 +934,8 @@ public void FindView_InvokesPageFactoryIfViewStartExpirationTokensHaveExpired()
934934
.Returns(GetPageFactoryResult(() => viewStart));
935935

936936
var fileProvider = new TestFileProvider();
937-
var razorProject = new FileProviderRazorProject(fileProvider);
937+
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);
938+
var razorProject = new FileProviderRazorProject(accessor);
938939
var viewEngine = CreateViewEngine(pageFactory.Object, razorProject: razorProject);
939940
var context = GetActionContext(_controllerTestContext);
940941

@@ -1384,7 +1385,8 @@ public void CreateCacheResult_LogsPrecompiledViewFound()
13841385
Mock.Of<IRazorPageActivator>(),
13851386
new HtmlTestEncoder(),
13861387
GetOptionsAccessor(expanders: null),
1387-
new FileProviderRazorProject(new TestFileProvider()),
1388+
new FileProviderRazorProject(
1389+
Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == new TestFileProvider())),
13881390
loggerFactory,
13891391
new DiagnosticListener("Microsoft.AspNetCore.Mvc.Razor"));
13901392

@@ -1822,7 +1824,8 @@ private TestableRazorViewEngine CreateViewEngine(
18221824
pageFactory = pageFactory ?? Mock.Of<IRazorPageFactoryProvider>();
18231825
if (razorProject == null)
18241826
{
1825-
razorProject = new FileProviderRazorProject(new TestFileProvider());
1827+
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == new TestFileProvider());
1828+
razorProject = new FileProviderRazorProject(accessor);
18261829
}
18271830
return new TestableRazorViewEngine(pageFactory, GetOptionsAccessor(expanders), razorProject);
18281831
}
@@ -1923,9 +1926,13 @@ private class TestableRazorViewEngine : RazorViewEngine
19231926
public TestableRazorViewEngine(
19241927
IRazorPageFactoryProvider pageFactory,
19251928
IOptions<RazorViewEngineOptions> optionsAccessor)
1926-
: this(pageFactory, optionsAccessor, new FileProviderRazorProject(new TestFileProvider()))
1927-
{
1928-
}
1929+
: this(
1930+
pageFactory,
1931+
optionsAccessor,
1932+
new FileProviderRazorProject(
1933+
Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == new TestFileProvider())))
1934+
{
1935+
}
19291936

19301937
public TestableRazorViewEngine(
19311938
IRazorPageFactoryProvider pageFactory,

test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/PageActionDescriptorChangeProviderTest.cs

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,13 @@ public void GetChangeToken_WatchesAllCshtmlFilesUnderFileSystemRoot()
1818
{
1919
// Arrange
2020
var fileProvider = new Mock<IFileProvider>();
21+
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider.Object);
22+
2123
var templateEngine = new RazorTemplateEngine(
2224
RazorEngine.Create(),
23-
new FileProviderRazorProject(fileProvider.Object));
25+
new FileProviderRazorProject(accessor));
2426
var options = new TestOptionsManager<RazorPagesOptions>();
25-
var fileProviderAccessor = new Mock<IRazorViewEngineFileProviderAccessor>();
26-
fileProviderAccessor
27-
.Setup(f => f.FileProvider)
28-
.Returns(fileProvider.Object);
29-
var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, fileProviderAccessor.Object, options);
27+
var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options);
3028

3129
// Act
3230
var changeToken = changeProvider.GetChangeToken();
@@ -42,16 +40,15 @@ public void GetChangeToken_WatchesAllCshtmlFilesUnderSpecifiedRootDirectory(stri
4240
{
4341
// Arrange
4442
var fileProvider = new Mock<IFileProvider>();
43+
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider.Object);
44+
4545
var templateEngine = new RazorTemplateEngine(
4646
RazorEngine.Create(),
47-
new FileProviderRazorProject(fileProvider.Object));
47+
new FileProviderRazorProject(accessor));
4848
var options = new TestOptionsManager<RazorPagesOptions>();
4949
options.Value.RootDirectory = rootDirectory;
50-
var fileProviderAccessor = new Mock<IRazorViewEngineFileProviderAccessor>();
51-
fileProviderAccessor
52-
.Setup(f => f.FileProvider)
53-
.Returns(fileProvider.Object);
54-
var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, fileProviderAccessor.Object, options);
50+
51+
var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options);
5552

5653
// Act
5754
var changeToken = changeProvider.GetChangeToken();
@@ -65,17 +62,16 @@ public void GetChangeToken_WatchesViewImportsOutsidePagesRoot()
6562
{
6663
// Arrange
6764
var fileProvider = new TestFileProvider();
65+
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);
66+
6867
var templateEngine = new RazorTemplateEngine(
6968
RazorEngine.Create(),
70-
new FileProviderRazorProject(fileProvider));
69+
new FileProviderRazorProject(accessor));
7170
templateEngine.Options.ImportsFileName = "_ViewImports.cshtml";
7271
var options = new TestOptionsManager<RazorPagesOptions>();
7372
options.Value.RootDirectory = "/dir1/dir2";
74-
var fileProviderAccessor = new Mock<IRazorViewEngineFileProviderAccessor>();
75-
fileProviderAccessor
76-
.Setup(f => f.FileProvider)
77-
.Returns(fileProvider);
78-
var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, fileProviderAccessor.Object, options);
73+
74+
var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options);
7975

8076
// Act & Assert
8177
var compositeChangeToken = Assert.IsType<CompositeChangeToken>(changeProvider.GetChangeToken());

test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/PageActionInvokerProviderTest.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,9 @@ public void OnProvidersExecuting_CachesViewStartFactories()
187187
var fileProvider = new TestFileProvider();
188188
fileProvider.AddFile("/Home/Path1/_ViewStart.cshtml", "content1");
189189
fileProvider.AddFile("/_ViewStart.cshtml", "content2");
190+
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);
190191

191-
var defaultRazorProject = new FileProviderRazorProject(fileProvider);
192+
var defaultRazorProject = new FileProviderRazorProject(accessor);
192193

193194
var invokerProvider = CreateInvokerProvider(
194195
loader.Object,

0 commit comments

Comments
 (0)