代码之家  ›  专栏  ›  技术社区  ›  Stuart.Sklinar

汇编发射(…)使用构造函数参数创建typeOf(T)

  •  0
  • Stuart.Sklinar  · 技术社区  · 7 年前

    我正在使用 RazorEngine 用于Razor模板解析并尝试使用其Roslyn代码。

    我知道我的问题是我使用的是基类型( ViewBase<t> )在我的razor视图中,它没有被构造(因为它有一个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;
    }
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   SLaks    7 年前

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

    我认为没有任何方法可以做到这一点。

    不过,你可以用Roslyn CSharpSyntaxRewriter 要在中查找现有构造函数 SyntaxTree 并将其重写为;传递参数。