2

Razor2.0およびRazorEngine3.2.0へのアップグレード後に失敗するRazorEngineプロジェクトがあります

これは、以前のRazor 1.0ベースのバージョンのRazorEngine(3.0.8)では正常に機能しました。

myInstanceクラス(MyClass)と拡張メソッドのインスタンス( )があります:

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

これをRazorEngineビューで呼び出したい(簡略化された例、これらのメソッドがたくさんあり、すべて同じように失敗します):

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

Some text @myInstance.ExtensionMethod() some more text

これは、RazorEngineによってコンパイルされたテキストファイルにあります。

string parsedResult = RE::Razor.Parse(fileContent, myModel, "testfile.txt");

問題は、この行(以前は機能していた)がRuntimeBinderException:をスローすることです。

「MyCompany.MyClass」には「ExtensionMethod」の定義が含まれていません

テキストファイルを次のように変更した場合は注意してください。

Some text @MyClassExtensions.ExtensionMethod(myInstance) some more text

正常に動作するので、拡張メソッドの名前空間を見つける必要があると思います。

私の最初の考えは、渡されたモデルをdynamic(したがって、それから派生したものdynamicも)と見なす必要があるということでしたが、で予想されるタイプを認識していRuntimeBinderExceptionます。例外は実行時なので、テンプレートのコンパイル中に拡張メソッドを識別できなかったに違いないと思いますが、なぜそれが変更されたのでしょうか。

3.0.8と3.2.0の間で何が変わったのか、なぜこれが壊れているのかわかりません。テンプレートのコンパイル中に拡張メソッドを見つけるために追加する必要があるものはありますか?

4

1 に答える 1

5

これはRazorEngineのバグですRazor.Compile動作しますTemplateBase<dynamic>Modelそしてそれから派生したものもすべてですdynamic)。つまり、拡張メソッドが「compiler-magic」を受け​​て静的呼び出しに変換されることはありません。次に、を正しい型としてRazor.Run渡しModelますが、拡張メソッドの構文はインスタンスメソッドとして呼び出されます。

おそらくすぐに修正されるでしょう(バグはほんの数日で、これはコーナーケースです)が、それまでの間、回避策があります:Razorテンプレートに明示的に入力しますModel

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

Some text @myInstance.ExtensionMethod() some more text

これは現在機能しています。これは、コンパイル時にModelまだ拡散していないためです。dynamicmyInstance

それは理想的ではなく、私がModel今使っているところはどこでもそうしなければなりませんがstrongTypeModel、それははるかに簡単な代用です。

于 2013-01-31T16:36:47.743 に答える