Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 应用没有程序集依赖项的调试器可视化工具_C#_Visual Studio 2010_Visual Studio_Debuggervisualizer - Fatal编程技术网

C# 应用没有程序集依赖项的调试器可视化工具

C# 应用没有程序集依赖项的调试器可视化工具,c#,visual-studio-2010,visual-studio,debuggervisualizer,C#,Visual Studio 2010,Visual Studio,Debuggervisualizer,我正在尝试创建一个适用于各种对象的调试可视化工具 而不使可视化工具程序集成为依赖项。我想将此可视化工具应用于各种类,包括私有嵌套类、内部类和涉及大量复杂泛型的类(父类和嵌套类)。这意味着我正在创建一个只包含关键数据的代理对象 我不希望我的主程序集依赖于可视化工具程序集,也不希望可视化工具程序集了解主程序集的核心 在主程序集中,我有如下内容: namespace MainAsm { public interface IVisualizable { DebugProx

我正在尝试创建一个适用于各种对象的调试可视化工具 而不使可视化工具程序集成为依赖项。我想将此可视化工具应用于各种类,包括私有嵌套类、内部类和涉及大量复杂泛型的类(父类和嵌套类)。这意味着我正在创建一个只包含关键数据的代理对象

我不希望我的主程序集依赖于可视化工具程序集,也不希望可视化工具程序集了解主程序集的核心

在主程序集中,我有如下内容:

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
        }
    }
}
[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(); } }
}
对于可视化工具,我有如下代码:

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
        }
    }
}
[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(); } }
}
我希望能够将可视化工具应用于任何知道如何创建DebugProxy的类。如果我展开一个对象并单击其DebugVisualizer属性,显然可以得到一个可视化工具,但是我希望可视化与顶级对象相关联。所以如果我有这样的东西:

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
        }
    }
}
[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(); } }
}
[System.Diagnostics.DebuggerVisualizer(???)]
公共类MyClass:IVisualizable
其中:MyClass,new()
其中T2:SomeOtherClass2,new()
其中T3:SomeOtherClass3,new()
{
DebugProxy IVisualizable.DebugVisualizer{get{return CreateProxy();}}
}
问题是,我需要用什么来代替???要让它与MyClass及其子体关联可视化工具

--

  • 如果我放置[System.Diagnostics.DebuggerTypeProxy(typeof(DebugProxy))],则DebugProxy不会显示可视化工具图标
  • 如果我放置[System.Diagnostics.DebuggerVisualizer(“dbg.Visualizer”)],我会在Microsoft.VisualStudio.DebuggerVisualizers.DebugViewersIM.ManagedShim.DelegateHost.CreateViewer中得到一个NullReferenceException
  • 如果我放入[System.Diagnostics.DebuggerVisualizer(“dbg.Visualizer,dbg”)],我会得到“无法加载文件或程序集dbg或其依赖项之一”,即使日志在尝试解析程序集时在“Initial PrivatePath=”下显示了正确的路径
  • 如果我放入[System.Diagnostics.DebuggerVisualizer(“dbg.Visualizer”、“Microsoft.VisualStudio.DebuggerVisualizers.VisualizationRobjectSource”)],我会得到“无法创建Visualizer对象源”。调用堆栈是DebuggerVisualizers.DebuggerViewersIM命名空间中的一系列方法:“DelegatedHost.CreateViewer”->“PrivateCallback.MaybedeSerializeAndRowException”->“DebugeeHost.CreateSourceInternal”->“RemoteObjectSourceException”

秘诀是创建一个定制的源代码,并将其放入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对象而不是原始类型执行序列化