When refactoring, it’s often hard to see which methods can easily be moved to another class, and what depends on what. Visual Studio has a built-in tool that can make this pretty easy, and almost fun! For a quick video overview of the tool, see this Channel9 video. The current article covers a lot of what is in that video, but concentrates on how to use the tool for refactoring. It’s worth watching the video, as there is a lot more to this than will be shown here.
Note: The dependency graph feature is only available in the Grown Up versions of Visual Studio, ie Enterprise, Ultimate or whatever-they-call-it-this-week versions
Creating a dependency graph
To get started, click the Architecture menu, choose Generate Dependency graph, and then For Solution…
Sadly, you only seem to be able to do this for a whole solution (the For Include File option is for C++ code only), which is a pain when you only want to analyse one class, but it’s still worth the wait. This will rebuild the entire solution, then analyse it, before building the graph. This can take some time, so feel free to search for cute cat pictures on the Internet (that’s what Google was invented for isn’t it?)…
Once the graph has been build, it will probably look fairly horrible, as Visual Studio attempts to connect absolutely everything. It’s probably worth removing such things as entity assemblies (which are referenced pretty much everywhere), external assemblies (which probably won’t be part of the refactoring) and so on. This will make the graph more manageable.
Note: It is a common gesture in graphical designers that the mouse wheel scrolls the canvas, and Ctrl-mouse wheel scales the designer. For some bizarre reason, Microsoft decided to confuse us, and do it differently here. When working with dependency diagrams, the mouse wheel zooms, irrespective of whether or not you hold down Ctrl at the same time. In order to scroll, you need to drag a blank part of the designer surface. If you drag any object, it will move the object. This all takes some getting used to!
Clarifying the graph so you can use it
If you want to visualise one specific area, then remove anything not related to that area. This will simply the graph somewhat. For example, here is a graph that just shows the relationship between the service, business logic and repository assemblies for the a solution (zoomed in somewhat)…
This is a little more manageable! If you hover your mouse over an assembly, a small icon appears that allows you to expand the assembly…
The initial view is, erm, rather difficult to use!
If you zoom in, you’ll see that inside the panel for the DLL is a panel for the class in question, and inside that is a panel for the class. Inside the class are boxes for the properties and methods. Those are the weeny light-grey rectangles you can just about see in the picture above.
Looking for potential refactorings
If you click on the title bar of a class in the assembly, and move your mouse in just the right way (which takes some practice), you get a small pop-up menu. The last icon allows you to change the view…
It’s worth playing with these, as some of them can even be useful!
The Quick Clusters option is worth exploring. It attempts to cluster the methods and properties of the class together…
You can see straight away that we have a few isolated items at the top-right. These are prime candidates for being pulled out into their own classes.
You can also see that whilst the majority of code in the class centres around the VrtSystemsRepository node (logical, as this is a systems business logic class, so most methods will access the corresponding repository), there is also a cluster of nodes in the middle that seems to be somewhat tenuously connected to the ones on the left. A little rearranging reveals something interesting…
The only connection between these items and the majority to the left (not shown in this picture) is the Log object. That is used for logging, and is not actually specific to this class. We can see that all of the methods and properties in this cluster could be moved into their own class, as long as that class has its own Log object.
Note: One of the (rather many) annoying things about this otherwise excellent tool is that if you move any objects around, then change the view, when you change back, it arranges the objects in their default positions, and doesn’t remember where you moved them. This means that the clarification we gained above would be lost.
It’s often worth dragging your dependent objects aside, as this can reveal other clusters, whose only connection is the injected dependency. Again, you could pull the related methods into another class, and add injection dependencies as required.
If you double-click a method in the graph, the code file opens at that method. Depending on the mood that Visual Studio is in at the time, it sometimes moves the graph to a separate tab group, allowing you to work on both files at the same…
If you look carefully, you’ll see that as you click around the code, the current method gets a little green arrow next to it in the graph. See the GetSystemInfoAndSystemInstallationDate() method in the graph, which is selected (yellow border), and has a little green arrow to its left. The green arrow is largely pointless, but doubtless made some Microsoft executive happy when it was demonstrated. I wonder if he was a fan of the DC Comics hero of the same name?
There is a lot more to this tool than has been shown here, but this alone is very useful stuff.
Saving dependency graphs
If you are a Real Developer(TM), then your left hand is probably twitching with the “Ctrl-S twitch,” which is the compulsion to save your file every three picoseconds, in case Visual Studio decides to stop responding (it wouldn’t do that would it?) and lose your work. If so, then you’re in for a surprise, and not a very pretty one either!
For reasons that completely escape me, someone at Microsoft (doubtless a pointy-haired boss) decided that dependency graphs aren’t worthy of being considered part of the solution. Therefore, when you save one, you’ll find it doesn’t appear anywhere in the solution. You have to save it, then right-click in Solution Explorer and choose Add → Existing Item, and include the .dgml file. Ho hum.
It’s probably an idea to add a folder called DependencyGraphs to your solution (using Windows Explorer, not via Visual Studio), then add a solution folder in Visual Studio, and use Add → Existing Item to include the graph files in the solution folder. All hugely intuitive, and highly logical, no? Erm, no.