【问题标题】:compilation.Emit(..) create typeOf(T) with constructor params编译.Emit(..) 使用构造函数参数创建 typeOf(T)
【发布时间】:2018-03-13 16:46:58
【问题描述】:

我正在使用 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 编译器生成一个 ctor 并使用参数调用您的基类 ctor?
  • 抱歉 - 是的,当我调用 emit 时,我收到错误 There is no argument given that corresponds to the required formal parameter 'componentContext' of 'ViewBase&lt;MyModelType&gt;.ViewBase(IComponentContext)' - 那么我将如何告诉 emit() 如何创建我的类型的实例 ViewBase&lt;T&gt; 创建一个空的 CTOR 有效很好 - 但不是我需要的。

标签: razor .net-core roslyn razorengine roslyn-code-analysis


【解决方案1】:

您问的是 Razor 编译器,而不是 Roslyn 编译。

我认为没有办法做到这一点。

但是,您可以使用 Roslyn CSharpSyntaxRewriter 在您的 SyntaxTree 中查找现有构造函数,并将其重写为具有并传递参数。

【讨论】:

  • 它目前有一个参数 - 我只需要让 Roslyn 传递所说的参数 - 如果我提供我的 viewBase...
  • 已更新 - 您的答案是否仍然适用?如果是这样,你有什么例子吗?谢谢
  • @Stuart.Sklinar:这正是我要说的。您应该在语法树中编辑 ctor。
  • 优秀。我会进一步研究它。谢谢
猜你喜欢
  • 2019-06-25
  • 1970-01-01
  • 2017-11-23
  • 1970-01-01
  • 2015-03-12
  • 1970-01-01
  • 1970-01-01
  • 2015-08-22
  • 1970-01-01
相关资源
最近更新 更多