繁体   English   中英

如何在C#中自动生成Decorator模式

[英]How to auto generate Decorator pattern in C#

我有一些接口,以及一个实现此接口的类,说:

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

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

现在,我想创建一个类,用一些特定的逻辑来装饰每个具体的类方法,在非生产环境中,在调用之前和之后执行。

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

我的问题是有一种更简单的方法来自动生成这样的类,而不是在界面上使用反射并创建一个带有cs扩展名的文本文件?

我个人只是明确地记录需要的地方,但如果你设置使用装饰器这样做,你可以使用RealProxy类

它可能看起来像这样:

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

        }

    }
}

我编写了一个T4模板,能够根据一些简单的约定为相当复杂的类生成装饰器。 该项目可以在GitHub - T4Decorators上找到。 与T4MVC类似,这就是我的想法。

你试过PostSharp吗? 它可以帮助您自动“检测”类并实现您的日志记录方案,而无需实际创建装饰器。

Logging Application块怎么样?

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

我们有相同的要求并编写了一个Roslyn生成器来执行此操作,请查看此处: https//github.com/proactima/ProxyGen您需要稍微修改代码以满足您的需要。 基本上我们在'ReliableServiceCall'方法中包装接口的方法(所有来自某个命名空间)。 修改它以做其他事情是微不足道的。

你能用T4和反射吗?

也许这些其他问题可以帮助:

这里最好的方法是通过接口使用Decorator Pattern。 我知道这是一个非常古老的帖子,但是如果你使用IoC注入器,比如SimpleInjector,你可以在一行代码中设置这些装饰器调用。 然后你可以做这样的事情:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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