Skip to content

Commit ed481c3

Browse files
updated readme
1 parent 4af684a commit ed481c3

File tree

1 file changed

+134
-16
lines changed

1 file changed

+134
-16
lines changed

README.md

Lines changed: 134 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,35 +9,153 @@ What's LINQBridgeVs?
99
-----------------
1010

1111
LINQBridgeVs is a Visual Studio Extension compatible with Visual Studio 2012/2013/2015/2017.
12-
It is a bridge between a Visual Studio debugging session and [LINQPad] (http://www.linqpad.net).
13-
When enabled on a solution containing VB/C# projects, it creates at compile time, a Custom Debugger Visualizer
14-
mapping to all the public complex types and making the magnifier glass
15-
available for all of them. By clicking on the magnifier glass on an object instance, this will be transmitted over a
16-
bus and read back by LINQPad.
12+
It is a bridge between a Visual Studio debugging session and [LINQPad](http://www.linqpad.net).
13+
When enabled on a solution containing C#, VB, ASP.NET or MVC projects, it creates at compile time a Custom Debugger Visualizer assembly
14+
mapping to all the public complex types and making the magnifier glass available for all of them. By clicking on the magnifier glass on an object instance, this will be transmitted over a
15+
bus and 'Dumped' out by LINQPad.
16+
1717

1818
## Getting Started
1919

2020
Once the extension is installed a new menu will be available in the Visual Studio Menu Bar, only visible
2121
when a solution is loaded, called "BridgeVs". There are two options available:
2222

23-
* Bridge Solution
24-
* Un-Bridge Solution
23+
* *Bridge Solution*
24+
* *Un-Bridge Solution*
2525

26-
Bridging a solution will enable all of the public types of every projects in the solution to be exported to [LINQPad](http://www.linqpad.net) at runtime.
26+
Bridging a solution will extend the MsBuild process to create a custom debugger visualizer assembly for each project. These assemblies are created or updated when you build your projects.
27+
Private and internal classes _are not_ included, magnifier glass will not be available for them.
28+
Run the solution, set a breakpoint and hover the mouse pointer on any object instance and the magnifier glass will appear.
29+
If the magnifier glass does not appear, after you bridged and rebuilt your solution, make sure that in this folder _"C:\Users\youruser\Documents\Visual Studio 201**x**\Visualizers"_ there is/are assemblies with this name template "***AssemblyName**.Visualizer.V1**x**.dll*" (where x is the version number of Visual Studio).
30+
If the folder does not contain any assembly then please check the log files here: *C:\Users\youruser\AppData\Local\LINQBridgeVs* and open [a new bug](https://github.com/codingadventures/LINQBridgeVs/issues/new).
2731

28-
Rebuild your solution, run it, set a breakpoint and hover the mouse pointer
29-
on any object instance and the magnifier glass will appear.
32+
Do not keep two instances of two different version of LINQPad running (e.g. LINQPad 4 and LINQPad 5) at the same time. If you do so, the data will be automatically sent to the lower version of LINQPad.
33+
<br><br>
34+
![Example]
3035

31-
No need to mark any of your classes as Serialized.
36+
## Configuration
3237

33-
[LINQPad] (http://www.linqpad.net) it is to be installed beforehand.
38+
Unfortunately an installer is not available yet, therefore Visual Studio needs to be configured in order to run the extension. This is done only once by the extension itself.
39+
Only for the first time, Visual Studio must be run with Administrator privileges, if not a form will appear asking to restart Visual Studio:
40+
<br><br>
41+
![vsrestartimage]{.classname}
3442

35-
## Compatibility
43+
Once Visual Studio is restarted as Administrator, the configuration will complete and the form will never appear again.
3644

37-
LINQBridgeVs is compatible for Visual Studio 2012/2013/2015/2015/2017. It works **for .NET Framework 4.0 - 4.6.2**. There is no support for .NET Framework 2.0 to 3.5
45+
During this process two custom MsBuild Targets [Custom.After.Microsoft.Common.targets](https://github.com/codingadventures/LINQBridgeVs/blob/master/Src/VsExtension/Targets/Custom.After.Microsoft.Common.targets) and [Custom.Before.Microsoft.Common.targets](https://github.com/codingadventures/LINQBridgeVs/blob/master/Src/VsExtension/Targets/Custom.Before.Microsoft.Common.targets), are needed to extend the MsBuild process. They are copied into specific Visual Studio version and edition's folder:
46+
* Visual Studio 2017 - C:\Program Files (x86)\Microsoft Visual Studio\2017\{Edition}\MSBuild\v15.0
47+
* Visual Studio 2015 - C:\Program Files (x86)\MSBuild\v14.0
48+
* Visual Studio 2013 - C:\Program Files (x86)\MSBuild\v12.0
49+
* Visual Studio 2012 - C:\Program Files (x86)\MSBuild\v4.0
3850

39-
Either LINQPad 4 and LINQPad 5 are supported.
51+
You can skip this process but you will not be able to use the extension until you complete the configuration.
4052

41-
[logo]: https://raw.github.com/codingadventures/LINQBridgeVs/master/Src/VsExtension/LINQBridgeLogo.png "LINQBridge"
53+
## Compatibility
4254

55+
LINQBridgeVs is compatible with any Visual Studio edition from 2012 to 2017. It works only for **.NET Framework 4.0 to 4.6.2**. There is no support for .NET Framework 3.5 downwards. LINQPad 4 and 5 are either supported.
56+
57+
## How it works
58+
59+
LINQBridgeVs uses a technique called [Aspect Oriented Programming](https://wikipedia.AOP). AOP is a programming paradigm that aims to increase modularity by allowing separations of cross-cutting concerns (read behaviors) without modifying the code itself. In general this is achieved by adding an extra step in the build process, usually after the assembly is created. Specifically in Visual Studio the [MsBuild](https://en.wikipedia.org/wiki/MSBuild), which is the Microsoft Build Engine, is to be extended to use AOP. This can be done by either copying a [custom Target file](https://msdn.microsoft.com/en-us/library/ms164312.aspx) to the MsBuild installation folder or by adding ***Target*** tags in a project file like the following:
60+
```xml
61+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
62+
Other similar extension points exist, see Microsoft.Common.targets. -->
63+
<Target Name="BeforeBuild">
64+
</Target>
65+
<Target Name="AfterBuild">
66+
</Target>
67+
```
68+
69+
This extension uses custom build Targets in order to avoid the modification of each individual project.
70+
71+
When a solution is *Bridged*, every projects in it is essentially flagged. Configuration values are stored in the Windows Registry at this location ***\HKEY_CURRENT_USER\Software\LINQBridgeVs***
72+
73+
![registry]{.classname}
74+
75+
For each flagged project the custom tasks that extend the MsBuild engine mentioned earlier, perform some operation on the corresponding generated assembly. These tasks are:
76+
77+
* **Mapper Task** - This task creates a Custom Debugger Visualizer assembly for each project.
78+
* **SInjection Task** - SInjection stands for "Serializable Injection". This task reads the built assembly and mark every public class and struct as Serializable. By doing so it's then possible to use binary serialization through the [BinaryFormatter](https://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatters.binary.binaryformatter(v=vs.110).aspx) which is the standard binary serializer available in the .NET framework. Binary serialization is pretty powerful, and also fast. I prefer it over Json serialization, as it proved to be more suitable for complex object graphs.
79+
* **Clean Task** - This taks deletes the custom visualizers assemblies. It is invoked either by rebuilding or cleaning the solution.
80+
81+
## Architecture of a Debugger Visualizer
82+
83+
From the [MSDN documentation](https://docs.microsoft.com/en-us/visualstudio/debugger/create-custom-visualizers-of-data):
84+
>Visualizers are components of the Visual Studio debugger user interface. A visualizer creates a dialog box or another interface to display a variable or object in a manner that is appropriate to its data type. For example, an HTML visualizer interprets an HTML string and displays the result as it would appear in a browser window; a bitmap visualizer interprets a bitmap structure and displays the graphic it represents. The Visual Studio debugger includes six standard visualizers.
85+
>
86+
The process of creating custom visualizers to extend the debugger is not too complicated. However it requires a lot of setup, either for mapping a class to custom visualizer but also to prepare the class for serialization.
87+
88+
The architecture of a debugger visualizer has two parts:
89+
90+
* The debugger side runs within the Visual Studio debugger.
91+
* The debugger-side code creates and displays the user interface for your visualizer.
92+
93+
The debuggee side runs within the process Visual Studio is debugging (the debuggee). The debuggee side has to send that data object to the debugger side, which can then display it using a user interface you create. In order to send that data, the object needs to be serialized. Unless you use a serializer, like JSON.NET, that requires no markup on neither the class itself nor on the properties, the class must be marked as Serialized, or with other specific attributes depending on the serializer.
94+
95+
Below is an example of what it is needed to map a class to a custom debugger visualizer:
96+
```csharp
97+
using DebuggerVisualizerExample;
98+
using Microsoft.VisualStudio.DebuggerVisualizers;
99+
using Microsoft.Windows.Form;
100+
101+
[assembly: System.Diagnostics.DebuggerVisualizer(
102+
typeof(DebuggerSide),
103+
typeof(VisualizerObjectSource),
104+
Target = typeof(Class1),
105+
Description = "My First Visualizer")]
106+
[assembly: System.Diagnostics.DebuggerVisualizer(
107+
typeof(DebuggerSide),
108+
typeof(VisualizerObjectSource),
109+
Target = typeof(Class2),
110+
Description = "My First Visualizer")]
111+
[assembly: System.Diagnostics.DebuggerVisualizer(
112+
typeof(DebuggerSide),
113+
typeof(VisualizerObjectSource),
114+
Target = typeof(Class3),
115+
Description = "My First Visualizer")]
116+
namespace DebuggerVisualizerExample
117+
{
118+
[Serializable]
119+
public class Class1 { }
120+
121+
[Serializable]
122+
public class Class2 { }
123+
124+
[Serializable]
125+
public class Class3 { }
126+
127+
public class DebuggerSide : DialogDebuggerVisualizer
128+
{
129+
protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
130+
{
131+
MessageBox.Show(objectProvider.GetObject()); //obviously MessageBox can't show any object we pass to it
132+
}
133+
}
134+
}
135+
```
136+
137+
For each class, *Class1, Class2, Class3* it is needed a global assembly attribute that maps the type to a debugger visualizer. This extension does all of this automatically. Internally it uses the .NET BinaryFormatter to send the data from the debuggee to the debugger. In case the BinaryFormatter fails to serialize the data, JSON.NET is used instead.
138+
139+
## Acknowledgments
140+
141+
I have used several community open source projects to make this extension. So if you like LINQBridgeVs I recommend checking out the following:
142+
143+
* [JSON.NET](https://github.com/JamesNK/Newtonsoft.Json) is an awesome serializer. It has become part of the .NET Framework and it is used by millions worlwide, now it has become the standard. LINQBridgeVs mainly uses the BinaryFormatter but in case it fails it falls back on JSON.NET.
144+
* [VsRestart](https://github.com/ilmax/vs-restart) is an extension that restart Visual Studio under Administrator privileges. Unfortunately the project seems abandoned and the extension works only with Visual Studio 2013. However but code proved to be working with any version really.
145+
* [MahApps](https://github.com/MahApps/MahApps.Metro) which was the first open source project to make WPF truly modern.
146+
* [LINQPad](http://www.linqpad.net) super useful scratch pad for C#, VB, F#, SQL. Without it this extension wouldn't exist.
147+
* [Mono.Cecil](http://www.mono-project.com/docs/tools+libraries/libraries/Mono.Cecil/) very famous and useful AOP library designed, written and maintaned by JB Evain to generate and inspect programs and libraries in the ECMA CIL format.
148+
* [ILMerge](https://github.com/Microsoft/ILMerge) is a utility that merges multiple .NET assemblies into a single assembly.
43149

150+
[logo]: https://raw.github.com/codingadventures/LINQBridgeVs/master/Src/VsExtension/LINQBridgeLogo.png "LINQBridge"
151+
[vsrestartimage]:https://github.com/codingadventures/LINQBridgeVs/blob/master/Docs/VsRestart.PNG?raw=true(=250x)
152+
[Example]:https://github.com/codingadventures/LINQBridgeVs/blob/master/Docs/Example.gif?raw=true
153+
[registry]:https://github.com/codingadventures/LINQBridgeVs/blob/master/Docs/Registry.PNG?raw=true
154+
<style type="text/css">
155+
.classname{
156+
width: 500px;
157+
display: block;
158+
margin-left: auto;
159+
margin-right: auto;
160+
}
161+
</style>

0 commit comments

Comments
 (0)