简体   繁体   中英

How to auto generate Decorator pattern in C#

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

interface IMyInterface
{
     void Func1();
     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);

        }

    }
}

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.

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

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.

Could you use T4 and reflection?

Maybe these other questions could help:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM