2011-06-17 16 views
1

說你有兩個簡單的接口及其方法:請在運行時調用關係圖,具體的方法


ISerializable.Serialize(IValueWriter writer) 
IValueWriter.WriteInt32(Int32 value) 
IValueWRiter.WriteInt64(Int64 value) 

當一個類實現ISerializable我希望能夠知道哪些調用由執行ISerializable.Serialize(IValueWriter writer)內部的IValueWriter並從中生成調用圖。所有這些都需要在運行時使用反射和而不需要調用序列化方法,並且它也將在我無法控制的類上完成,只要內部的代碼執行。

例子:


public sealed class SomeObject : ISerializable 
{ 
    private readonly Int32 first; 
    private readonly Int64 second; 

    public SomeObject(Int32 first, Int64 second) 
    { 
     this.first = first; 
     this.second = second; 
    } 

    public void Serialize(IValueWriter writer) 
    { 
     writer.WriteInt32(this.first); 
     writer.WriteInt64(this.second); 
    } 
} 

調用圖將是:


SomeObject -> Serialize | -> IValueWriter.WriteInt32 
         | -> IValueWriter.WriteInt64 

如何將一個在非常乾淨的方式做到這一點? 我真正瞄準的是基於接口方法的特定實現中調用的MethodInfo[]

回答

0

是的,你可以使用反射來做到這一點。當分析的代碼沒有運行時,我不會真的稱它爲「運行時」。

  1. 迭代裝配中的所有類型。
  2. 實施ISerializable
  3. 類型的過濾查找執行ISerializable.Serialize
  4. 取的IL方法
  5. 查找callvirt指令,其中方法令牌內IValueWriter的方法相匹配。

有一個開源項目ILSpy,它應該是如何解碼IL指令並尋找方法調用的一個很好的例子。

+0

我在扼殺了它之後想到了這一點。基本上你是對的。我基本上從Type中取出MethodInfo,然後使用MethodBody和MethodInfo.GetMethodBody進行播放。我通過反映OpCode結構的OpCodes字段來構建反向查找表,以將它們的數值解碼爲它們各自的結構。我會將您的答案標記爲解決方案,因爲這幾乎是我在此期間發現的。 –

0

最清潔的方式是AOP。 看看到PostSharp

所有你需要做的是創造一些屬性,並將它們添加到您的方法,要記錄等

,據我所知,他們操縱IL編譯之後。

+0

這些方法需要在實際執行之前進行分析並調用圖表。不幸的是,這是行不通的。 –

+0

「這些方法需要在實際執行之前進行分析和調用圖表」這是完全正確的。在調用具有MethodStartAttribute的方法時,您的代碼將被稱爲 –

+0

PostSharp在此處不起作用。是的,它編織了你的AOP,但它對於編譯時調用圖分析沒有任何作用。 – Amy