2010-12-08 13 views
6

que tienen alguna de las interfaces, y una clase que implementa esta interfaz, dicen:Cómo Generar automáticamente Decorator en C#

interface IMyInterface 
{ 
    void Func1(); 
    void Func2(); 
} 

class Concrete : IMyInterface 
{ 
    public virtual void Func1() { //do something } 
    public virtual void Func2() { //do something } 
} 

Ahora, quiero crear una clase que decora cada uno de los métodos de la clase de hormigón con algunos lógica específica, que se ejecutará en un entorno que no sea de producción, antes y después de la llamada.

class Decorator : Concrete 
{ 
    public override void Func1() { Pre(); base.Func1; Post(); } 
    public virtual void Func2() { Pre(); base.Func2; Post(); } 
} 

Mi pregunta es que hay una manera más sencilla para auto generar dicha clase que no sea el uso reflexión sobre la interfaz y crear un archivo de texto con extensión cs?

Respuesta

8

Personalmente me acaba de iniciar la sesión de forma explícita cuando sea necesario, pero si se fijan en el uso de un decorador de hacer esto se podría utilizar el RealProxy class.

Podría ser algo como esto:

public class DecoratorProxy<T> : RealProxy 
{ 
    private T m_instance; 

    public static T CreateDecorator<T>(T instance) 
    { 
     var proxy = new DecoratorProxy<T>(instance); 
     (T)proxy.GetTransparentProxy(); 
    } 

    private DecoratorProxy(T instance) : base(typeof(T)) 
    { 
     m_instance = instance; 

    } 
    public override IMessage Invoke(IMessage msg) 
    { 
     IMethodCallMessage methodMessage = msg as IMethodCallMessage; 
     if (methodMessage != null) 
     { 
      // log method information 

      //call method 
      methodMessage.MethodBase.Invoke(m_instance, methodMessage.Args); 
      return new ReturnMessage(retval, etc,etc); 

     } 

    } 
} 
+0

El mensaje de Invocación debería devolver algo, así que devolví el mensaje original. Se llamó al método original, pero obtuve la siguiente excepción: System.Runtime.Remoting.RemotingException: se llamó al método con un mensaje de tipo inesperado. ¿Alguna idea? –

+0

Al buscar en MSDN (http://msdn.microsoft.com/en-us/library/system.runtime.remoting.proxies.realproxy.aspx) se debe devolver un tipo de IMethodReturnMessage. ¿Cómo simplemente creo uno? –

+1

nuevo ReturnMessage (retval) - vea aquí: http://msdn.microsoft.com/en-us/library/system.runtime.remoting.messaging.returnmessage.aspx – SpeksETC

2

¿Ha intentado PostSharp? Puede ayudarlo a "instrumentar" automáticamente las clases y lograr su escenario de registro sin crear decoradores.

+0

tenga cuidado con cualquier herramienta de AOP - si su empresa necesita cumplir con SOX, entonces puede que no sea una opción para usted – stack72

+0

Gracias, pero quiero algo gratis ... ¿Qué es SOX? –

+0

PostSharp tiene una edición comunitaria gratuita. ¡No tienes que comprarlo! Solo ve a la página de descargas. – Alex

2

¿Qué pasa con el bloque Aplicación Logging?

http://msdn.microsoft.com/en-us/library/ff647183.aspx

+0

Lo siento, pero mi pregunta original no era precisa: no uso el inicio de sesión en el sentido más simple. Hago pre y post lógica ... 1 arriba para esta biblioteca –

+0

Dada la nueva experiencia, sugeriría que las personas que aterricen aquí consideren la interceptación de políticas. – brumScouse

2

He escrito una plantilla T4 capaz de generar decorador para las clases bastante complejas basadas en algunas convenciones sencillas. El proyecto se puede encontrar en GitHub - T4Decorators. Funciona de manera similar a T4MVC, de ahí surgió la idea.

1

Tenemos el mismo requisito y escribimos un generador de Roslyn para hacer esto, mira aquí: https://github.com/proactima/ProxyGen Tienes que modificar el código ligeramente para satisfacer tus necesidades. Básicamente, envolvemos los métodos de una interfaz (todo desde un cierto espacio de nombres) en un método 'ReliableServiceCall'. Es trivial modificar esto para hacer otra cosa.

Cuestiones relacionadas