2012-06-18 12 views
6

Ich verwende Castle DynamicProxy, um einen Interceptor zu meinen Typen hinzuzufügen. Jetzt muss ich den zugrunde liegenden Basistyp (NICHT den Proxy selbst) bekommen.Castle DynamicProxy: Unexpected Objekt

fand ich ein paar Hinweise auf, so dass die ProxyUtil Klasse wie folgt verwenden vorgeschlagen:

object realInstance = ProxyUtil.GetUnproxiedInstance(proxyInstance); 

Dies scheint nicht zu arbeiten, wie

bool isProxy = ProxyUtil.IsProxy(realInstance); 

ist immer wahr.

Ich habe auch versucht, den folgenden Codeausschnitt verwendet, die im Wesentlichen ist, was ProxyUtil tut:

var accessor = proxyInstance as IProxyTargetAccessor; 
var realInstance = accessor.DynProxyGetTarget(); 

mit dem gleichen Ergebnis, ist realInstance noch ein Proxy.

Was fehlt mir hier?

Antwort

1

Ich benutze einfach eine Schnittstelle wie diese

public interface IMarker 
{ 
    Type ActualType { get; } 
} 

fügen Sie es zu meinem Proxy und abfangen es:

public class MyInterceptor<T> : IInterceptor 

...

if (invocation.Method.DeclaringType == typeof(IMarker)) 
{ 
    if (invocation.Method.Name.Equals("get_ActualType")) 
    { 
    invocation.ReturnValue = typeof(T); 
    return; 
    } 
} 

Also am Ende ich nur überprüfen müssen

if(obj is IMarker) 
    Type t = (obj as IMarker).ActualType` 

Vielleicht gibt es bessere Möglichkeiten, es zu tun, aber es funktioniert und hält meinen Code sauber von Castle Referenzen. Hoffe, das hilft.

1

Wenn Sie einen vererbungsbasierten Proxy erstellen (generator.CreateClassProxy<MyClass>()), lautet der Proxy das Ziel.

+2

Ich benutze 'CreateClassProxyWithTarget (Instanz, Interceptor)', um den Proxy zu erstellen. Das Problem ist, dass NHibernate fehlschlägt, weil es denkt, dass es den Proxy und nicht das Ziel zuordnen sollte. – cguedel

8

Diese Frage ist ein wenig alt, aber hoffentlich wird meine Lösung (die auf .NET 4+ beruht) jemandem helfen.

einen Proxy erstellt, wie folgt:

ProxyGenerator generator = new ProxyGenerator(); 
MyClass proxy = generator.CreateClassProxyWithTarget(underlying, new MyInterceptor(this)); 

ich in der Lage, die zugrunde liegende Ziel mit dem folgenden Verfahren zu erhalten:

internal static TType UnwrapProxy<TType>(TType proxy) 
{ 
    if (!ProxyUtil.IsProxy(proxy)) 
     return proxy; 

    try 
    { 
     dynamic dynamicProxy = proxy; 
     return dynamicProxy.__target; 
    } 
    catch (RuntimeBinderException) 
    { 
     return proxy; 
    } 
} 

Es ist auf der internen Umsetzung von Castle beruht - das heißt, dass Der generierte Proxy hat ein __target-Mitglied. Es ist nett und in sich geschlossen und mit einem oder zwei Unit-Tests gesichert, wir sollten alle Änderungen auffangen, sollte eine neuere Version von Castle dies kaputt machen. Dies verwendet v3.2.0.0 von Castle.

+0

das funktionierte für mich :), danke – dbones

+0

'dynamisch' für den Sieg hier. Beats, die versuchen, darüber nachzudenken. Das war episch gescheitert. – IAbstract