2012-06-18 17 views
6

Estoy usando Castle DynamicProxy para agregar un interceptor a mis tipos. Ahora necesito obtener el tipo de base subyacente (NO el proxy en sí).Castle DynamicProxy: obtener el objeto sin proxy

He encontrado algunas pistas para que los que sugiere el uso de la clase ProxyUtil como esto:

object realInstance = ProxyUtil.GetUnproxiedInstance(proxyInstance); 

Esto no parece funcionar tan

bool isProxy = ProxyUtil.IsProxy(realInstance); 

siempre es cierto.

También he intentado usar el siguiente fragmento de código, que es esencialmente lo que está haciendo ProxyUtil:

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

con los mismos resultados, realInstance sigue siendo un proxy.

¿Qué me falta aquí?

Respuesta

1

Me basta con utilizar una interfaz como esta

public interface IMarker 
{ 
    Type ActualType { get; } 
} 

añadirlo a mi proxy y interceptarlo:

public class MyInterceptor<T> : IInterceptor 

...

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

Así que al final sólo tiene que verificar

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

Quizás haya mejores opciones para hacerlo, pero funciona y mantiene mi código limpio de referencias de castillo. Espero que esto ayude.

1

Si está construyendo un proxy basado en herencia (generator.CreateClassProxy<MyClass>()) el proxy es el destino.

+2

Estoy usando 'CreateClassProxyWithTarget (instancia, interceptor)' para crear el proxy. El problema es que NHibernate falla porque cree que debe correlacionar el proxy y no el destino. – cguedel

8

Esta pregunta es un poco antigua pero espero que mi solución (que se basa en .NET 4+) ayude a alguien.

haber creado un proxy de la siguiente manera:

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

he podido conseguir el objetivo que subyace con el siguiente método:

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

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

Se basa en la aplicación interna del Castillo - es decir, que el proxy generado tiene un miembro __target. Aunque es bonito y autónomo, y respaldado con una prueba unitaria o dos, deberíamos detectar cualquier cambio si una versión posterior de Castle lo rompe. Esto está usando v3.2.0.0 de Castle.

+0

esto funcionó para mí :), gracias – dbones

+0

'dinámico' para la victoria aquí. Beats tratando de reflejar en ello. Eso fue un fracaso épico. – IAbstract

Cuestiones relacionadas