diff --git a/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorHost.cs b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorHost.cs
index aaf87e13ff..11a628d597 100644
--- a/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorHost.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorHost.cs
@@ -11,10 +11,6 @@ using Microsoft.AspNet.Razor.Generator.Compiler;
using Microsoft.AspNet.Razor.Parser;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
-#if ASPNET50 || ASPNETCORE50
-using Microsoft.Framework.Runtime;
-#endif
-
namespace Microsoft.AspNet.Mvc.Razor
{
public class MvcRazorHost : RazorEngineHost, IMvcRazorHost
@@ -41,17 +37,7 @@ namespace Microsoft.AspNet.Mvc.Razor
// This field holds the type name without the generic decoration (MyBaseType)
private readonly string _baseType;
-#if ASPNET50 || ASPNETCORE50
- ///
- /// Initializes a new instance of with the specified
- /// .
- ///
- /// Contains information about the executing application.
- public MvcRazorHost(IApplicationEnvironment appEnvironment)
- : this(new PhysicalFileSystem(appEnvironment.ApplicationBasePath))
- {
- }
-#elif NET45
+#if NET45
///
/// Initializes a new instance of with the specified
/// .
@@ -62,12 +48,11 @@ namespace Microsoft.AspNet.Mvc.Razor
{
}
#endif
-
///
/// Initializes a new instance of using the specified .
///
/// A rooted at the application base path.
- protected internal MvcRazorHost([NotNull] IFileSystem fileSystem)
+ public MvcRazorHost(IFileSystem fileSystem)
: base(new CSharpRazorCodeLanguage())
{
_fileSystem = fileSystem;
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Compilation/ExpiringFileInfoCache.cs b/src/Microsoft.AspNet.Mvc.Razor/Compilation/ExpiringFileInfoCache.cs
index 0c37c64e9b..68af815d4d 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/Compilation/ExpiringFileInfoCache.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/Compilation/ExpiringFileInfoCache.cs
@@ -5,7 +5,6 @@ using System;
using System.Collections.Concurrent;
using Microsoft.AspNet.FileSystems;
using Microsoft.Framework.OptionsModel;
-using Microsoft.Framework.Runtime;
namespace Microsoft.AspNet.Mvc.Razor
{
@@ -17,15 +16,13 @@ namespace Microsoft.AspNet.Mvc.Razor
private readonly ConcurrentDictionary _fileInfoCache =
new ConcurrentDictionary(StringComparer.Ordinal);
- private readonly PhysicalFileSystem _fileSystem;
+ private readonly IFileSystem _fileSystem;
private readonly TimeSpan _offset;
- protected virtual IFileSystem FileSystem
+ public ExpiringFileInfoCache(IOptionsAccessor optionsAccessor)
{
- get
- {
- return _fileSystem;
- }
+ _fileSystem = optionsAccessor.Options.FileSystem;
+ _offset = optionsAccessor.Options.ExpirationBeforeCheckingFilesOnDisk;
}
protected virtual DateTime UtcNow
@@ -36,14 +33,6 @@ namespace Microsoft.AspNet.Mvc.Razor
}
}
- public ExpiringFileInfoCache(IApplicationEnvironment env,
- IOptionsAccessor optionsAccessor)
- {
- // TODO: Inject the IFileSystem but only when we get it from the host
- _fileSystem = new PhysicalFileSystem(env.ApplicationBasePath);
- _offset = optionsAccessor.Options.ExpirationBeforeCheckingFilesOnDisk;
- }
-
///
public IFileInfo GetFileInfo([NotNull] string virtualPath)
{
@@ -59,7 +48,7 @@ namespace Microsoft.AspNet.Mvc.Razor
}
else
{
- FileSystem.TryGetFileInfo(virtualPath, out fileInfo);
+ _fileSystem.TryGetFileInfo(virtualPath, out fileInfo);
expiringFileInfo = new ExpiringFileInfo()
{
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Compilation/IExpiringFileInfoCache.cs b/src/Microsoft.AspNet.Mvc.Razor/Compilation/IFileInfoCache.cs
similarity index 100%
rename from src/Microsoft.AspNet.Mvc.Razor/Compilation/IExpiringFileInfoCache.cs
rename to src/Microsoft.AspNet.Mvc.Razor/Compilation/IFileInfoCache.cs
diff --git a/src/Microsoft.AspNet.Mvc.Razor/OptionDescriptors/RazorViewEngineOptions.cs b/src/Microsoft.AspNet.Mvc.Razor/OptionDescriptors/RazorViewEngineOptions.cs
index 53d534ecd7..3585041721 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/OptionDescriptors/RazorViewEngineOptions.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/OptionDescriptors/RazorViewEngineOptions.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using Microsoft.AspNet.FileSystems;
using Microsoft.AspNet.Mvc.Razor.OptionDescriptors;
namespace Microsoft.AspNet.Mvc.Razor
@@ -13,6 +14,7 @@ namespace Microsoft.AspNet.Mvc.Razor
public class RazorViewEngineOptions
{
private TimeSpan _expirationBeforeCheckingFilesOnDisk = TimeSpan.FromSeconds(2);
+ private IFileSystem _fileSystem;
///
/// Controls the caching behavior.
@@ -47,5 +49,28 @@ namespace Microsoft.AspNet.Mvc.Razor
///
public IList ViewLocationExpanders { get; }
= new List();
+
+ ///
+ /// Gets or sets the used by to locate Razor files on
+ /// disk.
+ ///
+ ///
+ /// At startup, this is initialized to an instance of that is rooted at the
+ /// application root.
+ ///
+ public IFileSystem FileSystem
+ {
+ get { return _fileSystem; }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value));
+ }
+
+ _fileSystem = value;
+ }
+ }
}
}
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Razor/PreCompileViews/RazorPreCompiler.cs b/src/Microsoft.AspNet.Mvc.Razor/Razor/PreCompileViews/RazorPreCompiler.cs
index a30c6ba5a9..82194d760d 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/Razor/PreCompileViews/RazorPreCompiler.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/Razor/PreCompileViews/RazorPreCompiler.cs
@@ -8,6 +8,7 @@ using Microsoft.AspNet.FileSystems;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.Framework.DependencyInjection;
+using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.Runtime;
namespace Microsoft.AspNet.Mvc.Razor
@@ -18,29 +19,26 @@ namespace Microsoft.AspNet.Mvc.Razor
private readonly IFileSystem _fileSystem;
private readonly IMvcRazorHost _host;
- protected virtual string FileExtension
- {
- get
- {
- return ".cshtml";
- }
- }
-
public RazorPreCompiler([NotNull] IServiceProvider designTimeServiceProvider) :
- this(designTimeServiceProvider, designTimeServiceProvider.GetService())
+ this(designTimeServiceProvider,
+ designTimeServiceProvider.GetService(),
+ designTimeServiceProvider.GetService>())
{
}
public RazorPreCompiler([NotNull] IServiceProvider designTimeServiceProvider,
- [NotNull] IMvcRazorHost host)
+ [NotNull] IMvcRazorHost host,
+ [NotNull] IOptionsAccessor optionsAccessor)
{
_serviceProvider = designTimeServiceProvider;
_host = host;
var appEnv = _serviceProvider.GetService();
- _fileSystem = new PhysicalFileSystem(appEnv.ApplicationBasePath);
+ _fileSystem = optionsAccessor.Options.FileSystem;
}
+ protected virtual string FileExtension { get; } = ".cshtml";
+
public virtual void CompileViews([NotNull] IBeforeCompileContext context)
{
var descriptors = CreateCompilationDescriptors(context);
diff --git a/src/Microsoft.AspNet.Mvc.Razor/ViewStartProvider.cs b/src/Microsoft.AspNet.Mvc.Razor/ViewStartProvider.cs
index f99d1a61d7..8116ca486b 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/ViewStartProvider.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/ViewStartProvider.cs
@@ -5,7 +5,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.FileSystems;
-using Microsoft.Framework.Runtime;
+using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Mvc.Razor
{
@@ -15,10 +15,10 @@ namespace Microsoft.AspNet.Mvc.Razor
private readonly IFileSystem _fileSystem;
private readonly IRazorPageFactory _pageFactory;
- public ViewStartProvider(IApplicationEnvironment appEnv,
- IRazorPageFactory pageFactory)
+ public ViewStartProvider(IRazorPageFactory pageFactory,
+ IOptionsAccessor optionsAccessor)
{
- _fileSystem = new PhysicalFileSystem(appEnv.ApplicationBasePath);
+ _fileSystem = optionsAccessor.Options.FileSystem;
_pageFactory = pageFactory;
}
diff --git a/src/Microsoft.AspNet.Mvc/MvcServices.cs b/src/Microsoft.AspNet.Mvc/MvcServices.cs
index d14339ab96..e1c66d5218 100644
--- a/src/Microsoft.AspNet.Mvc/MvcServices.cs
+++ b/src/Microsoft.AspNet.Mvc/MvcServices.cs
@@ -35,6 +35,8 @@ namespace Microsoft.AspNet.Mvc
// Options and core services.
//
yield return describe.Transient, MvcOptionsSetup>();
+ yield return describe.Transient, RazorViewEngineOptionsSetup>();
+
yield return describe.Transient();
yield return describe.Transient(typeof(INestedProviderManager<>), typeof(NestedProviderManager<>));
yield return describe.Transient(typeof(INestedProviderManagerAsync<>), typeof(NestedProviderManagerAsync<>));
@@ -106,7 +108,11 @@ namespace Microsoft.AspNet.Mvc
yield return describe.Singleton();
// The host is designed to be discarded after consumption and is very inexpensive to initialize.
- yield return describe.Transient();
+ yield return describe.Transient(serviceProvider =>
+ {
+ var optionsAccessor = serviceProvider.GetService>();
+ return new MvcRazorHost(optionsAccessor.Options.FileSystem);
+ });
yield return describe.Singleton();
yield return describe.Singleton();
diff --git a/src/Microsoft.AspNet.Mvc/RazorPreCompileModule.cs b/src/Microsoft.AspNet.Mvc/RazorPreCompileModule.cs
index 560a157143..0f72b07400 100644
--- a/src/Microsoft.AspNet.Mvc/RazorPreCompileModule.cs
+++ b/src/Microsoft.AspNet.Mvc/RazorPreCompileModule.cs
@@ -6,9 +6,10 @@ using System.Collections.Generic;
using Microsoft.AspNet.Mvc.Razor;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
-using Microsoft.Framework.Runtime;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback;
+using Microsoft.Framework.OptionsModel;
+using Microsoft.Framework.Runtime;
namespace Microsoft.AspNet.Mvc
{
@@ -21,9 +22,16 @@ namespace Microsoft.AspNet.Mvc
_appServices = services;
}
+ protected virtual string FileExtension { get; } = ".cshtml";
+
public virtual void BeforeCompile(IBeforeCompileContext context)
{
var sc = new ServiceCollection();
+ var appEnv = _appServices.GetService();
+
+ var setup = new RazorViewEngineOptionsSetup(appEnv);
+ var accessor = new OptionsAccessor(new[] { setup });
+ sc.AddInstance>(accessor);
sc.Add(MvcServices.GetDefaultServices());
var sp = sc.BuildServiceProvider(_appServices);
diff --git a/src/Microsoft.AspNet.Mvc/RazorViewEngineOptionsSetup.cs b/src/Microsoft.AspNet.Mvc/RazorViewEngineOptionsSetup.cs
new file mode 100644
index 0000000000..d93e10d43c
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc/RazorViewEngineOptionsSetup.cs
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNet.FileSystems;
+using Microsoft.AspNet.Mvc.Razor;
+using Microsoft.Framework.OptionsModel;
+using Microsoft.Framework.Runtime;
+
+namespace Microsoft.AspNet.Mvc
+{
+ ///
+ /// Sets up default options for .
+ ///
+ public class RazorViewEngineOptionsSetup : OptionsAction
+ {
+ ///
+ /// Initializes a new instance of .
+ ///
+ /// for the application.
+ public RazorViewEngineOptionsSetup(IApplicationEnvironment applicationEnvironment)
+ : base(options => ConfigureRazor(options, applicationEnvironment))
+ {
+ Order = DefaultOrder.DefaultFrameworkSortOrder;
+ }
+
+ private static void ConfigureRazor(RazorViewEngineOptions razorOptions,
+ IApplicationEnvironment applicationEnvironment)
+ {
+ razorOptions.FileSystem = new PhysicalFileSystem(applicationEnvironment.ApplicationBasePath);
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/ExpiringFileInfoCacheTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/ExpiringFileInfoCacheTest.cs
index 3efe7db857..7414bf09e7 100644
--- a/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/ExpiringFileInfoCacheTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Razor.Test/Compilation/ExpiringFileInfoCacheTest.cs
@@ -6,7 +6,6 @@ using System.Collections.Generic;
using System.IO;
using Microsoft.AspNet.FileSystems;
using Microsoft.Framework.OptionsModel;
-using Microsoft.Framework.Runtime;
using Moq;
using Xunit;
@@ -16,30 +15,16 @@ namespace Microsoft.AspNet.Mvc.Razor
{
private const string FileName = "myView.cshtml";
- public IApplicationEnvironment ApplicationEnvironment
- {
- get
- {
- var mock = new Mock(MockBehavior.Strict);
- mock.Setup(ae => ae.ApplicationBasePath).Returns(Directory.GetCurrentDirectory());
-
- return mock.Object;
- }
- }
-
- public RazorViewEngineOptions Options
- {
- get
- {
- return new RazorViewEngineOptions();
- }
- }
+ public DummyFileSystem TestFileSystem { get; } = new DummyFileSystem();
public IOptionsAccessor OptionsAccessor
{
get
{
- var options = Options;
+ var options = new RazorViewEngineOptions
+ {
+ FileSystem = TestFileSystem
+ };
var mock = new Mock>(MockBehavior.Strict);
mock.Setup(oa => oa.Options).Returns(options);
@@ -50,18 +35,18 @@ namespace Microsoft.AspNet.Mvc.Razor
public ControllableExpiringFileInfoCache GetCache(IOptionsAccessor optionsAccessor)
{
- return new ControllableExpiringFileInfoCache(ApplicationEnvironment, optionsAccessor);
+ return new ControllableExpiringFileInfoCache(optionsAccessor);
}
- public void CreateFile(string FileName, ControllableExpiringFileInfoCache cache)
+ public void CreateFile(string fileName)
{
var fileInfo = new DummyFileInfo()
{
- Name = FileName,
+ Name = fileName,
LastModified = DateTime.Now,
};
- cache.UnderlyingFileSystem.AddFile(fileInfo);
+ TestFileSystem.AddFile(fileInfo);
}
public void Sleep(ControllableExpiringFileInfoCache cache, int offsetMilliseconds)
@@ -96,7 +81,7 @@ namespace Microsoft.AspNet.Mvc.Razor
// Arrange
var cache = GetCache(OptionsAccessor);
- CreateFile(FileName, cache);
+ CreateFile(FileName);
// Act
var fileInfo1 = cache.GetFileInfo(FileName);
@@ -114,12 +99,12 @@ namespace Microsoft.AspNet.Mvc.Razor
// Arrange
var cache = GetCache(OptionsAccessor);
- CreateFile(FileName, cache);
+ CreateFile(FileName);
// Act
var fileInfo1 = cache.GetFileInfo(FileName);
- CreateFile(FileName, cache);
+ CreateFile(FileName);
var fileInfo2 = cache.GetFileInfo(FileName);
@@ -139,13 +124,13 @@ namespace Microsoft.AspNet.Mvc.Razor
// Arrange
var cache = GetCache(optionsAccessor);
- CreateFile(FileName, cache);
+ CreateFile(FileName);
// Act
var fileInfo1 = cache.GetFileInfo(FileName);
Sleep(optionsAccessor, cache, 500);
- CreateFile(FileName, cache);
+ CreateFile(FileName);
var fileInfo2 = cache.GetFileInfo(FileName);
@@ -164,7 +149,7 @@ namespace Microsoft.AspNet.Mvc.Razor
var cache = GetCache(optionsAccessor);
- CreateFile(FileName, cache);
+ CreateFile(FileName);
// Act
var fileInfo1 = cache.GetFileInfo(FileName);
@@ -213,7 +198,7 @@ namespace Microsoft.AspNet.Mvc.Razor
string FileName = "myfile4.cshtml";
var cache = GetCache(optionsAccessor);
- CreateFile(FileName, cache);
+ CreateFile(FileName);
// Act
var fileInfo1 = cache.GetFileInfo(FileName);
@@ -254,7 +239,7 @@ namespace Microsoft.AspNet.Mvc.Razor
string FileName = "myfile5.cshtml";
var cache = GetCache(optionsAccessor);
- CreateFile(FileName, cache);
+ CreateFile(FileName);
// Act
var fileInfo1 = cache.GetFileInfo(FileName);
@@ -280,7 +265,7 @@ namespace Microsoft.AspNet.Mvc.Razor
string FileName = "myfile6.cshtml";
var cache = GetCache(optionsAccessor);
- CreateFile(FileName, cache);
+ CreateFile(FileName);
// Act
var fileInfo1 = cache.GetFileInfo(FileName);
@@ -305,7 +290,7 @@ namespace Microsoft.AspNet.Mvc.Razor
string FileName = "myfile7.cshtml";
var cache = GetCache(optionsAccessor);
- CreateFile(FileName, cache);
+ CreateFile(FileName);
// Act
var fileInfo1 = cache.GetFileInfo(FileName);
@@ -322,14 +307,12 @@ namespace Microsoft.AspNet.Mvc.Razor
public class ControllableExpiringFileInfoCache : ExpiringFileInfoCache
{
- public ControllableExpiringFileInfoCache(IApplicationEnvironment env,
- IOptionsAccessor optionsAccessor)
- : base(env, optionsAccessor)
+ public ControllableExpiringFileInfoCache(IOptionsAccessor optionsAccessor)
+ : base(optionsAccessor)
{
}
private DateTime? _internalUtcNow { get; set; }
- private DummyFileSystem _underlyingFileSystem = new DummyFileSystem();
protected override DateTime UtcNow
{
@@ -344,14 +327,6 @@ namespace Microsoft.AspNet.Mvc.Razor
}
}
- protected override IFileSystem FileSystem
- {
- get
- {
- return UnderlyingFileSystem;
- }
- }
-
public void Sleep(int milliSeconds)
{
if (milliSeconds <= 0)
@@ -361,14 +336,6 @@ namespace Microsoft.AspNet.Mvc.Razor
_internalUtcNow = UtcNow.AddMilliseconds(milliSeconds);
}
-
- public DummyFileSystem UnderlyingFileSystem
- {
- get
- {
- return _underlyingFileSystem;
- }
- }
}
public class DummyFileSystem : IFileSystem
diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewEngineOptionsTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewEngineOptionsTest.cs
new file mode 100644
index 0000000000..12ffb3abc4
--- /dev/null
+++ b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewEngineOptionsTest.cs
@@ -0,0 +1,22 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Xunit;
+
+namespace Microsoft.AspNet.Mvc.Razor
+{
+ public class RazorViewEngineOptionsTest
+ {
+ [Fact]
+ public void FileSystemThrows_IfNullIsAsseigned()
+ {
+ // Arrange
+ var options = new RazorViewEngineOptions();
+
+ // Act and Assert
+ var ex = Assert.Throws(() => options.FileSystem = null);
+ Assert.Equal("value", ex.ParamName);
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.Test/RazorViewEngineOptionsSetupTest.cs b/test/Microsoft.AspNet.Mvc.Test/RazorViewEngineOptionsSetupTest.cs
new file mode 100644
index 0000000000..2226461a36
--- /dev/null
+++ b/test/Microsoft.AspNet.Mvc.Test/RazorViewEngineOptionsSetupTest.cs
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.IO;
+using Microsoft.AspNet.FileSystems;
+using Microsoft.AspNet.Mvc.Razor;
+using Microsoft.Framework.Runtime;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNet.Mvc
+{
+ public class RazorViewEngineOptionsSetupTest
+ {
+ [Fact]
+ public void RazorViewEngineOptionsSetup_SetsUpFileSystem()
+ {
+ // Arrange
+ var options = new RazorViewEngineOptions();
+ var appEnv = new Mock();
+ appEnv.SetupGet(e => e.ApplicationBasePath)
+ .Returns(Directory.GetCurrentDirectory());
+ var optionsSetup = new RazorViewEngineOptionsSetup(appEnv.Object);
+
+ // Act
+ optionsSetup.Invoke(options);
+
+ // Assert
+ Assert.NotNull(options.FileSystem);
+ Assert.IsType(options.FileSystem);
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.Test/project.json b/test/Microsoft.AspNet.Mvc.Test/project.json
index 6a8a995178..55c791c321 100644
--- a/test/Microsoft.AspNet.Mvc.Test/project.json
+++ b/test/Microsoft.AspNet.Mvc.Test/project.json
@@ -10,6 +10,10 @@
"test": "Xunit.KRunner"
},
"frameworks": {
- "aspnet50": { }
+ "aspnet50": {
+ "dependencies": {
+ "Moq": "4.2.1312.1622"
+ }
+ }
}
}