diff --git a/README.md b/README.md
index 92d19c5b..93dbce00 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ To change this file edit the source file and then run MarkdownSnippets.
Use Razor to build templates from Files / EmbeddedResources / Strings / Database or your custom source outside of ASP.NET MVC. No redundant dependencies and workarounds in pair with excellent performance and **.NET Standard 2.0** and **.NET Core 3.0** support.

- [](https://www.nuget.org/packages/RazorLight/) [](https://www.nuget.org/packages/RazorLight/) [](https://gitter.im/Razor-Light)
+[](https://www.nuget.org/packages/RazorLight/) [](https://www.nuget.org/packages/RazorLight/) [](https://gitter.im/Razor-Light)
# Solidarity with Ukraine

@@ -18,8 +18,6 @@ Dear friends, my name is Ivan, I am the guy who created this library. I live in
*Update:* it's been a long time since I first posted this message. Thank you for your enormous support, I am removing my volunteer donation account and instead providing you with the largest and proven charity organization in Ukraine - [ComeBackAlive](https://savelife.in.ua/en/donate-en/). If you have the possibility and desire to help Ukraine - that is the right place for your valuable donations. Thank you. Be safe
-
-
# Table of contents
- [Quickstart](#quickstart)
- [Template sources](#template-sources)
@@ -41,8 +39,8 @@ Install-Package RazorLight -Version 2.3.0
The simplest scenario is to create a template from string. Each template must have a ````templateKey```` that is associated with it, so you can render the same template next time without recompilation.
-
-
+
+
```cs
var engine = new RazorLightEngineBuilder()
// required to have a default RazorLightProject type,
@@ -57,13 +55,13 @@ ViewModel model = new ViewModel {Name = "John Doe"};
string result = await engine.CompileRenderStringAsync("templateKey", template, model);
```
-snippet source | anchor
+snippet source | anchor
To render a compiled template:
-
+
```cs
var cacheResult = engine.Handler.Cache.RetrieveTemplate("templateKey");
if(cacheResult.Success)
@@ -72,7 +70,7 @@ if(cacheResult.Success)
string result = await engine.RenderTemplateAsync(templatePage, model);
}
```
-snippet source | anchor
+snippet source | anchor
# Template sources
@@ -84,7 +82,7 @@ RazorLight can resolve templates from any source, but there are a built-in provi
When resolving a template from filesystem, templateKey - is a relative path to the root folder, that you pass to RazorLightEngineBuilder.
-
+
```cs
var engine = new RazorLightEngineBuilder()
.UseFileSystemProject("C:/RootFolder/With/YourTemplates")
@@ -94,7 +92,7 @@ var engine = new RazorLightEngineBuilder()
var model = new {Name = "John Doe"};
string result = await engine.CompileRenderAsync("Subfolder/View.cshtml", model);
```
-snippet source | anchor
+snippet source | anchor
## EmbeddedResource source
@@ -115,7 +113,7 @@ Project.Core/
````
-
+
```cs
var engine = new RazorLightEngineBuilder()
.UseEmbeddedResourcesProject(typeof(SomeService).Assembly)
@@ -125,13 +123,13 @@ var engine = new RazorLightEngineBuilder()
var model = new Model();
string html = await engine.CompileRenderAsync("EmailTemplates.Body", model);
```
-snippet source | anchor
+snippet source | anchor
Setting the root namespace allows you to leave that piece off when providing the template name as the key:
-
+
```cs
var engine = new RazorLightEngineBuilder()
.UseEmbeddedResourcesProject(typeof(SomeService).Assembly, "Project.Core.EmailTemplates")
@@ -141,7 +139,7 @@ var engine = new RazorLightEngineBuilder()
var model = new Model();
string html = await engine.CompileRenderAsync("Body", model);
```
-snippet source | anchor
+snippet source | anchor
## Custom source
diff --git a/README.source.md b/README.source.md
index aa0a1642..abb5b843 100644
--- a/README.source.md
+++ b/README.source.md
@@ -32,7 +32,7 @@ Install-Package RazorLight -Version 2.3.0
The simplest scenario is to create a template from string. Each template must have a ````templateKey```` that is associated with it, so you can render the same template next time without recompilation.
-snippet: simple
+snippet: Simple
To render a compiled template:
diff --git a/samples/RazorLight.Samples/Samples.EntityFrameworkProject.csproj b/samples/RazorLight.Samples/Samples.EntityFrameworkProject.csproj
index cdea2c30..18656313 100644
--- a/samples/RazorLight.Samples/Samples.EntityFrameworkProject.csproj
+++ b/samples/RazorLight.Samples/Samples.EntityFrameworkProject.csproj
@@ -2,28 +2,30 @@
Exe
- netcoreapp2.1;netcoreapp3.1;net5.0
+ net8.0
true
false
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
-
+
diff --git a/sandbox/RazorLight.Sandbox/RazorLight.Sandbox.csproj b/sandbox/RazorLight.Sandbox/RazorLight.Sandbox.csproj
index b8515886..88ebf5ac 100644
--- a/sandbox/RazorLight.Sandbox/RazorLight.Sandbox.csproj
+++ b/sandbox/RazorLight.Sandbox/RazorLight.Sandbox.csproj
@@ -2,7 +2,7 @@
Exe
- netcoreapp3.1
+ net8.0
true
false
@@ -32,6 +32,13 @@
+
+
+
+
+
+
+
@@ -39,4 +46,8 @@
+
+
+
+
diff --git a/src/RazorLight.Precompile/RazorLight.Precompile.csproj b/src/RazorLight.Precompile/RazorLight.Precompile.csproj
index 55d5c9ea..6653d941 100644
--- a/src/RazorLight.Precompile/RazorLight.Precompile.csproj
+++ b/src/RazorLight.Precompile/RazorLight.Precompile.csproj
@@ -2,7 +2,7 @@
Exe
- net6.0
+ net8.0
razorlight-precompile
true
true
@@ -12,8 +12,14 @@
-
-
+
+
+
+
+
+
+
+
diff --git a/src/RazorLight/Compilation/RoslynCompilationService.cs b/src/RazorLight/Compilation/RoslynCompilationService.cs
index 2d9c1bf2..0858c15f 100644
--- a/src/RazorLight/Compilation/RoslynCompilationService.cs
+++ b/src/RazorLight/Compilation/RoslynCompilationService.cs
@@ -1,260 +1,260 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp;
-using Microsoft.CodeAnalysis.Emit;
-using Microsoft.CodeAnalysis.Text;
-using Microsoft.Extensions.DependencyModel;
-using Microsoft.Extensions.Options;
-using RazorLight.Generation;
-using RazorLight.Internal;
-using DependencyContextCompilationOptions = Microsoft.Extensions.DependencyModel.CompilationOptions;
-
-namespace RazorLight.Compilation
-{
- public class RoslynCompilationService : ICompilationService
- {
- private readonly IMetadataReferenceManager metadataReferenceManager;
- private readonly bool isDevelopment;
- private readonly List metadataReferences = new List();
- private readonly IPrecompileCallback precompileCallback;
-
- public RoslynCompilationService(IMetadataReferenceManager referenceManager, Assembly operatingAssembly, IPrecompileCallback precompileCallback = null)
- {
- this.metadataReferenceManager = referenceManager ?? throw new ArgumentNullException(nameof(referenceManager));
- this.OperatingAssembly = operatingAssembly ?? throw new ArgumentNullException(nameof(operatingAssembly));
- this.precompileCallback = precompileCallback;
-
- isDevelopment = AssemblyDebugModeUtility.IsAssemblyDebugBuild(OperatingAssembly);
- var pdbFormat = SymbolsUtility.SupportsFullPdbGeneration() ?
- DebugInformationFormat.Pdb :
- DebugInformationFormat.PortablePdb;
-
- EmitOptions = new EmitOptions(debugInformationFormat: pdbFormat);
- }
-
- public RoslynCompilationService(IMetadataReferenceManager referenceManager, IOptions options, IPrecompileCallback precompileCallback = null) :
- this(referenceManager, options.Value.OperatingAssembly, precompileCallback)
- {
-
- }
-
- #region Options
-
- public virtual Assembly OperatingAssembly { get; }
-
- public virtual EmitOptions EmitOptions { get; }
- public virtual CSharpCompilationOptions CSharpCompilationOptions
- {
- get
- {
- EnsureOptions();
- return _compilationOptions;
- }
- }
- public virtual CSharpParseOptions ParseOptions
- {
- get
- {
- EnsureOptions();
- return _parseOptions;
- }
- }
-
- #endregion
-
- private CSharpParseOptions _parseOptions;
- private CSharpCompilationOptions _compilationOptions;
-
- private static readonly object locker = new object();
-
- private bool _optionsInitialized;
- private void EnsureOptions()
- {
- lock (locker)
- {
- if (!_optionsInitialized)
- {
- var dependencyContextOptions = GetDependencyContextCompilationOptions();
- _parseOptions = GetParseOptions(dependencyContextOptions);
- _compilationOptions = GetCompilationOptions(dependencyContextOptions);
-
- metadataReferences.AddRange(metadataReferenceManager.Resolve(OperatingAssembly));
-
- _optionsInitialized = true;
- }
- }
- }
-
-
- public Assembly CompileAndEmit(IGeneratedRazorTemplate razorTemplate)
- {
- if (razorTemplate == null)
- {
- throw new ArgumentNullException(nameof(razorTemplate));
- }
-
- string assemblyName = Path.GetRandomFileName();
- var compilation = CreateCompilation(razorTemplate.GeneratedCode, assemblyName);
-
- using (var assemblyStream = new MemoryStream())
- using (var pdbStream = new MemoryStream())
- {
- var result = compilation.Emit(
- assemblyStream,
- pdbStream,
- options: EmitOptions);
-
- if (!result.Success)
- {
- List errorsDiagnostics = result.Diagnostics
- .Where(d => d.IsWarningAsError || d.Severity == DiagnosticSeverity.Error)
- .ToList();
-
- StringBuilder builder = new StringBuilder();
- builder.AppendLine("Failed to compile generated Razor template:");
-
- var compilationDiagnostics = new List();
-
- foreach (Diagnostic diagnostic in errorsDiagnostics)
- {
- FileLinePositionSpan lineSpan = diagnostic.Location.SourceTree.GetMappedLineSpan(diagnostic.Location.SourceSpan);
- string errorMessage = diagnostic.GetMessage();
- string formattedMessage = $"- ({lineSpan.StartLinePosition.Line}:{lineSpan.StartLinePosition.Character}) {errorMessage}";
-
- var compilationDiagnostic = new TemplateCompilationDiagnostic(errorMessage, formattedMessage, lineSpan);
- compilationDiagnostics.Add(compilationDiagnostic);
-
- builder.AppendLine(formattedMessage);
- }
-
- builder.AppendLine("\nSee CompilationErrors for detailed information");
-
- throw new TemplateCompilationException(builder.ToString(),compilationDiagnostics);
- }
-
- assemblyStream.Seek(0, SeekOrigin.Begin);
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.Emit;
+using Microsoft.CodeAnalysis.Text;
+using Microsoft.Extensions.DependencyModel;
+using Microsoft.Extensions.Options;
+using RazorLight.Generation;
+using RazorLight.Internal;
+using DependencyContextCompilationOptions = Microsoft.Extensions.DependencyModel.CompilationOptions;
+
+namespace RazorLight.Compilation
+{
+ public class RoslynCompilationService : ICompilationService
+ {
+ private readonly IMetadataReferenceManager metadataReferenceManager;
+ private readonly bool isDevelopment;
+ private readonly List metadataReferences = new List();
+ private readonly IPrecompileCallback precompileCallback;
+
+ public RoslynCompilationService(IMetadataReferenceManager referenceManager, Assembly operatingAssembly, IPrecompileCallback precompileCallback = null)
+ {
+ this.metadataReferenceManager = referenceManager ?? throw new ArgumentNullException(nameof(referenceManager));
+ this.OperatingAssembly = operatingAssembly ?? throw new ArgumentNullException(nameof(operatingAssembly));
+ this.precompileCallback = precompileCallback;
+
+ isDevelopment = AssemblyDebugModeUtility.IsAssemblyDebugBuild(OperatingAssembly);
+ var pdbFormat = SymbolsUtility.SupportsFullPdbGeneration() ?
+ DebugInformationFormat.Pdb :
+ DebugInformationFormat.PortablePdb;
+
+ EmitOptions = new EmitOptions(debugInformationFormat: pdbFormat);
+ }
+
+ public RoslynCompilationService(IMetadataReferenceManager referenceManager, IOptions options, IPrecompileCallback precompileCallback = null) :
+ this(referenceManager, options.Value.OperatingAssembly, precompileCallback)
+ {
+
+ }
+
+ #region Options
+
+ public virtual Assembly OperatingAssembly { get; }
+
+ public virtual EmitOptions EmitOptions { get; }
+ public virtual CSharpCompilationOptions CSharpCompilationOptions
+ {
+ get
+ {
+ EnsureOptions();
+ return _compilationOptions;
+ }
+ }
+ public virtual CSharpParseOptions ParseOptions
+ {
+ get
+ {
+ EnsureOptions();
+ return _parseOptions;
+ }
+ }
+
+ #endregion
+
+ private CSharpParseOptions _parseOptions;
+ private CSharpCompilationOptions _compilationOptions;
+
+ private static readonly object locker = new object();
+
+ private bool _optionsInitialized;
+ private void EnsureOptions()
+ {
+ lock (locker)
+ {
+ if (!_optionsInitialized)
+ {
+ var dependencyContextOptions = GetDependencyContextCompilationOptions();
+ _parseOptions = GetParseOptions(dependencyContextOptions);
+ _compilationOptions = GetCompilationOptions(dependencyContextOptions);
+
+ metadataReferences.AddRange(metadataReferenceManager.Resolve(OperatingAssembly));
+
+ _optionsInitialized = true;
+ }
+ }
+ }
+
+
+ public Assembly CompileAndEmit(IGeneratedRazorTemplate razorTemplate)
+ {
+ if (razorTemplate == null)
+ {
+ throw new ArgumentNullException(nameof(razorTemplate));
+ }
+
+ string assemblyName = Path.GetRandomFileName();
+ var compilation = CreateCompilation(razorTemplate.GeneratedCode, assemblyName);
+
+ using (var assemblyStream = new MemoryStream())
+ using (var pdbStream = new MemoryStream())
+ {
+ var result = compilation.Emit(
+ assemblyStream,
+ pdbStream,
+ options: EmitOptions);
+
+ if (!result.Success)
+ {
+ List errorsDiagnostics = result.Diagnostics
+ .Where(d => d.IsWarningAsError || d.Severity == DiagnosticSeverity.Error)
+ .ToList();
+
+ StringBuilder builder = new StringBuilder();
+ builder.AppendLine("Failed to compile generated Razor template:");
+
+ var compilationDiagnostics = new List();
+
+ foreach (Diagnostic diagnostic in errorsDiagnostics)
+ {
+ FileLinePositionSpan lineSpan = diagnostic.Location.SourceTree.GetMappedLineSpan(diagnostic.Location.SourceSpan);
+ string errorMessage = diagnostic.GetMessage();
+ string formattedMessage = $"- ({lineSpan.StartLinePosition.Line}:{lineSpan.StartLinePosition.Character}) {errorMessage}";
+
+ var compilationDiagnostic = new TemplateCompilationDiagnostic(errorMessage, formattedMessage, lineSpan);
+ compilationDiagnostics.Add(compilationDiagnostic);
+
+ builder.AppendLine(formattedMessage);
+ }
+
+ builder.AppendLine("\nSee CompilationErrors for detailed information");
+
+ throw new TemplateCompilationException(builder.ToString(),compilationDiagnostics);
+ }
+
+ assemblyStream.Seek(0, SeekOrigin.Begin);
pdbStream.Seek(0, SeekOrigin.Begin);
var rawAssembly = assemblyStream.ToArray();
var rawSymbolStore = pdbStream.ToArray();
precompileCallback?.Invoke(razorTemplate, rawAssembly, rawSymbolStore);
- var assembly = Assembly.Load(rawAssembly, rawSymbolStore);
-
- return assembly;
- }
- }
-
- protected internal virtual DependencyContextCompilationOptions GetDependencyContextCompilationOptions()
- {
- var dependencyContext = DependencyContext.Load(OperatingAssembly);
-
- if (dependencyContext?.CompilationOptions != null)
- {
- return dependencyContext.CompilationOptions;
- }
-
- return DependencyContextCompilationOptions.Default;
- }
-
- private CSharpCompilation CreateCompilation(string compilationContent, string assemblyName)
- {
- SourceText sourceText = SourceText.From(compilationContent, Encoding.UTF8);
- SyntaxTree syntaxTree = CreateSyntaxTree(sourceText).WithFilePath(assemblyName);
-
- CSharpCompilation compilation = CreateCompilation(assemblyName).AddSyntaxTrees(syntaxTree);
-
- compilation = ExpressionRewriter.Rewrite(compilation);
-
- //var compilationContext = new RoslynCompilationContext(compilation);
- //_compilationCallback(compilationContext);
- //compilation = compilationContext.Compilation;
- return compilation;
- }
-
- public CSharpCompilation CreateCompilation(string assemblyName)
- {
- return CSharpCompilation.Create(
- assemblyName,
- options: CSharpCompilationOptions,
- references: metadataReferences);
- }
-
- public SyntaxTree CreateSyntaxTree(SourceText sourceText)
- {
- return CSharpSyntaxTree.ParseText(sourceText, options: ParseOptions);
- }
-
- private CSharpCompilationOptions GetCompilationOptions(DependencyContextCompilationOptions dependencyContextOptions)
- {
- var csharpCompilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
-
- // Disable 1702 until roslyn turns this off by default
- csharpCompilationOptions = csharpCompilationOptions.WithSpecificDiagnosticOptions(
- new Dictionary
- {
- {"CS1701", ReportDiagnostic.Suppress}, // Binding redirects
- {"CS1702", ReportDiagnostic.Suppress},
- {"CS1705", ReportDiagnostic.Suppress}
- });
-
- if (dependencyContextOptions.AllowUnsafe.HasValue)
- {
- csharpCompilationOptions = csharpCompilationOptions.WithAllowUnsafe(
- dependencyContextOptions.AllowUnsafe.Value);
- }
-
- OptimizationLevel optimizationLevel;
- if (dependencyContextOptions.Optimize.HasValue)
- {
- optimizationLevel = dependencyContextOptions.Optimize.Value ?
- OptimizationLevel.Release :
- OptimizationLevel.Debug;
- }
- else
- {
- optimizationLevel = isDevelopment ?
- OptimizationLevel.Debug :
- OptimizationLevel.Release;
- }
- csharpCompilationOptions = csharpCompilationOptions.WithOptimizationLevel(optimizationLevel);
-
- if (dependencyContextOptions.WarningsAsErrors.HasValue)
- {
- var reportDiagnostic = dependencyContextOptions.WarningsAsErrors.Value ?
- ReportDiagnostic.Error :
- ReportDiagnostic.Default;
- csharpCompilationOptions = csharpCompilationOptions.WithGeneralDiagnosticOption(reportDiagnostic);
- }
-
- return csharpCompilationOptions;
- }
-
- private CSharpParseOptions GetParseOptions(DependencyContextCompilationOptions dependencyContextOptions)
- {
- var configurationSymbol = isDevelopment ? "DEBUG" : "RELEASE";
- var defines = dependencyContextOptions.Defines.Concat(new[] { configurationSymbol });
-
- var parseOptions = new CSharpParseOptions(preprocessorSymbols: defines);
-
- if (!string.IsNullOrEmpty(dependencyContextOptions.LanguageVersion))
- {
- if (LanguageVersionFacts.TryParse(dependencyContextOptions.LanguageVersion, out var languageVersion))
- {
- parseOptions = parseOptions.WithLanguageVersion(languageVersion);
- }
- else
- {
- Debug.Fail($"LanguageVersion {dependencyContextOptions.LanguageVersion} specified in the deps file could not be parsed.");
- }
- }
-
- return parseOptions;
- }
- }
-}
+ var assembly = Assembly.Load(rawAssembly, rawSymbolStore);
+
+ return assembly;
+ }
+ }
+
+ protected internal virtual DependencyContextCompilationOptions GetDependencyContextCompilationOptions()
+ {
+ var dependencyContext = DependencyContext.Load(OperatingAssembly);
+
+ if (dependencyContext?.CompilationOptions != null)
+ {
+ return dependencyContext.CompilationOptions;
+ }
+
+ return DependencyContextCompilationOptions.Default;
+ }
+
+ private CSharpCompilation CreateCompilation(string compilationContent, string assemblyName)
+ {
+ SourceText sourceText = SourceText.From(compilationContent, Encoding.UTF8);
+ SyntaxTree syntaxTree = CreateSyntaxTree(sourceText).WithFilePath(assemblyName);
+
+ CSharpCompilation compilation = CreateCompilation(assemblyName).AddSyntaxTrees(syntaxTree);
+
+ compilation = ExpressionRewriter.Rewrite(compilation);
+
+ //var compilationContext = new RoslynCompilationContext(compilation);
+ //_compilationCallback(compilationContext);
+ //compilation = compilationContext.Compilation;
+ return compilation;
+ }
+
+ public CSharpCompilation CreateCompilation(string assemblyName)
+ {
+ return CSharpCompilation.Create(
+ assemblyName,
+ options: CSharpCompilationOptions,
+ references: metadataReferences);
+ }
+
+ public SyntaxTree CreateSyntaxTree(SourceText sourceText)
+ {
+ return CSharpSyntaxTree.ParseText(sourceText, options: ParseOptions);
+ }
+
+ private CSharpCompilationOptions GetCompilationOptions(DependencyContextCompilationOptions dependencyContextOptions)
+ {
+ var csharpCompilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
+
+ // Disable 1702 until roslyn turns this off by default
+ csharpCompilationOptions = csharpCompilationOptions.WithSpecificDiagnosticOptions(
+ new Dictionary
+ {
+ {"CS1701", ReportDiagnostic.Suppress}, // Binding redirects
+ {"CS1702", ReportDiagnostic.Suppress},
+ {"CS1705", ReportDiagnostic.Suppress}
+ });
+
+ if (dependencyContextOptions.AllowUnsafe.HasValue)
+ {
+ csharpCompilationOptions = csharpCompilationOptions.WithAllowUnsafe(
+ dependencyContextOptions.AllowUnsafe.Value);
+ }
+
+ OptimizationLevel optimizationLevel;
+ if (dependencyContextOptions.Optimize.HasValue)
+ {
+ optimizationLevel = dependencyContextOptions.Optimize.Value ?
+ OptimizationLevel.Release :
+ OptimizationLevel.Debug;
+ }
+ else
+ {
+ optimizationLevel = isDevelopment ?
+ OptimizationLevel.Debug :
+ OptimizationLevel.Release;
+ }
+ csharpCompilationOptions = csharpCompilationOptions.WithOptimizationLevel(optimizationLevel);
+
+ if (dependencyContextOptions.WarningsAsErrors.HasValue)
+ {
+ var reportDiagnostic = dependencyContextOptions.WarningsAsErrors.Value ?
+ ReportDiagnostic.Error :
+ ReportDiagnostic.Default;
+ csharpCompilationOptions = csharpCompilationOptions.WithGeneralDiagnosticOption(reportDiagnostic);
+ }
+
+ return csharpCompilationOptions;
+ }
+
+ private CSharpParseOptions GetParseOptions(DependencyContextCompilationOptions dependencyContextOptions)
+ {
+ var configurationSymbol = isDevelopment ? "DEBUG" : "RELEASE";
+ var defines = dependencyContextOptions.Defines.Concat(new[] { configurationSymbol });
+
+ var parseOptions = new CSharpParseOptions(preprocessorSymbols: defines);
+
+ if (!string.IsNullOrEmpty(dependencyContextOptions.LanguageVersion))
+ {
+ if (LanguageVersionFacts.TryParse(dependencyContextOptions.LanguageVersion, out var languageVersion))
+ {
+ parseOptions = parseOptions.WithLanguageVersion(languageVersion);
+ }
+ else
+ {
+ Debug.Fail($"LanguageVersion {dependencyContextOptions.LanguageVersion} specified in the deps file could not be parsed.");
+ }
+ }
+
+ return parseOptions;
+ }
+ }
+}
diff --git a/src/RazorLight/Razor/FileSystemRazorProject.cs b/src/RazorLight/Razor/FileSystemRazorProject.cs
index 46e4a248..1b156000 100644
--- a/src/RazorLight/Razor/FileSystemRazorProject.cs
+++ b/src/RazorLight/Razor/FileSystemRazorProject.cs
@@ -1,106 +1,106 @@
-using Microsoft.Extensions.FileProviders;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
+using Microsoft.Extensions.FileProviders;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
using System.Text;
-using System.Threading.Tasks;
-
-namespace RazorLight.Razor
+using System.Threading.Tasks;
+
+namespace RazorLight.Razor
{
- ///
- /// Specifies RazorProject where templates are located in files
- ///
- public class FileSystemRazorProject : RazorLightProject
- {
- public const string DefaultExtension = ".cshtml";
- private readonly IFileProvider _fileProvider;
-
- public FileSystemRazorProject(string root)
- : this(root, DefaultExtension)
- {
- }
-
- public FileSystemRazorProject(string root, string extension)
- {
- Extension = extension ?? throw new ArgumentNullException(nameof(extension));
-
- if (!Directory.Exists(root))
- {
- throw new DirectoryNotFoundException($"Root directory {root} not found");
- }
-
- Root = root;
- _fileProvider = new PhysicalFileProvider(Root);
- }
-
- public string Extension { get; set; }
-
- ///
- /// Looks up for the template source with a given
- ///
- /// Unique template key
- ///
- public override Task GetItemAsync(string templateKey)
- {
- if (!templateKey.EndsWith(Extension))
- {
- templateKey = templateKey + Extension;
- }
-
- string absolutePath = GetAbsoluteFilePathFromKey(templateKey);
- var item = new FileSystemRazorProjectItem(templateKey, new FileInfo(absolutePath));
-
- if (item.Exists)
- {
- item.ExpirationToken = _fileProvider.Watch(templateKey);
- }
-
- return Task.FromResult((RazorLightProjectItem)item);
- }
-
- ///
- /// Root folder
- ///
- public string Root { get; }
-
- protected string GetAbsoluteFilePathFromKey(string templateKey)
- {
- if (string.IsNullOrEmpty(templateKey))
- {
- throw new ArgumentNullException(nameof(templateKey));
- }
-
- var absolutePath = templateKey;
- if (!absolutePath.StartsWith(Root, StringComparison.OrdinalIgnoreCase))
- {
- if (templateKey[0] == '/' || templateKey[0] == '\\')
- {
- templateKey = templateKey.Substring(1);
- }
-
- absolutePath = Path.Combine(Root, templateKey);
- }
-
- absolutePath = absolutePath.Replace('\\', '/');
-
- return absolutePath;
- }
-
- public override Task> GetImportsAsync(string templateKey)
- {
- return Task.FromResult(Enumerable.Empty());
- }
- public override Task> GetKnownKeysAsync()
- {
- var files = Directory.EnumerateFiles(Root, $"*{Extension}", SearchOption.AllDirectories)
- .Where(x => x.StartsWith(Root))
- .Select(x => x.Substring(Root.Length, x.Length - Root.Length))
- .Select(x => x.StartsWith("\\") || x.StartsWith("/") ? x.Substring(1) : x)
- .Select(x => x.Replace('\\', '/'));
-
- return Task.FromResult(files);
- }
- public override string NormalizeKey(string templateKey) => FileSystemRazorProjectHelper.NormalizeKey(templateKey);
- }
-}
+ ///
+ /// Specifies RazorProject where templates are located in files
+ ///
+ public class FileSystemRazorProject : RazorLightProject
+ {
+ public const string DefaultExtension = ".cshtml";
+ private readonly IFileProvider _fileProvider;
+
+ public FileSystemRazorProject(string root)
+ : this(root, DefaultExtension)
+ {
+ }
+
+ public FileSystemRazorProject(string root, string extension)
+ {
+ Extension = extension ?? throw new ArgumentNullException(nameof(extension));
+
+ if (!Directory.Exists(root))
+ {
+ throw new DirectoryNotFoundException($"Root directory {root} not found");
+ }
+
+ Root = root;
+ _fileProvider = new PhysicalFileProvider(Root);
+ }
+
+ public string Extension { get; set; }
+
+ ///
+ /// Looks up for the template source with a given
+ ///
+ /// Unique template key
+ ///
+ public override Task GetItemAsync(string templateKey)
+ {
+ if (!templateKey.EndsWith(Extension))
+ {
+ templateKey = templateKey + Extension;
+ }
+
+ string absolutePath = GetAbsoluteFilePathFromKey(templateKey);
+ var item = new FileSystemRazorProjectItem(templateKey, new FileInfo(absolutePath));
+
+ if (item.Exists)
+ {
+ item.ExpirationToken = _fileProvider.Watch(templateKey);
+ }
+
+ return Task.FromResult((RazorLightProjectItem)item);
+ }
+
+ ///
+ /// Root folder
+ ///
+ public string Root { get; }
+
+ protected string GetAbsoluteFilePathFromKey(string templateKey)
+ {
+ if (string.IsNullOrEmpty(templateKey))
+ {
+ throw new ArgumentNullException(nameof(templateKey));
+ }
+
+ var absolutePath = templateKey;
+ if (!absolutePath.StartsWith(Root, StringComparison.OrdinalIgnoreCase))
+ {
+ if (templateKey[0] == '/' || templateKey[0] == '\\')
+ {
+ templateKey = templateKey.Substring(1);
+ }
+
+ absolutePath = Path.Combine(Root, templateKey);
+ }
+
+ absolutePath = absolutePath.Replace('\\', '/');
+
+ return absolutePath;
+ }
+
+ public override Task> GetImportsAsync(string templateKey)
+ {
+ return Task.FromResult(Enumerable.Empty());
+ }
+ public override Task> GetKnownKeysAsync()
+ {
+ var files = Directory.EnumerateFiles(Root, $"*{Extension}", SearchOption.AllDirectories)
+ .Where(x => x.StartsWith(Root))
+ .Select(x => x.Substring(Root.Length, x.Length - Root.Length))
+ .Select(x => x.StartsWith("\\") || x.StartsWith("/") ? x.Substring(1) : x)
+ .Select(x => x.Replace('\\', '/'));
+
+ return Task.FromResult(files);
+ }
+ public override string NormalizeKey(string templateKey) => FileSystemRazorProjectHelper.NormalizeKey(templateKey);
+ }
+}
diff --git a/src/RazorLight/RazorLight.csproj b/src/RazorLight/RazorLight.csproj
index b3d95fd2..bd9fa97d 100644
--- a/src/RazorLight/RazorLight.csproj
+++ b/src/RazorLight/RazorLight.csproj
@@ -1,6 +1,6 @@
- netstandard2.0;netcoreapp3.1;net5.0;net6.0
+ net8.0
@@ -14,72 +14,18 @@
https://github.com/toddams/RazorLight
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/RazorLight.Precompile.Tests/FileSystemCachingStrategyTests.cs b/tests/RazorLight.Precompile.Tests/FileSystemCachingStrategyTests.cs
index 8ed30eee..f3d91d0f 100644
--- a/tests/RazorLight.Precompile.Tests/FileSystemCachingStrategyTests.cs
+++ b/tests/RazorLight.Precompile.Tests/FileSystemCachingStrategyTests.cs
@@ -1,4 +1,5 @@
using NUnit.Framework;
+using NUnit.Framework.Legacy;
using RazorLight.Caching;
using System.Runtime.InteropServices;
@@ -57,14 +58,14 @@ public void DifferentKey(IFileSystemCachingStrategy s)
var templateFilePath = "Samples/folder/MessageItem.cshtml";
var o1 = s.GetCachedFileInfo("folder/MessageItem.cshtml", templateFilePath, "X:/");
var o2 = s.GetCachedFileInfo("MessageItem.cshtml", templateFilePath, "X:/");
- Assert.AreNotEqual(o1.AssemblyFilePath, o2.AssemblyFilePath);
+ ClassicAssert.AreNotEqual(o1.AssemblyFilePath, o2.AssemblyFilePath);
}
[TestCaseSource(nameof(s_sepCombinations))]
public void EquivalentKeyFileHashCachingStrategy(string[] sepCombination)
{
var (asmFilePath1, asmFilePath2) = GetAsmFilePaths(FileHashCachingStrategy.Instance, sepCombination);
- Assert.AreEqual(asmFilePath1, asmFilePath2);
+ ClassicAssert.AreEqual(asmFilePath1, asmFilePath2);
}
[TestCaseSource(nameof(s_sepCombinations))]
@@ -76,7 +77,7 @@ public void EquivalentKeySimpleFileCachingStrategy(string[] sepCombination)
asmFilePath1 = Path.GetFullPath(asmFilePath1);
asmFilePath2 = Path.GetFullPath(asmFilePath2);
}
- Assert.AreEqual(asmFilePath1, asmFilePath2);
+ ClassicAssert.AreEqual(asmFilePath1, asmFilePath2);
}
private static (string, string) GetAsmFilePaths(IFileSystemCachingStrategy s, string[] sepCombination)
@@ -84,7 +85,7 @@ private static (string, string) GetAsmFilePaths(IFileSystemCachingStrategy s, st
var templateFilePath = "Samples/folder/MessageItem.cshtml";
string key1 = $"{sepCombination[0]}folder{sepCombination[1]}MessageItem.cshtml";
string key2 = $"{sepCombination[2]}folder{sepCombination[3]}MessageItem.cshtml";
- Assert.AreNotEqual(key1, key2);
+ ClassicAssert.AreNotEqual(key1, key2);
var asmFilePath1 = s.GetCachedFileInfo(key1, templateFilePath, "X:/").AssemblyFilePath;
var asmFilePath2 = s.GetCachedFileInfo(key2, templateFilePath, "X:/").AssemblyFilePath;
return (asmFilePath1, asmFilePath2);
diff --git a/tests/RazorLight.Precompile.Tests/Helper.cs b/tests/RazorLight.Precompile.Tests/Helper.cs
index 3a0d9db6..d21aa8f0 100644
--- a/tests/RazorLight.Precompile.Tests/Helper.cs
+++ b/tests/RazorLight.Precompile.Tests/Helper.cs
@@ -1,4 +1,5 @@
using NUnit.Framework;
+using NUnit.Framework.Legacy;
using System.Text;
namespace RazorLight.Precompile.Tests
@@ -17,7 +18,7 @@ public static StringBuilder RunCommand(params string[] args)
var sw = new StringWriter();
Program.ConsoleOut = sw;
var exitCode = Program.DoRun(args);
- Assert.Zero(exitCode);
+ ClassicAssert.Zero(exitCode);
sw.Close();
return sw.GetStringBuilder();
diff --git a/tests/RazorLight.Precompile.Tests/PrecompileTests.cs b/tests/RazorLight.Precompile.Tests/PrecompileTests.cs
index 1841c3ce..0e48e993 100644
--- a/tests/RazorLight.Precompile.Tests/PrecompileTests.cs
+++ b/tests/RazorLight.Precompile.Tests/PrecompileTests.cs
@@ -1,4 +1,5 @@
using NUnit.Framework;
+using NUnit.Framework.Legacy;
using System.Diagnostics;
namespace RazorLight.Precompile.Tests
@@ -60,7 +61,7 @@ public static void Precompile(string templateFilePath, TestScenario scenario, st
commandLineArgs.AddRange(scenario.ExtraCommandLineArgs);
var precompiledFilePath = Helper.RunCommandTrimNewline(commandLineArgs.ToArray());
- Assert.AreEqual(expectedPrecompiledFilePath, precompiledFilePath);
+ ClassicAssert.AreEqual(expectedPrecompiledFilePath, precompiledFilePath);
FileAssert.Exists(precompiledFilePath);
}
}
diff --git a/tests/RazorLight.Precompile.Tests/RazorLight.Precompile.Tests.csproj b/tests/RazorLight.Precompile.Tests/RazorLight.Precompile.Tests.csproj
index 73be2459..d537df08 100644
--- a/tests/RazorLight.Precompile.Tests/RazorLight.Precompile.Tests.csproj
+++ b/tests/RazorLight.Precompile.Tests/RazorLight.Precompile.Tests.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net8.0
true
enable
enable
@@ -9,9 +9,15 @@
-
-
-
+
+
+
+
+
+
+
+
+
@@ -31,4 +37,8 @@
+
+
+
+
diff --git a/tests/RazorLight.Precompile.Tests/Render1Tests.cs b/tests/RazorLight.Precompile.Tests/Render1Tests.cs
index fdd07545..c6ca1710 100644
--- a/tests/RazorLight.Precompile.Tests/Render1Tests.cs
+++ b/tests/RazorLight.Precompile.Tests/Render1Tests.cs
@@ -1,4 +1,5 @@
using NUnit.Framework;
+using NUnit.Framework.Legacy;
namespace RazorLight.Precompile.Tests
{
@@ -90,7 +91,7 @@ public void Render(string templateFilePath, string jsonQuery, string expected)
}
var actual = Helper.RunCommand(commandLineArgs.ToArray()).ToString();
- Assert.AreEqual(expected, actual);
+ ClassicAssert.AreEqual(expected, actual);
}
[TestCaseSource(nameof(s_testCases))]
@@ -112,7 +113,7 @@ public void PrecompileAndRender(string templateFilePath, string jsonQuery, strin
}
var actual = Helper.RunCommand(commandLineArgs.ToArray()).ToString();
- Assert.AreEqual(expected, actual);
+ ClassicAssert.AreEqual(expected, actual);
}
}
}
\ No newline at end of file
diff --git a/tests/RazorLight.Precompile.Tests/Render2Tests.cs b/tests/RazorLight.Precompile.Tests/Render2Tests.cs
index f6858946..c562d442 100644
--- a/tests/RazorLight.Precompile.Tests/Render2Tests.cs
+++ b/tests/RazorLight.Precompile.Tests/Render2Tests.cs
@@ -1,4 +1,5 @@
using NUnit.Framework;
+using NUnit.Framework.Legacy;
using RazorLight.Caching;
namespace RazorLight.Precompile.Tests
@@ -102,7 +103,7 @@ public void RenderFolderNonRecursive(string key, string key2, IFileSystemCaching
Precompile(key, key2, s);
var exc = Assert.Throws(() => Run(key, expected, "Samples"));
- Assert.AreEqual("No precompiled template found for the key /folder/MessageItem.cshtml", exc.Message);
+ ClassicAssert.AreEqual("No precompiled template found for the key /folder/MessageItem.cshtml", exc.Message);
}
[TestCaseSource(nameof(s_testCases))]
@@ -111,7 +112,7 @@ public void RenderGlobNonRecursive(string key, string key2, IFileSystemCachingSt
Precompile(key, key2, s);
var exc = Assert.Throws(() => Run(key, expected, "Samples/*.dll"));
- Assert.AreEqual("No precompiled template found for the key /folder/MessageItem.cshtml", exc.Message);
+ ClassicAssert.AreEqual("No precompiled template found for the key /folder/MessageItem.cshtml", exc.Message);
}
private static (string, string) Precompile(string key, string key2, IFileSystemCachingStrategy s) => (
@@ -134,7 +135,7 @@ private static void Run(string key, string expected, string precompiledFilePath,
commandLineArgs.AddRange(args);
var actual = Helper.RunCommand(commandLineArgs.ToArray()).ToString();
- Assert.AreEqual(expected, actual);
+ ClassicAssert.AreEqual(expected, actual);
}
[TestCaseSource(nameof(s_testCases))]
@@ -154,7 +155,7 @@ public void PrecompileAndRender(string templateFilePath, string _, IFileSystemCa
};
var actual = Helper.RunCommand(commandLineArgs.ToArray()).ToString();
- Assert.AreEqual(expected, actual);
+ ClassicAssert.AreEqual(expected, actual);
}
}
}
\ No newline at end of file
diff --git a/tests/RazorLight.Tests/Compilation/RazorTemplateCompilerTest.cs b/tests/RazorLight.Tests/Compilation/RazorTemplateCompilerTest.cs
index 280cebae..94ed6f87 100644
--- a/tests/RazorLight.Tests/Compilation/RazorTemplateCompilerTest.cs
+++ b/tests/RazorLight.Tests/Compilation/RazorTemplateCompilerTest.cs
@@ -117,14 +117,14 @@ public async Task Compiler_Searches_WithNormalizedKey_IfNotFound()
}
[Fact]
- public void Throws_TemplateNotFoundException_If_ProjectItem_NotExist()
+ public async void Throws_TemplateNotFoundException_If_ProjectItem_NotExist()
{
var project = new EmbeddedRazorProject(typeof(Root).Assembly);
var compiler = TestRazorTemplateCompiler.Create(project: project);
Func task = new Func(() => compiler.CompileAsync("Not.Existing.Key"));
- Assert.ThrowsAsync(task);
+ await Assert.ThrowsAsync(task);
}
[Fact]
diff --git a/tests/RazorLight.Tests/Integration/RendererCommonCasesTests.cs b/tests/RazorLight.Tests/Integration/RendererCommonCasesTests.cs
index 7c787eb9..21b37d4e 100644
--- a/tests/RazorLight.Tests/Integration/RendererCommonCasesTests.cs
+++ b/tests/RazorLight.Tests/Integration/RendererCommonCasesTests.cs
@@ -14,7 +14,7 @@ public class TestViewModel
public int NumberOfItems { get; set; }
}
- [UsesVerify]
+ //[UsesVerify]
public class RendererCommonCasesTests
{
diff --git a/tests/RazorLight.Tests/Razor/EmbeddedRazorProjectTest.cs b/tests/RazorLight.Tests/Razor/EmbeddedRazorProjectTest.cs
index 0d6521ed..4bf0816f 100644
--- a/tests/RazorLight.Tests/Razor/EmbeddedRazorProjectTest.cs
+++ b/tests/RazorLight.Tests/Razor/EmbeddedRazorProjectTest.cs
@@ -17,11 +17,11 @@ public void Ensure_Throws_OnNullRootType()
}
[Fact]
- public void Ensure_Throws_OnNullTemplateKey()
+ public async void Ensure_Throws_OnNullTemplateKey()
{
var project = new EmbeddedRazorProject(typeof(EmbeddedRazorProject));
- Assert.ThrowsAsync(async () => { await project.GetItemAsync(null); });
+ await Assert.ThrowsAsync(async () => { await project.GetItemAsync(null); });
}
[Fact]
diff --git a/tests/RazorLight.Tests/Razor/FileSystemRazorProjectTest.cs b/tests/RazorLight.Tests/Razor/FileSystemRazorProjectTest.cs
index f01b19cd..ccdc2add 100644
--- a/tests/RazorLight.Tests/Razor/FileSystemRazorProjectTest.cs
+++ b/tests/RazorLight.Tests/Razor/FileSystemRazorProjectTest.cs
@@ -50,11 +50,12 @@ public void Ensure_ExtensionProperty_AssignedOnConstructor()
}
[Fact]
- public void Null_TemplateKey_ThrowsOn_GetItem()
+ public async void Null_TemplateKey_ThrowsOn_GetItem()
{
var project = new FileSystemRazorProject(DirectoryUtils.RootDirectory);
- Assert.ThrowsAsync(async () => await project.GetItemAsync("not-existing-key"));
+ //Maybe you want to check if the file exists and then throw an exception if it doesn't?
+ await Assert.ThrowsAsync(async () => await project.GetItemAsync("not-existing-key"));
}
[Fact]
diff --git a/tests/RazorLight.Tests/RazorLight.Tests.csproj b/tests/RazorLight.Tests/RazorLight.Tests.csproj
index 524b10c5..56561604 100644
--- a/tests/RazorLight.Tests/RazorLight.Tests.csproj
+++ b/tests/RazorLight.Tests/RazorLight.Tests.csproj
@@ -1,80 +1,98 @@
-
-
-
- netcoreapp2.0;netcoreapp3.1;net5.0;net6.0
- false
- true
- $(DefineConstants);SOME_TEST_DEFINE
+
+
+
+ net8.0
+ false
+ true
+ $(DefineConstants);SOME_TEST_DEFINE
true
- NU1701;CS0618
-
-
-
- $(SolutionDir)
-
-
-
- true
-
-
-
- false
- true
-
-
-
-
-
-
-
-
-
-
- Always
-
-
-
-
-
-
-
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ NU1701;CS0618
+
+
+
+ $(SolutionDir)
+
+
+
+ true
+
+
+
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+