升级到Razor 2/RE 3.2后,RazorEngine扩展方法因RuntimeBinderException而失败

Kei*_*ith 2 extension-methods razor razor-2

我有一个RazorEngine项目,在升级到Razor 2.0和RazorEngine 3.2.0之后失败了

这在之前基于Razor 1.0的RazorEngine版本(3.0.8)中运行良好.

我有myInstance一个class(MyClass)的实例()和扩展方法:

namespace MyCompany.Extensions 
{
    public static class MyClassExtensions
    {
        public static string ExtensionMethod(this MyClass thing) 
        {
            // do stuff
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想在RazorEngine视图中调用它(简化示例,有很多这些方法,并且都以相同的方式失败):

@using MyCompany.Extensions
@using MyCompany
@{
    var myInstance = new MyClass(Model, ...);
}

Some text @myInstance.ExtensionMethod() some more text
Run Code Online (Sandbox Code Playgroud)

这是由RazorEngine编译的文本文件:

string parsedResult = RE::Razor.Parse(fileContent, myModel, "testfile.txt");
Run Code Online (Sandbox Code Playgroud)

问题是这条线(曾经工作过)抛出RuntimeBinderException:

'MyCompany.MyClass'不包含'ExtensionMethod'的定义

请注意,如果我将文本文件更改为:

Some text @MyClassExtensions.ExtensionMethod(myInstance) some more text
Run Code Online (Sandbox Code Playgroud)

它工作正常,所以我认为它必须找到扩展方法的命名空间.

我的第一个想法是它必须将传递的模型视为一个dynamic(因此也是从它衍生出来的任何东西dynamic),但它知道了预期的类型RuntimeBinderException.由于异常是运行时我认为在编译模板时必须无法识别扩展方法,但为什么会发生变化?

我不确定3.0.8和3.2.0之间有什么变化,或者为什么会这样.我需要添加一些东西,以便在编译模板时找到扩展方法吗?

Kei*_*ith 5

这是RazorEngine中的一个错误:Razor.Compile工作原理TemplateBase<dynamic>(所以Model从它衍生的所有内容也是dynamic如此),这意味着没有扩展方法经过'compiler-magic'将它们转换为静态调用.然后Razor.Run传递Model为正确的类型,但扩展方法语法被称为实例方法.

可能很快就会解决这个问题(这个bug只有几天了,这是一个极端的案例),但在此期间我有一个解决方法:在Razor模板中明确输入Model

@using MyCompany.Extensions
@using MyCompany
@{
    ExpectedModelClass strongTypeModel = Model as ExpectedModelClass;
    MyClass myInstance = new MyClass(strongTypeModel , ...);
}

Some text @myInstance.ExtensionMethod() some more text
Run Code Online (Sandbox Code Playgroud)

这现在有效,因为即使Modeldynamic处于编译时,它仍然不再传播myInstance.

它并不理想,我Model现在所使用的每个地方都必须如此strongTypeModel,但这是一个更简单的替代品.