Frage

Kennt jemand eine Möglichkeit, dynamic Methodenaufrufe abfangen (insbesondere solche, die RuntimeBinderExceptions gehen zu erhöhen) mit einem RealProxy? Ich hatte gehofft, die Ausnahme zu fangen und zu implementieren ‚Methode fehlt‘ obendrein, aber es scheint geworfen zu werden, bevor die Abfangjäger einen Blick in bekommt.

Mein Test nur wie folgt aussieht:

dynamic hello = MethodMissingInterceptor<DynamicObject>.Create();
Assert.AreEqual("World", hello.World());

Wo World nicht tatsächlich auf DynamicObject umgesetzt. Der Interceptor ist ziemlich einfach - ich habe gehofft, IMethodReturnMessage.Exception für RuntimeBinderException zu überprüfen und nach vorn auf so etwas wie:

public IMessage MethodMissing(IMethodCallMessage call)
{
    return new ReturnMessage(call.MethodBase.Name, new object[0], 0, call.LogicalCallContext, call);
}

Leider alles, was ich in meinem Interceptor sehen sind einige Anrufe GetType, und nicht die nicht-existente World Methode.

Gelingt das nicht? - Wer weiß, ob es eine DynamicProxy Version läuft glücklich auf 4.0 noch .NET, dass das Problem in Angriff genommen haben könnte

War es hilfreich?

Lösung

Ich werde mit der langen Antwort beginnen. Jeder bind eines dynamischen Betrieb in C # hat etwa diese drei Dinge in dieser Reihenfolge:

  1. Stellen Sie das Objekt selbst zu binden, wenn sie implementiert IDynamicMetaObjectProvider oder ein COM-Objekt, und wenn das nicht funktioniert, dann ...
  2. Binden Sie den Betrieb auf einen Betrieb auf einem einfachen-old-clr-Objekt mit Reflexion, und wenn das nicht funktioniert, dann ...
  3. Gibt einen DynamicMetaObject, die einen Totalausfall darstellt zu binden.

Sie sehen, die GetType-Anrufe, weil in Schritt 2 wird die C # Laufzeit Bindemittel über Sie reflektieren, um zu versuchen, wenn Sie eine „Welt“ Methode haben, um herauszufinden, die geeignet ist, zu nennen, und dies geschieht, weil die IDynamicMetaObjectProvider Implementierung von hallo, wenn es einen gibt, konnte nicht kommen mit etwas besonderes zu tun.

Leider ist für Sie durch die Zeit, die RuntimeBinderException geworfen wird, sind wir nicht mehr bindend. Die Ausnahme kommt aus der Ausführungsphase des dynamischen Betrieb, in Reaktion auf das Meta-Objekt zurückgegeben aufgrund 3. Die einzige Möglichkeit, zu Schritt für Sie, es ist an der tatsächlichen Aufrufort zu fangen.

Damit Strategie geht zu erarbeiten für Sie nicht, wenn Sie method_missing in C # implementieren möchten. Sie tun, obwohl einige Optionen haben.

Eine einfache Möglichkeit ist IDynamicMetaObjectProvider in Ihrem MethodMissingInterceptor zu implementieren und an die IDMOP Umsetzung des umwickelten Gegenstand verschieben. Im Falle des Scheiterns auf dem Teil des inneren IDMOP, können Sie binden sich an, was Sie wollen (vielleicht ein Anruf zu einem method_missing Delegierten in der Abfangjäger gespeichert). Der Nachteil dabei ist, dass dies nur für Objekte funktioniert die dynamischen Objekte bekannt sind, z.B. diejenigen, die IDMOP implementieren zu beginnen. Dies ist, weil Sie im Grunde einfügen sich zwischen den Schritten 1 und 2.

Eine weitere Alternative, die ich denken kann, ist IDynamicMetaObjectProvider zu implementieren, und darin, reagiert positiv auf jeden binden, einen Anruf auf ein Verfahren zurückkehrt, die (a) der C # Compiler erzeugt hätte den gleichen Code erzeugt in erster Linie zu binden und (b) eine fängt RuntimeBinderException method_missing Methode aufzurufen. Der Nachteil hierbei ist, dass es ziemlich kompliziert sein würde - ich würde Bedarf beliebige Delegattypen und die IL zu erzeugen, die sie gegen die öffentlichen Typen in der C # Laufzeitbinderanordnung verwendet, die, ehrlich gesagt, sind nicht für die Öffentlichkeit gedacht. Aber zumindest würden Sie Methode fehlt gegen alle Operationen erhalten.

Ich bin sicher, es gibt auch andere Strategien, die ich nicht gedacht haben, wie Sie scheinen zu Hinting über Remoting Proxies. Ich kann mir nicht vorstellen, wie sie aussehen, obwohl, und ich kann nicht sagen, ob sie erfolgreich sein würde.

Der Kern des Problems ist hier, dass C # 4.0 nicht ein Design hat, die Ihren Wunsch, dies zu tun erwartet. Insbesondere können Sie nicht einfach selbst einfügen zwischen den Schritten 2 und 3. Das hat mich auf die kurze Antwort bringt, die leider ist, # C 4.0 nicht method_missing hat.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top