Some time ago, Patrick Smacchia (NDepend lead developer) offered me a NDepend Pro license to play around. NDepend is a tool providing a lot of features. The feature that impressed me from the very start is visualizing dependencies. Not just dependencies from classes to classes, or assemblies to assemblies; no from everything to everything. Like for example all assemblies that use somewhere the method Foo of class Bar. It works for assemblies, namespaces, types, methods and fields.
But, what’s all this fuss about?
Keeping a code base and its design as simple as possible over a long period of time is very difficult. It happens just too quickly that we loose the overview of how things are sticked together. And this is the moment when NDepend with its quick and easy dependency visualization comes to the rescue.
Let’s take a look at an example.
I use the state machine (bbv.Common.StateMachine) of the bbv.Common project as an example. The state machine assembly references two other assemblies of the bbv.Common project: bbv.Common.AsyncModules (for active state machines) and bbv.Common (string formatters and basic types):
References of bbv.Common.StateMachine created with NDepend: select all assemblies that ‘bbv.Common.StateMachine’ uses directly or indirectly and visualized in graph view
Now consider the scenario that I want to refactor the method ConvertToString(IEnumerable enumerable) in the class FormatHelper in the assembly bbv.Common.
Therefore, I just select the method in the class browser of NDepend and select all methods that depend directly or indirectly on this method. Finally, I can visualize the result in the Graph view:
Direct and indirect usages of ‘FormatHelper.ConvertToString’ in the bbv.Common.StateMachine assembly. Box size equals the lines of code the box represents and edge thickness represents how many members of the dependency are used.
This took me about 3 seconds and I get a nice overview where this method is used. Now I know that a change to ‘FormatHelper.ConvertToString’ may have an impact on all this methods.
And now the Untangling
You’ve seen two tiny features of NDepend. But these two features already provide me a powerful tool to keep the dependencies in my code base simple. When I get the feeling that something in my design gets complicated or I simply lost the overview. I fire up NDepend and let me show the dependencies. For example for namespaces in bbv.Common.StateMachine:
Namespaces of bbv.Common.StateMachine visualized with the NDepend Graph view.
What immediately strikes the eye is the fat red arrow between bbv.Common.StateMachine and bbv.Common.StateMachine.Internals. That means, there are types in both namespaces that depend on types of the other namespace. A design smell for my clean code understanding.
Therefore lets fire up the NDepend dependency matrix just for this connection (by choosing open this cycle on dependency matrix) and drill down into the namespaces:
Dependency matrix of NDepend showing dependent elements: blue = element from top uses element on the left, green = element on the left uses element on top, black = both elements use their counterpart.
With this information, I can start to untangle the namespaces to get code that is better and quicker understandable and easier to extend for users of the library. Obviously, there is quite some work to do here. Fortunately, nobody has complaint till now 🙂
NDepend helps to quickly get an overview of a code base and what depends on what. Especially for code that is worked on for a long time, this helps tremendously, to reduce complexity.
That’s it for now. But stay tuned, NDepend offers much more…
I’m also a heavy Resharper user. Resharper offers itself navigation and simple visualization of dependencies. However, NDepend delivers you the information needed to start untangling dependencies faster and with more easy.
Why I like … posts are not about a tool or process being better that others, it’s just my thoughts what makes them useful for me in my projects.