簡體   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