How to auto generate Decorator pattern in C#
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(); }
}
精彩评论