c# - Apply a debugger visualizer without assembly dependencies -


i trying create debug visualizer applies variety of objects without make visualizer assembly dependency. want apply visualizer variety of classes, including private nested, internal, , lots of complex generics involved (both of parent , nested classes). means i'm creating proxy object critical data involved.

i don't want main assembly have dependency on visualizer assembly, , don't want visualizer assembly know guts of main assembly.

in main assembly, have looks this:

namespace mainasm {     public interface ivisualizable     {         debugproxy debugvisualizer { get; }     }      [serializable]     public class debugproxy     {         // data required visualization here          public debugproxy() { }         public debugproxy(ivisualizable source)         {             var orig = source.debugvisualizer;             // copy properties orig         }     } } 

then visualizer, have code looks this:

[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 grab additional properties , open window         }     } } 

i want able apply visualizer class knows how create debugproxy. can visualizer if expand object , click on debugvisualizer property, want visualization associated top level object. if have this:

[system.diagnostics.debuggervisualizer(???)] public class myclass<tthis, t2, t3> : ivisualizable     tthis : myclass<tthis, t2, t3>, new()     t2 : someotherclass2<t2, t3>, new()     t3 : someotherclass3<t2, t3>, new() {     debugproxy ivisualizable.debugvisualizer { { return createproxy(); } } } 

the question is, need put in place of ??? associate visualizer myclass<,,> , descendants?

--

  • if put [system.diagnostics.debuggertypeproxy(typeof(debugproxy))] debugproxy doesn't show visualizer icon
  • if put [system.diagnostics.debuggervisualizer("dbg.visualizer")], nullreferenceexception @ microsoft.visualstudio.debuggervisualizers.debugviewershim.managedshim.delegatehost.createviewer
  • if put [system.diagnostics.debuggervisualizer("dbg.visualizer, dbg")], "could not load file or assembly dbg or 1 of dependencies" though log shows correct path under "initial privatepath = " when tries resolve assembly.
  • if put [system.diagnostics.debuggervisualizer("dbg.visualizer", "microsoft.visualstudio.debuggervisualizers.visualizerobjectsource")], "cannot create visualizer object source." call stack series of methods in debuggervisualizeres.debugviewershim namespace: "delegatedhost.createviewer" -> "privatecallback.maybedeserializeandthrowexception" -> "debugeehost.createsourceinternal" -> "remoteobjectsourceexception"

the secret create customized visualizerobjectsource , put 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);         }     } } 

then put following attribute on classes implement 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=???"] 

where ??? public key of assembly.

it's important assembly customobjectsource goes gac, because ensures can loaded debugee app domain no matter base path set as. make sure has strong name , use "gacutil /f /i dbg.dll" visual studio command prompt install it.

then when try visualize class, load customobjectsource app domain, use createreplacementobject method convert serializable type, , perform serialization on debugproxy object instead of original type.


Comments

Popular posts from this blog

css - SVG using textPath a symbol not rendering in Firefox -

Java 8 + Maven Javadoc plugin: Error fetching URL -

datatable - Matlab struct computations -