2015-04-14 46 views
0

我想創建一個調試可視化器,它適用於各種對象 沒有使可視化組件的依賴。我想將這個可視化器應用到各種類中,包括私有嵌套,內部以及涉及大量複雜的泛型(父類和嵌套類)。這意味着我正在創建一個只包含關鍵數據的代理對象。申請一個調試器可視化器沒有組件依賴關係

我不希望我的主要程序集對可視化程序集程序有依賴性,我也不想讓可視化程序集程序集知道主要程序集的內核。

在主機上時,我有一些看起來像這樣:

namespace MainAsm 
{ 
    public interface IVisualizable 
    { 
     DebugProxy DebugVisualizer { get; } 
    } 

    [Serializable] 
    public class DebugProxy 
    { 
     // data required for visualization here 

     public DebugProxy() { } 
     public DebugProxy(IVisualizable source) 
     { 
      var orig = source.DebugVisualizer; 
      // copy properties from orig 
     } 
    } 
} 

那麼對於可視化,我有一些代碼,看起來像這樣:

[assembly:System.Diagnostics.DebuggerVisualizer(
    typeof(dbg.Visualizer), 
    typeof(Microsoft.VisualStudio.DebuggerVisualizers.VisualizerObjectSource), 
    TargetTypeName="MainAsm.DebugProxy, MainAsm", 
    Description="MainAsm Debug Visualizer")] 

namespace dbg 
{ 
    public class Visualizer : Microsoft.VisualStudio.DebuggerVisualizers.DialogDebuggerVisualizer 
    { 
     protected override void Show(
      Microsoft.VisualStudio.DebuggerVisualizers.IDialogVisualizerService windowService, 
      Microsoft.VisualStudio.DebuggerVisualizers.IVisualizerObjectProvider objectProvider) 
     { 
      object data = objectProvider.GetObject(); 
      if (data == null) 
       return; 
      var t = data.GetType(); 
      var prop = t.GetProperty("DebugVisualizer"); 
      if (prop != null) 
      { 
       data = prop.GetValue(data, null) ?? data; 
      } 

      // use reflection to grab additional properties and open a window 
     } 
    } 
} 

我希望能夠到將可視化器應用於任何知道如何創建DebugProxy的類。如果我展開一個對象並單擊它的DebugVisualizer屬性,我顯然可以獲得一個可視化器,但我希望可視化與頂層對象相關聯。所以如果我有這樣的事情:

[System.Diagnostics.DebuggerVisualizer(???)] 
public class MyClass<TThis, T2, T3> : IVisualizable 
    where TThis : MyClass<TThis, T2, T3>, new() 
    where T2 : SomeOtherClass2<T2, T3>, new() 
    where T3 : SomeOtherClass3<T2, T3>, new() 
{ 
    DebugProxy IVisualizable.DebugVisualizer { get { return CreateProxy(); } } 
} 

問題是,我需要什麼來代替???讓它將可視化器與MyClass < ,,>及其後代關聯起來?

-

  • 如果我把[System.Diagnostics.DebuggerTypeProxy(typeof運算(DebugProxy))]的DebugProxy不具有可視化圖標
  • 顯示如果我把[系統.Diagnostics.DebuggerVisualizer( 「dbg.Visualizer」),我在Microsoft.VisualStudio.DebuggerVisualizers.DebugViewerShim.ManagedShim.DelegateHost.CreateViewer
  • 得到的NullReferenceException如果我把[System.Diagnostics.DebuggerVisualizer(「dbg.Visualizer,dbg」)],我得到「無法加載文件或程序集dbg或它的某個依賴項」,即使日誌顯示「Initial PrivatePath = 「當它試圖解決大會。
  • 如果我把[System.Diagnostics.DebuggerVisualizer(「dbg.Visualizer」,「Microsoft.VisualStudio.DebuggerVisualizers.VisualizerObjectSource」),我得到「無法創建可視化對象源。」調用堆棧是一系列DebuggerVisualizeres.DebugViewerShim命名方法: 「DelegatedHost.CreateViewer」 - > 「PrivateCallback.MaybeDeserializeAndthrowException」 - > 「DebugeeHost.CreateSourceInternal」 - > 「RemoteObjectSourceException」

回答

0

祕密是創建一個自定義VisualizerObjectSource放即進入GAC:

namespace dbg 
{ 
    public class CustomObjectSource 
     : Microsoft.VisualStudio.DebuggerVisualizers.VisualizerObjectSource 
    { 
     private static object ConvertObject(object oldObj) 
     { 
      if (oldObj == null) 
       return null; 
      foreach (var intf in oldObj.GetType().GetInterfaces()) 
      { 
       var prop = intf.GetProperty("DebugVisualizer"); 
       if (prop != null) 
        return prop.GetValue(oldObj, null); 
      } 
      return oldObj; 
     } 

     public override void TransferData(object target, Stream incomingData, Stream outgoingData) 
     { 
      base.TransferData(ConvertObject(target), incomingData, outgoingData); 
     } 

     public override object CreateReplacementObject(object target, Stream incomingData) 
     { 
      return ConvertObject(base.CreateReplacementObject(ConvertObject(target), incomingData)); 
     } 

     public override void GetData(object target, Stream outgoingData) 
     { 
      base.GetData(ConvertObject(target), outgoingData); 
     } 
    } 
} 

然後把下面的屬性上實現IVisualizable類:

[System.Diagnostics.DebuggerVisualizer(
    "dbg.Visualizer, dbg, Version=1.0.0.0, Culture=neutral, PublicKeyToken=???", 
    "dbg.CustomObjectSource, dbg, Version=1.0.0.0, Culture=neutral, PublicKeyToken=???"] 

在哪裏???是大會的公鑰。

帶有CustomObjectSource的程序集進入GAC非常重要,因爲這可以確保它可以加載到惡魔應用程序域中,而不管其基本路徑如何設置。確保它具有強大的名稱,並使用Visual Studio命令提示符下的「gacutil/f/i dbg.dll」進行安裝。

然後,當您嘗試將您的類可視化時,它會將CustomObjectSource加載到您的應用程序域中,使用CreateReplacementObject方法將其轉換爲可序列化類型,並在DebugProxy對象上執行序列化,而不是原始類型。

相關問題