开发者

How to auto generate Decorator pattern in C#

开发者 https://www.devze.com 2023-01-29 04:47 出处:网络
I have some interface, and a class implementing this interface, say: interface IMyInterface { void Fu开发者_开发技巧nc1();

I have some interface, and a class implementing this interface, say:

interface IMyInterface
{
     void Fu开发者_开发技巧nc1();
     void Func2();
}

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

Now, I want to create a class that decorates each of the concrete class methods with some specific logic, to be executed in non production environment, before and after the call.

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

My question is there a simpler way to auto generate such class other than use reflection on the interface and create a text file with cs extension?


Personally I would just explicitly log where needed, but if you are set on using a decorator to do this you could use the RealProxy class.

It could look something like this:

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);

        }

    }
}


Have you tried PostSharp? It can help you automatically "instrument" classes and achieve your logging scenario without actually creating decorators.


What about the Logging Application block?

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


I have written a T4 template capable of generating decorator for fairly complex classes based on some simple conventions. The project can be found on GitHub - T4Decorators. Works similar to T4MVC, that is where I got the idea.


Could you use T4 and reflection?

Maybe these other questions could help:

  • T4 Code generation: Access types in current project
  • How do you use .Net reflection with T4


We have the same requirement and wrote a Roslyn generator to do this, take a look here: https://github.com/proactima/ProxyGen You need to modify the code slightly to fit your needs. Basically we wrap the methods of an interface (all from a certain namespace) in a 'ReliableServiceCall' method. It's trivial to modify this to do something else.


Best approach here is to use Decorator Pattern via interfaces. I know this is a very old post, but if you use an IoC injector, like SimpleInjector, you can setup these decorator calls in 1 line of code. Then you can do something like this:

public class Decorator : IMyInterface
{ 
     private readonly IMyInterface _next;

     public Decorator (IMyInterface next) { _next = next; }

     public override void Func1() { Pre(); _next.Func1; Post(); }
     public virtual void Func2() { Pre(); _next.Func2; Post(); }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号