2010-12-08 11 views
6

J'ai une interface et une classe qui implémente cette interface, disent:Comment générer automatiquement pattern Décorateur en C#

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

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

Maintenant, je veux créer une classe qui décore chacune des méthodes de classe en béton avec un certain logique spécifique, à exécuter dans un environnement non productif, avant et après l'appel.

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

Ma question est-il un moyen plus simple de générer automatiquement cette classe autre que la réflexion sur l'utilisation de l'interface et de créer un fichier texte avec l'extension cs?

Répondre

8

Personnellement je voudrais simplement vous connecter explicitement si nécessaire, mais si vous êtes mis sur l'utilisation d'un décorateur pour ce faire, vous pouvez utiliser le RealProxy class.

Il pourrait ressembler à ceci:

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

Le message Appeler devrait retourner quelque chose, donc j'ai retourné le message original. La méthode d'origine a été appelée, mais j'ai reçu l'exception suivante: System.Runtime.Remoting.RemotingException: La méthode a été appelée avec un message de type inattendu. Des pensées? –

+0

En regardant dans MSDN (http://msdn.microsoft.com/en-us/library/system.runtime.remoting.proxies.realproxy.aspx) un type de IMethodReturnMessage devrait être retourné. Comment puis-je simplement en créer un? –

+1

new ReturnMessage (retval) - voir ici: http://msdn.microsoft.com/fr-fr/library/system.runtime.remoting.messaging.returnmessage.aspx – SpeksETC

2

Avez-vous essayé PostSharp? Il peut vous aider à "instrumentaliser" automatiquement les classes et à réaliser votre scénario de journalisation sans créer de décorateurs.

+0

soyez prudent avec n'importe quel outil AOP - si votre entreprise a besoin de SOX conforme alors il ne peut pas être une option pour vous – stack72

+0

Merci, mais je veux quelque chose de gratuit ... Qu'est-ce que SOX? –

+0

PostSharp a une édition communautaire gratuite. Vous n'avez pas à l'acheter! Il suffit d'aller à la page de téléchargements. – Alex

2

Qu'en est-il du bloc Application de journalisation?

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

+0

Désolé, mais ma question initiale n'était pas exacte - je ne fais pas de journalisation dans le sens le plus simple. Je fais quelques pré et post logique ... 1 pour cette bibliothèque –

+0

Compte tenu de la nouvelle expérience, je suggère que les gens qui débarquent ici devraient regarder l'interception de la politique. – brumScouse

2

J'ai écrit un modèle T4 capable de générer décorateur pour les classes assez complexes basées sur certaines conventions simples. Le projet peut être trouvé sur GitHub - T4Decorators. Fonctionne comme T4MVC, c'est là que j'ai eu l'idée.

1

Nous avons la même exigence et a écrit un générateur Roslyn pour ce faire, jetez un oeil ici: https://github.com/proactima/ProxyGen Vous devez modifier légèrement le code pour répondre à vos besoins. Fondamentalement, nous enveloppons les méthodes d'une interface (tout à partir d'un certain espace de noms) dans une méthode «ReliableServiceCall». Il est trivial de modifier cela pour faire autre chose.

Questions connexes