Posted on Friday July 2011
NDepend. That’s the answer.
However, the question was, how can I visualize dependancies in a .NET assembly? And as it turns, quite easily indeed.
First of all, this is what I am talking about. Here is a graph showing constructor injection (you know, IoC, DI, etc.) in an application I wrote a while back that downloads MP3 from RSS/ATOM feeds.
The Downloader model class expects Download and RSS Managers to be injected, among other things. You can also see possible issues, such as a concrete reference to History, instead of IHistory, for example.
When you use a tool like Castle, or Unity, or Structure map, etc, you will become familiar with the term “dependency graph” – this is literally a visualization of such a graph.
We can also visualize class inheritance and interface implementations:
MainView is a WPF window by the look of it, and inherits a lot of stuff because of it.
Or assembly references:
The MediaGrabber assembly references the usual system assemblies, as well as Castle and the RSS and Download manager components.
And if I ever get around to it, you could also visualize namespace references as well...
In essence all I am doing is some simple reflection over an assembly, and graphing relationships between types and/or assemblies.
private void ShowConstructorInjection(Assembly rootAssembly)
{
AddAllParentTypes(rootAssembly);
foreach (var type in rootAssembly.GetTypes())
{
// inspect constructors
foreach (var constructor in type.GetConstructors())
{
// here we look at constructor injection
// to determine a "dependency"
foreach (var param in constructor.GetParameters())
{
try
{
AddVertex(param.ParameterType.FullName);
GraphToVisualize.AddEdge(new Edge<object>(param.ParameterType.FullName, type.FullName));
}
catch { }
}
}
}
}
The graphing and visualization is handled by the most excellent QuickGraph and Graph# respectively.
You can grab the source code here and have a play. I can tell you now, it’s pretty brittle and will crash a lot :)
For comparison, this is a small part of DotNetNuke6, constructor injection (that's System.Object in the center, btw...):