parent
cba4d1dd0c
commit
0ff2f875d9
|
|
@ -29,12 +29,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DefaultRoslynCompilationService : ICompilationService
|
public class DefaultRoslynCompilationService : ICompilationService
|
||||||
{
|
{
|
||||||
|
private readonly IHostingEnvironment _hostingEnvironment;
|
||||||
private readonly IFileProvider _fileProvider;
|
private readonly IFileProvider _fileProvider;
|
||||||
private readonly Action<RoslynCompilationContext> _compilationCallback;
|
private readonly Action<RoslynCompilationContext> _compilationCallback;
|
||||||
private readonly CSharpParseOptions _parseOptions;
|
private readonly CSharpParseOptions _parseOptions;
|
||||||
private readonly CSharpCompilationOptions _compilationOptions;
|
private readonly CSharpCompilationOptions _compilationOptions;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly DependencyContext _dependencyContext;
|
|
||||||
private object _applicationReferencesLock = new object();
|
private object _applicationReferencesLock = new object();
|
||||||
private bool _applicationReferencesInitialized;
|
private bool _applicationReferencesInitialized;
|
||||||
private List<MetadataReference> _applicationReferences;
|
private List<MetadataReference> _applicationReferences;
|
||||||
|
|
@ -51,26 +51,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
||||||
IOptions<RazorViewEngineOptions> optionsAccessor,
|
IOptions<RazorViewEngineOptions> optionsAccessor,
|
||||||
IRazorViewEngineFileProviderAccessor fileProviderAccessor,
|
IRazorViewEngineFileProviderAccessor fileProviderAccessor,
|
||||||
ILoggerFactory loggerFactory)
|
ILoggerFactory loggerFactory)
|
||||||
: this(
|
|
||||||
GetDependencyContext(environment),
|
|
||||||
optionsAccessor.Value,
|
|
||||||
fileProviderAccessor,
|
|
||||||
loggerFactory)
|
|
||||||
{
|
{
|
||||||
}
|
_hostingEnvironment = environment;
|
||||||
|
|
||||||
// Internal for unit testing
|
|
||||||
internal DefaultRoslynCompilationService(
|
|
||||||
DependencyContext dependencyContext,
|
|
||||||
RazorViewEngineOptions viewEngineOptions,
|
|
||||||
IRazorViewEngineFileProviderAccessor fileProviderAccessor,
|
|
||||||
ILoggerFactory loggerFactory)
|
|
||||||
{
|
|
||||||
_dependencyContext = dependencyContext;
|
|
||||||
_fileProvider = fileProviderAccessor.FileProvider;
|
_fileProvider = fileProviderAccessor.FileProvider;
|
||||||
_compilationCallback = viewEngineOptions.CompilationCallback;
|
_compilationCallback = optionsAccessor.Value.CompilationCallback;
|
||||||
_parseOptions = viewEngineOptions.ParseOptions;
|
_parseOptions = optionsAccessor.Value.ParseOptions;
|
||||||
_compilationOptions = viewEngineOptions.CompilationOptions;
|
_compilationOptions = optionsAccessor.Value.CompilationOptions;
|
||||||
_logger = loggerFactory.CreateLogger<DefaultRoslynCompilationService>();
|
_logger = loggerFactory.CreateLogger<DefaultRoslynCompilationService>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -165,6 +151,22 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the <see cref="DependencyContext"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hostingEnvironment">The <see cref="IHostingEnvironment"/>.</param>
|
||||||
|
/// <returns>The <see cref="DependencyContext"/>.</returns>
|
||||||
|
protected virtual DependencyContext GetDependencyContext(IHostingEnvironment hostingEnvironment)
|
||||||
|
{
|
||||||
|
if (hostingEnvironment.ApplicationName != null)
|
||||||
|
{
|
||||||
|
var applicationAssembly = Assembly.Load(new AssemblyName(hostingEnvironment.ApplicationName));
|
||||||
|
return DependencyContext.Load(applicationAssembly);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private Assembly LoadStream(MemoryStream assemblyStream, MemoryStream pdbStream)
|
private Assembly LoadStream(MemoryStream assemblyStream, MemoryStream pdbStream)
|
||||||
{
|
{
|
||||||
#if NET451
|
#if NET451
|
||||||
|
|
@ -241,16 +243,17 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
||||||
private List<MetadataReference> GetApplicationReferences()
|
private List<MetadataReference> GetApplicationReferences()
|
||||||
{
|
{
|
||||||
var metadataReferences = new List<MetadataReference>();
|
var metadataReferences = new List<MetadataReference>();
|
||||||
if (_dependencyContext == null)
|
var dependencyContext = GetDependencyContext(_hostingEnvironment);
|
||||||
|
if (dependencyContext == null)
|
||||||
{
|
{
|
||||||
// Avoid null ref if the entry point does not have DependencyContext specified.
|
// Avoid null ref if the entry point does not have DependencyContext specified.
|
||||||
return metadataReferences;
|
return metadataReferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
var libraryPaths = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
var libraryPaths = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
for (var i = 0; i < _dependencyContext.CompileLibraries.Count; i++)
|
for (var i = 0; i < dependencyContext.CompileLibraries.Count; i++)
|
||||||
{
|
{
|
||||||
var library = _dependencyContext.CompileLibraries[i];
|
var library = dependencyContext.CompileLibraries[i];
|
||||||
IEnumerable<string> referencePaths;
|
IEnumerable<string> referencePaths;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -322,16 +325,5 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
||||||
mappedLineSpan.EndLinePosition.Line + 1,
|
mappedLineSpan.EndLinePosition.Line + 1,
|
||||||
mappedLineSpan.EndLinePosition.Character + 1);
|
mappedLineSpan.EndLinePosition.Character + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DependencyContext GetDependencyContext(IHostingEnvironment environment)
|
|
||||||
{
|
|
||||||
if (environment.ApplicationName != null)
|
|
||||||
{
|
|
||||||
var applicationAssembly = Assembly.Load(new AssemblyName(environment.ApplicationName));
|
|
||||||
return DependencyContext.Load(applicationAssembly);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,14 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Mvc.Razor.Compilation;
|
using Microsoft.AspNetCore.Mvc.Razor.Compilation;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.CodeAnalysis.Text;
|
using Microsoft.CodeAnalysis.Text;
|
||||||
using Microsoft.Extensions.DependencyModel;
|
using Microsoft.Extensions.DependencyModel;
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
using Microsoft.Extensions.Logging.Testing;
|
using Microsoft.Extensions.Logging.Testing;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -24,11 +26,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
||||||
var content = @"
|
var content = @"
|
||||||
public class MyTestType {}";
|
public class MyTestType {}";
|
||||||
|
|
||||||
var compilationService = new DefaultRoslynCompilationService(
|
var compilationService = new TestableRoslynCompilationService(
|
||||||
GetDependencyContext(),
|
GetDependencyContext(),
|
||||||
GetOptions(),
|
GetOptions(),
|
||||||
GetFileProviderAccessor(),
|
GetFileProviderAccessor());
|
||||||
NullLoggerFactory.Instance);
|
|
||||||
var relativeFileInfo = new RelativeFileInfo(
|
var relativeFileInfo = new RelativeFileInfo(
|
||||||
new TestFileInfo { PhysicalPath = "SomePath" },
|
new TestFileInfo { PhysicalPath = "SomePath" },
|
||||||
"some-relative-path");
|
"some-relative-path");
|
||||||
|
|
@ -52,11 +53,10 @@ this should fail";
|
||||||
var fileProvider = new TestFileProvider();
|
var fileProvider = new TestFileProvider();
|
||||||
var fileInfo = fileProvider.AddFile(viewPath, fileContent);
|
var fileInfo = fileProvider.AddFile(viewPath, fileContent);
|
||||||
|
|
||||||
var compilationService = new DefaultRoslynCompilationService(
|
var compilationService = new TestableRoslynCompilationService(
|
||||||
GetDependencyContext(),
|
GetDependencyContext(),
|
||||||
GetOptions(),
|
GetOptions(),
|
||||||
GetFileProviderAccessor(fileProvider),
|
GetFileProviderAccessor(fileProvider));
|
||||||
NullLoggerFactory.Instance);
|
|
||||||
var relativeFileInfo = new RelativeFileInfo(fileInfo, "some-relative-path");
|
var relativeFileInfo = new RelativeFileInfo(fileInfo, "some-relative-path");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -77,11 +77,10 @@ this should fail";
|
||||||
var fileContent = "file content";
|
var fileContent = "file content";
|
||||||
var content = @"this should fail";
|
var content = @"this should fail";
|
||||||
|
|
||||||
var compilationService = new DefaultRoslynCompilationService(
|
var compilationService = new TestableRoslynCompilationService(
|
||||||
GetDependencyContext(),
|
GetDependencyContext(),
|
||||||
GetOptions(),
|
GetOptions(),
|
||||||
GetFileProviderAccessor(),
|
GetFileProviderAccessor());
|
||||||
NullLoggerFactory.Instance);
|
|
||||||
var relativeFileInfo = new RelativeFileInfo(
|
var relativeFileInfo = new RelativeFileInfo(
|
||||||
new TestFileInfo { Content = fileContent },
|
new TestFileInfo { Content = fileContent },
|
||||||
"some-relative-path");
|
"some-relative-path");
|
||||||
|
|
@ -113,11 +112,10 @@ this should fail";
|
||||||
var fileProvider = new TestFileProvider();
|
var fileProvider = new TestFileProvider();
|
||||||
fileProvider.AddFile(path, mockFileInfo.Object);
|
fileProvider.AddFile(path, mockFileInfo.Object);
|
||||||
|
|
||||||
var compilationService = new DefaultRoslynCompilationService(
|
var compilationService = new TestableRoslynCompilationService(
|
||||||
GetDependencyContext(),
|
GetDependencyContext(),
|
||||||
GetOptions(),
|
GetOptions(),
|
||||||
GetFileProviderAccessor(),
|
GetFileProviderAccessor());
|
||||||
NullLoggerFactory.Instance);
|
|
||||||
var relativeFileInfo = new RelativeFileInfo(mockFileInfo.Object, path);
|
var relativeFileInfo = new RelativeFileInfo(mockFileInfo.Object, path);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -146,11 +144,10 @@ public class MyNonCustomDefinedClass {}
|
||||||
var options = GetOptions();
|
var options = GetOptions();
|
||||||
options.ParseOptions = options.ParseOptions.WithPreprocessorSymbols("MY_CUSTOM_DEFINE");
|
options.ParseOptions = options.ParseOptions.WithPreprocessorSymbols("MY_CUSTOM_DEFINE");
|
||||||
|
|
||||||
var compilationService = new DefaultRoslynCompilationService(
|
var compilationService = new TestableRoslynCompilationService(
|
||||||
GetDependencyContext(),
|
GetDependencyContext(),
|
||||||
options,
|
options,
|
||||||
GetFileProviderAccessor(),
|
GetFileProviderAccessor());
|
||||||
NullLoggerFactory.Instance);
|
|
||||||
var relativeFileInfo = new RelativeFileInfo(
|
var relativeFileInfo = new RelativeFileInfo(
|
||||||
new TestFileInfo { PhysicalPath = "SomePath" },
|
new TestFileInfo { PhysicalPath = "SomePath" },
|
||||||
"some-relative-path");
|
"some-relative-path");
|
||||||
|
|
@ -174,11 +171,10 @@ public class MyNonCustomDefinedClass {}
|
||||||
var options = new RazorViewEngineOptions();
|
var options = new RazorViewEngineOptions();
|
||||||
options.FileProviders.Add(fileProvider);
|
options.FileProviders.Add(fileProvider);
|
||||||
|
|
||||||
var compilationService = new DefaultRoslynCompilationService(
|
var compilationService = new TestableRoslynCompilationService(
|
||||||
GetDependencyContext(),
|
GetDependencyContext(),
|
||||||
options,
|
options,
|
||||||
GetFileProviderAccessor(fileProvider),
|
GetFileProviderAccessor(fileProvider));
|
||||||
NullLoggerFactory.Instance);
|
|
||||||
|
|
||||||
var assemblyName = "random-assembly-name";
|
var assemblyName = "random-assembly-name";
|
||||||
|
|
||||||
|
|
@ -261,11 +257,10 @@ public class MyNonCustomDefinedClass {}
|
||||||
var content = "public class MyTestType {}";
|
var content = "public class MyTestType {}";
|
||||||
RoslynCompilationContext usedCompilation = null;
|
RoslynCompilationContext usedCompilation = null;
|
||||||
|
|
||||||
var compilationService = new DefaultRoslynCompilationService(
|
var compilationService = new TestableRoslynCompilationService(
|
||||||
GetDependencyContext(),
|
GetDependencyContext(),
|
||||||
GetOptions(callback: c => usedCompilation = c),
|
GetOptions(callback: c => usedCompilation = c),
|
||||||
GetFileProviderAccessor(),
|
GetFileProviderAccessor());
|
||||||
NullLoggerFactory.Instance);
|
|
||||||
|
|
||||||
var relativeFileInfo = new RelativeFileInfo(
|
var relativeFileInfo = new RelativeFileInfo(
|
||||||
new TestFileInfo { PhysicalPath = "SomePath" },
|
new TestFileInfo { PhysicalPath = "SomePath" },
|
||||||
|
|
@ -283,11 +278,10 @@ public class MyNonCustomDefinedClass {}
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var content = "public class MyTestType {}";
|
var content = "public class MyTestType {}";
|
||||||
var compilationService = new DefaultRoslynCompilationService(
|
var compilationService = new TestableRoslynCompilationService(
|
||||||
dependencyContext: null,
|
dependencyContext: null,
|
||||||
viewEngineOptions: GetOptions(),
|
viewEngineOptions: GetOptions(),
|
||||||
fileProviderAccessor: GetFileProviderAccessor(),
|
fileProviderAccessor: GetFileProviderAccessor());
|
||||||
loggerFactory: NullLoggerFactory.Instance);
|
|
||||||
|
|
||||||
var relativeFileInfo = new RelativeFileInfo(
|
var relativeFileInfo = new RelativeFileInfo(
|
||||||
new TestFileInfo { PhysicalPath = "SomePath" },
|
new TestFileInfo { PhysicalPath = "SomePath" },
|
||||||
|
|
@ -313,11 +307,10 @@ public class MyNonCustomDefinedClass {}
|
||||||
new CompilationLibrary[0],
|
new CompilationLibrary[0],
|
||||||
new RuntimeLibrary[0],
|
new RuntimeLibrary[0],
|
||||||
Enumerable.Empty<RuntimeFallbacks>());
|
Enumerable.Empty<RuntimeFallbacks>());
|
||||||
var compilationService = new DefaultRoslynCompilationService(
|
var compilationService = new TestableRoslynCompilationService(
|
||||||
dependencyContext: dependencyContext,
|
dependencyContext: dependencyContext,
|
||||||
viewEngineOptions: GetOptions(),
|
viewEngineOptions: GetOptions(),
|
||||||
fileProviderAccessor: GetFileProviderAccessor(),
|
fileProviderAccessor: GetFileProviderAccessor());
|
||||||
loggerFactory: NullLoggerFactory.Instance);
|
|
||||||
|
|
||||||
var relativeFileInfo = new RelativeFileInfo(
|
var relativeFileInfo = new RelativeFileInfo(
|
||||||
new TestFileInfo { PhysicalPath = "SomePath" },
|
new TestFileInfo { PhysicalPath = "SomePath" },
|
||||||
|
|
@ -341,11 +334,10 @@ public class MyNonCustomDefinedClass {}
|
||||||
context.Compilation = context.Compilation.RemoveAllReferences();
|
context.Compilation = context.Compilation.RemoveAllReferences();
|
||||||
});
|
});
|
||||||
var content = "public class MyTestType {}";
|
var content = "public class MyTestType {}";
|
||||||
var compilationService = new DefaultRoslynCompilationService(
|
var compilationService = new TestableRoslynCompilationService(
|
||||||
dependencyContext: GetDependencyContext(),
|
dependencyContext: GetDependencyContext(),
|
||||||
viewEngineOptions: options,
|
viewEngineOptions: options,
|
||||||
fileProviderAccessor: GetFileProviderAccessor(),
|
fileProviderAccessor: GetFileProviderAccessor());
|
||||||
loggerFactory: NullLoggerFactory.Instance);
|
|
||||||
|
|
||||||
var relativeFileInfo = new RelativeFileInfo(
|
var relativeFileInfo = new RelativeFileInfo(
|
||||||
new TestFileInfo { PhysicalPath = "SomePath" },
|
new TestFileInfo { PhysicalPath = "SomePath" },
|
||||||
|
|
@ -371,11 +363,10 @@ public class MyNonCustomDefinedClass {}
|
||||||
.AddReferences(MetadataReference.CreateFromFile(assemblyLocation));
|
.AddReferences(MetadataReference.CreateFromFile(assemblyLocation));
|
||||||
});
|
});
|
||||||
var content = "public class MyTestType {}";
|
var content = "public class MyTestType {}";
|
||||||
var compilationService = new DefaultRoslynCompilationService(
|
var compilationService = new TestableRoslynCompilationService(
|
||||||
dependencyContext: null,
|
dependencyContext: null,
|
||||||
viewEngineOptions: options,
|
viewEngineOptions: options,
|
||||||
fileProviderAccessor: GetFileProviderAccessor(),
|
fileProviderAccessor: GetFileProviderAccessor());
|
||||||
loggerFactory: NullLoggerFactory.Instance);
|
|
||||||
|
|
||||||
var relativeFileInfo = new RelativeFileInfo(
|
var relativeFileInfo = new RelativeFileInfo(
|
||||||
new TestFileInfo { PhysicalPath = "SomePath" },
|
new TestFileInfo { PhysicalPath = "SomePath" },
|
||||||
|
|
@ -422,5 +413,33 @@ public class MyNonCustomDefinedClass {}
|
||||||
var assembly = typeof(DefaultRoslynCompilationServiceTest).GetTypeInfo().Assembly;
|
var assembly = typeof(DefaultRoslynCompilationServiceTest).GetTypeInfo().Assembly;
|
||||||
return DependencyContext.Load(assembly);
|
return DependencyContext.Load(assembly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class TestableRoslynCompilationService : DefaultRoslynCompilationService
|
||||||
|
{
|
||||||
|
private readonly DependencyContext _dependencyContext;
|
||||||
|
|
||||||
|
public TestableRoslynCompilationService(
|
||||||
|
DependencyContext dependencyContext,
|
||||||
|
RazorViewEngineOptions viewEngineOptions,
|
||||||
|
IRazorViewEngineFileProviderAccessor fileProviderAccessor)
|
||||||
|
: base(
|
||||||
|
Mock.Of<IHostingEnvironment>(),
|
||||||
|
GetAccessor(viewEngineOptions),
|
||||||
|
fileProviderAccessor,
|
||||||
|
NullLoggerFactory.Instance)
|
||||||
|
{
|
||||||
|
_dependencyContext = dependencyContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IOptions<RazorViewEngineOptions> GetAccessor(RazorViewEngineOptions options)
|
||||||
|
{
|
||||||
|
var optionsAccessor = new Mock<IOptions<RazorViewEngineOptions>>();
|
||||||
|
optionsAccessor.SetupGet(a => a.Value).Returns(options);
|
||||||
|
return optionsAccessor.Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override DependencyContext GetDependencyContext(IHostingEnvironment hostingEnvironment)
|
||||||
|
=> _dependencyContext;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue