Pregunta

Cuando usted tiene un coche de la clase que implementa IVehicle y desea envolverlo en un decorador que reenvía todas las llamadas al coche y los cuenta, ¿cómo hacerlo?

En Rubí tan sólo pudiera construir un decorador sin ningún tipo de métodos y utilizar method_missing para desviar todas las llamadas al objeto coche.

En Java podría construir un objeto proxy que se ejecuta todo el código a través de un método y lo envía después.

¿Hay alguna cosa similar que pueda hacer en C #?


Actualización:

basado en las answeres y lo que he leído sobre System.Reflection.Emit debería ser posible escribir un método similar a este:

Type proxyBuilder(Type someType, delagate functionToBeApplied, Object forward)

donde tipo implementa todo el interfaz de sometype, ejecuta functionToBeApplied y luego reenvía la llamada al método de oponerse al regresar su retorno.

¿Hay alguna lib que hace precisamente eso, o tendría que escribir mi propia?

¿Fue útil?

Solución

Para hacer proxy que podría mirar en "RealProxy" si desea utilizar los tipos estándar, que es un poco de una molestia de usar, aunque (y requiere sus clases heredan de MarshalByRefObject).

public class TestProxy<T> : RealProxy where T : class
{
    public T Instance { get { return (T)GetTransparentProxy(); } }
    private readonly MarshalByRefObject refObject;
    private readonly string uri;

    public TestProxy() : base(typeof(T))
    {
        refObject = (MarshalByRefObject)Activator.CreateInstance(typeof(T));
        var objRef = RemotingServices.Marshal(refObject);
        uri = objRef.URI;
    }

    // You can find more info on what can be done in here off MSDN.
    public override IMessage Invoke(IMessage message)
    {
        Console.WriteLine("Invoke!");
        message.Properties["__Uri"] = uri;
        return ChannelServices.SyncDispatchMessage(message);
    }
}

Como alternativa se puede conseguir "DynamicProxy" de Castillo .. Funciona un poco mejor en mi experiencia ..

Si se utiliza uno de los que no necesariamente siempre obtendrá un gran rendimiento sin embargo, los utilizo principalmente en las llamadas que probablemente será lento en el primer lugar .. Pero se puede probarlo si lo desea.

La solución de Marc tendrá un mejor rendimiento.

Otros consejos

Por desgracia, no hay apoyo mixin en C #. Así que había necesidad de poner en práctica todos los métodos, o utilizar algún Reflection.Emit de alta resistencia para hacerlo. La otra alternativa es una (opcional) clase de proxy / base decorador ...

abstract class FooBase : IFoo {
   protected FooBase(IFoo next) {this.next = next;}
   private readonly IFoo next;
   public virtual void Bar() { // one of the interface methods
       next.Bar();
   }
   public virtual int Blop() { // one of the interface methods
       return next.Blop();
   }
   // etc
}

entonces

class SomeFoo : FooBase {
   public SomeFoo(IFoo next) : base(next) {}
   public override void Bar() {...}
}

Tras señalar que el uso de la FooBase es estrictamente opcional; Se permite cualquier IFoo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top