ventajas que programacion patrones patron estructural ejemplo diseño desventajas decoradores decorador cafe c# .net reflection proxy decorator

que - patrones de diseño c#



¿Cuál es la forma más corta de implementar una clase proxy o decorador en c#? (2)

Cuando tienes un coche de clase que implementa un vehículo y quieres envolverlo en un decorador que reenvía todas las llamadas al automóvil y las cuenta, ¿cómo lo harías?

En Ruby, podría construir un decorador sin ningún método y usar method_missing para reenviar todas las llamadas al objeto del coche.

En Java podría construir un objeto Proxy que ejecute todo el código a través de un método y lo reenvíe posteriormente.

¿Hay algo similar que pueda hacer en C #?

actualizar:

basado en las respuestas 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 toda la interfaz de someType, ejecuta functionToBeApplied y luego reenvía la llamada de método al objeto mientras devuelve su devolución.

¿Hay alguna lib que haga exactamente eso o tendría que escribir la mía?


Desafortunadamente, no hay soporte de mixina en C #. Por lo tanto, necesitaría implementar todos los métodos, o usar algunos reflectores de alta resistencia. Deje de hacerlo. La otra alternativa es una clase base proxy / decorador (opcional) ...

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() {...} }

Observando que el uso de FooBase es estrictamente opcional; cualquier IFoo está permitido.


Para el proxy, podrías buscar en "RealProxy" si quieres usar tipos estándar, aunque es un poco complicado de usar (y requiere que tus clases hereden 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); } }

Alternativamente, podrías obtener "DynamicProxy" de Castle ... Funciona un poco mejor en mi experiencia ...

Si usas uno de esos, no necesariamente obtendrás un gran rendimiento, los utilizo principalmente en llamadas que probablemente serán lentas en primer lugar ... Pero podrías probarlo si quieres.

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