compilation.Emit(..) 使用构造函数参数创建 typeOf(T)
compilation.Emit(..) create typeOf(T) with constructor params
我正在使用 RazorEngine
进行 Razor 模板解析并尝试使用其 Roslyn 代码。
我知道我的问题是我在我的 razor 视图中使用了一个基本类型 (ViewBase<t>
),但它没有被构造(因为它有一个 ctor 参数)。
然而,经过大量谷歌搜索后,我无法找到一种方法来告诉 Emit()
如何创建我的类型的实例。
下面是它使用的代码 - 源代码生成很好,下面包含一个省略的版本。
有没有我可以提供的某种工厂,它可以用来生成这种类型?
当我调用 emit 时出现错误 There is no argument given that corresponds to the required formal parameter 'componentContext' of 'ViewBase<MyModelType>.ViewBase(IComponentContext)'
- 那么我如何告诉 emit() 如何创建我的类型的实例 ViewBase<T>
创建一个空的 CTOR 工作正常 - 但不是我所需要的。
public override Tuple<Type, CompilationData> CompileType(TypeContext context)
{
var sourceCode = GetCodeCompileUnit(context);
var assemblyName = GetAssemblyName(context);
(new PermissionSet(PermissionState.Unrestricted)).Assert();
var tempDir = GetTemporaryDirectory();
var sourceCodeFile = Path.Combine(tempDir, String.Format("{0}.{1}", assemblyName, SourceFileExtension));
File.WriteAllText(sourceCodeFile, sourceCode);
var references = GetAllReferences(context);
var compilation =
GetEmptyCompilation(assemblyName)
.AddSyntaxTrees(
GetSyntaxTree(sourceCode, sourceCodeFile))
.AddReferences(GetMetadataReferences(references));
compilation =
compilation
.WithOptions(
CreateOptions(context)
.WithOutputKind(OutputKind.DynamicallyLinkedLibrary)
.WithPlatform(Platform.AnyCpu)
.WithSourceReferenceResolver(new RazorEngineSourceReferenceResolver(sourceCodeFile)));
var assemblyFile = Path.Combine(tempDir, String.Format("{0}.dll", assemblyName));
var assemblyPdbFile = Path.Combine(tempDir, String.Format("{0}.pdb", assemblyName));
var compilationData = new CompilationData(sourceCode, tempDir);
using (var assemblyStream = File.Open(assemblyFile, FileMode.Create, FileAccess.ReadWrite))
using (var pdbStream = File.Open(assemblyPdbFile, FileMode.Create, FileAccess.ReadWrite))
{
var opts = new EmitOptions()
.WithPdbFilePath(assemblyPdbFile);
var pdbStreamHelper = pdbStream;
if (IsMono())
{
opts = opts.WithDebugInformationFormat(DebugInformationFormat.PortablePdb);
}
var result = compilation.Emit(assemblyStream, pdbStreamHelper, options: opts);
}
}
我生成的查看代码
namespace CompiledRazorTemplates.Dynamic
{
#line default
#line hidden
;
using System;
//my load of other using statements...
public class RazorEngine_99d043dd3e3d4c3ca787d42dd7a0bb6b : ViewBase<MyModelType>
{
#line hidden
public RazorEngine_99d043dd3e3d4c3ca787d42dd7a0bb6b()
{
}
#pragma warning disable 1998
public override async Task Execute()
{
..... OMITTED
}
}
}
public ViewBase(IComponentContext componentContext)
{
Contract.Requires(componentContext != null);
_componentContext = componentContext;
}
您问的是 Razor 编译器,而不是 Roslyn 编译。
我认为没有办法做到这一点。
但是,您可以使用 Roslyn CSharpSyntaxRewriter
在 SyntaxTree
中找到现有的构造函数并重写它以具有并传递参数。
我正在使用 RazorEngine
进行 Razor 模板解析并尝试使用其 Roslyn 代码。
我知道我的问题是我在我的 razor 视图中使用了一个基本类型 (ViewBase<t>
),但它没有被构造(因为它有一个 ctor 参数)。
然而,经过大量谷歌搜索后,我无法找到一种方法来告诉 Emit()
如何创建我的类型的实例。
下面是它使用的代码 - 源代码生成很好,下面包含一个省略的版本。
有没有我可以提供的某种工厂,它可以用来生成这种类型?
当我调用 emit 时出现错误 There is no argument given that corresponds to the required formal parameter 'componentContext' of 'ViewBase<MyModelType>.ViewBase(IComponentContext)'
- 那么我如何告诉 emit() 如何创建我的类型的实例 ViewBase<T>
创建一个空的 CTOR 工作正常 - 但不是我所需要的。
public override Tuple<Type, CompilationData> CompileType(TypeContext context)
{
var sourceCode = GetCodeCompileUnit(context);
var assemblyName = GetAssemblyName(context);
(new PermissionSet(PermissionState.Unrestricted)).Assert();
var tempDir = GetTemporaryDirectory();
var sourceCodeFile = Path.Combine(tempDir, String.Format("{0}.{1}", assemblyName, SourceFileExtension));
File.WriteAllText(sourceCodeFile, sourceCode);
var references = GetAllReferences(context);
var compilation =
GetEmptyCompilation(assemblyName)
.AddSyntaxTrees(
GetSyntaxTree(sourceCode, sourceCodeFile))
.AddReferences(GetMetadataReferences(references));
compilation =
compilation
.WithOptions(
CreateOptions(context)
.WithOutputKind(OutputKind.DynamicallyLinkedLibrary)
.WithPlatform(Platform.AnyCpu)
.WithSourceReferenceResolver(new RazorEngineSourceReferenceResolver(sourceCodeFile)));
var assemblyFile = Path.Combine(tempDir, String.Format("{0}.dll", assemblyName));
var assemblyPdbFile = Path.Combine(tempDir, String.Format("{0}.pdb", assemblyName));
var compilationData = new CompilationData(sourceCode, tempDir);
using (var assemblyStream = File.Open(assemblyFile, FileMode.Create, FileAccess.ReadWrite))
using (var pdbStream = File.Open(assemblyPdbFile, FileMode.Create, FileAccess.ReadWrite))
{
var opts = new EmitOptions()
.WithPdbFilePath(assemblyPdbFile);
var pdbStreamHelper = pdbStream;
if (IsMono())
{
opts = opts.WithDebugInformationFormat(DebugInformationFormat.PortablePdb);
}
var result = compilation.Emit(assemblyStream, pdbStreamHelper, options: opts);
}
}
我生成的查看代码
namespace CompiledRazorTemplates.Dynamic
{
#line default
#line hidden
;
using System;
//my load of other using statements...
public class RazorEngine_99d043dd3e3d4c3ca787d42dd7a0bb6b : ViewBase<MyModelType>
{
#line hidden
public RazorEngine_99d043dd3e3d4c3ca787d42dd7a0bb6b()
{
}
#pragma warning disable 1998
public override async Task Execute()
{
..... OMITTED
}
}
}
public ViewBase(IComponentContext componentContext)
{
Contract.Requires(componentContext != null);
_componentContext = componentContext;
}
您问的是 Razor 编译器,而不是 Roslyn 编译。
我认为没有办法做到这一点。
但是,您可以使用 Roslyn CSharpSyntaxRewriter
在 SyntaxTree
中找到现有的构造函数并重写它以具有并传递参数。