This is an article about using Roslyn Workspaces to run quick one-off analysis on your .NET projects without going into complexities of analyzers and code-fixes. It builds upon part 1, where we created a query that analyzed logical expressions inside our code-base. This time we will use Workspaces to replace invocations of an obsolete method with a newer version.
Our synthetic code-base emulates a reporting system for a big corporation. The system pulls together information form accounting, HR, sales and supply systems and prepares analytical reports for our users. It's a big system that has been around for over a decade, so there is quite a bit of legacy code in it. Today we finally decided to get rid of the obsolete overload of our most called method ScheduleReport. We want to replace:
var scheduleId = reportSchedulingSystem.ScheduleReport(reportName, false, id, null, null, null);
var scheduleId = reportSchedulingSystem.ScheduleReport( reportName, new UserIdsAcrossSystems(userIdInAccountingSystem: id), false).id;
in a fully automated manner.
Roslyn compiler platform is among the best things that happened to .NET in the previous decade. 10 years ago static code analysis was reserved for teams of highly dedicated programmers who spent hundreds of hours studying C# compilation process and intermediary models that stood between a programs text and resulting byte-code. Thanks to their contribution and great work done by the .NET team, today we can achieve the same result in mere hours with a comprehensive and user-friendly API gateway into the compilation process. This article will show you the easiest, yet very practical form of static code analysis with Roslyn, something that takes under an hour to use: Workspaces.
Roslyn is at the core of modern C# IDEs. When you click a screwdriver icon in Visual Studio and choose a quick refactoring - that's a Roslyn "code fix". When during compilation a 3-rd party library gives you a warning concerning how your code is using its API - that's Roslyn "analyzer".
There have been ample articles written about analyzers, including my own series 1↗ 2↗ 3↗ 4↗. But analyzers are not something that a typical dev gets to write often. They are mostly handled by teams maintaining libraries and frameworks. In day-to-day application development there isn't much opportunity to write them, nor is there budget to get through initial learning overhead. On the other hand, a typical enterprise developer routinely does refactoring work, analyzing various pieces of code in a big code-base, looking for spots that can be unified and improved. That's where Workspaces and one-off refactoring come in. One-off refactoring is much easier than writing an analyzer, since we don't have to worry about code efficiency and dozens of corner-cases that an analyzer has to account for. And with the relatively small amount of effort needed to get comfortable with such refactoring - it becomes a net positive time saved very quickly.