An American colloquialism holds, “only two things are certain: death and taxes.” If I had to appropriate that for the software industry, I might say that the two certainties are death and legacy code. Inevitably, you have code that you have had for a while, and you want to do things with it.
Software architects typically find themselves tasked with such considerations. Oh, sure, sometimes they get to pick techs and frameworks for greenfield development. Sometimes they get to draw fancy diagrams and lay out plans. But frequently, life charges them with the more mundane task of “figuring out how to make that creaky old application run on an iPhone.” Okay, maybe it’s not quite that silly, but you get the idea.
If you earn a living as an architect in the .NET world, you have, no doubt, contemplated the impact of .NET Core on your application portfolio. Even if you have no active plans to migrate, this evolution of .NET should inform your strategic decisions going forward. But if you have use for deploying the framework along with your application or if you want to run on different operating systems, you’re going to need to port that legacy code.
I am, by no means, an expert in .NET Core. Instead, my areas of specialty lie in code analysis, developer training, and IT management and strategy consulting. I help dev teams create solutions economically. And because of this, I can recognize the value of NDepend to a port from what I do know about .NET core.
Is Your Code Worth Preserving?
As I’ve mentioned various times on this blog, part of my consulting practice revolves around codebase assessments. I help clients understand how aspects of their code translate to business outcomes. Often, NDepend plays a key role in such assessments.
Clients often ask me the question, “is this code worth preserving?” Obviously, this question invites intense subjectivity. But that doesn’t mean you can’t establish some objective criteria for answering. NDepend’s extensive code quality metrics and code rules help you get started. On top of that, you can use it to identify problematic areas of the codebase and recurring anti-patterns.
If your applications sets off red flags left and right, you may want to rethink your strategy. Do you have classes that are thousands of lines? How about methods that are brutally complex? Is the code of even marginal quality?
Use the tool to give yourself an idea as to the state of your code. Sometimes simply looking at things from a new angle can give you the jolt that you need to consider a new option. It’s possible that you’d be better off starting from scratch with .NET core than trying a port.
Identifying Dependencies
If you’re satisfied that porting your code would be worthwhile, you should first run this API port utility on the prospective codebase. It will furnish you with a high level summary of assembly portability, and a list of non-portable API usage. That gives you a great start, but NDepend can further help you.
The utility itself provides a general score and a list. But NDepend specifically deals in helping you visualize and manage your dependencies. Use NDepend to see just how daunting a task you face. Perhaps the actual scope of your dependence is more or less than you think. Alternatively, you might find hidden, transitive dependencies.
How Modular Are You?
Once you have a feel for the mechanics of the port and dependency management, it’s time to look at a higher level architectural concern. How modular is your application?
.NET Core, for instance, does not support Webforms. But perhaps you were thinking that you’d prefer to move forward with MVC anyway and were willing to incur the cost of migrating both to .NET Core and to MVC.
That’s a fine goal, to be sure, but is it realistic? NDepend can help you visualize properties in your codebase that help you understand. The aforementioned dependencies factor in, certainly. And you will also want to look at cohesion, coupling, and fan-in as well. NDepend can help you paint a picture of whether a partially portable codebase is modular enough to evolve or not.
Ad Hoc Queries
In the past, I’ve blogged about treating code as data. Powerful visualization tools, informative out of the box rules, and tons of capabilities all make NDepend a wonderful tool. But perhaps its most subtle, and possibly underrated, value proposition comes from it allowing you to make ad hoc queries of your code.
Consider the aforementioned Webforms example. Beyond what NDepend gives you immediately, you might want other questions answered. “What percentage of classes in my code base reference a Webforms namespace?” “Which assemblies depend on Webforms?” “What is the average cyclomatic complexity of code behind methods?”
CQLinq and the NDepend API grant you a whole lot of power. Using these tools, you can construct answers to questions like these that you might have about your codebase. In fact, you can construct answers to far more questions than I can dream up and feed you as examples.
For the architect role, the answers to questions like that furnish true power. The business wants capability, and you find yourself tasked with helping them achieve that. If your respond with, “gosh, I don’t know if this will work,” the counter will likely be “make it work.” If, on the other hand, you respond with “80% of classes in this code depend on something we cannot port,” you’ll encounter far less pushback.
Whether for .NET Core or, really, for any other major architectural initiative, NDepend gives you the ammo to make good decisions and good arguments.