I'd like to create a solution that controls the project references in C# projects. Ideally, this solution is IDE-agnostic so that it can be used with Visual Studio, Jetbrains Rider, or even VS Code. The reason for this is that I've seen solutions that are completely messed up due to people creating almost arbitrary project references. It's super hard to get them straight after a project has grown to a certain size.
I know that Visual Studio Enterprise offers this out-of-the-box. Unfortunately, in my current company we do not have VS Enterprise. Thus, I want to create that on my own.
So what would be the best way to do it? After doing some research I think leveraging the .NET Compiler Platform ("Roslyn") with its Workspace API might be a good idea? Seems like I could deploy it as a NuGet package which can then be used in any IDE or build-automation. But maybe there's an easier or better way, I'd like to hear your opinion on that before I start digging into it.
Also: if the "Roslyn"-way is the right one is there some good resources on how to create an analyzer that works with the Workspace APIs?
Thanks in advance.
In your analyser, register a compilation start action:
public override void Initialize(AnalysisContext context)
{
context.RegisterCompilationStartAction(Initialize);
}
private void Initialize(CompilationStartAnalysisContext context)
{
var compilation = context.Compilation;
}
From that compilation object, you have various options:
var referencedAssemblyNames = compilation.ReferencedAssemblyNames;
or
var references = compilation.References;
Then do your analysis. To report diagnostics, register an action on the CompilationStartAnalysisContext
using context.RegisterCompilationEndAction
.
If you don't need to look at actual project content for your analysis, you can simply use RegisterCompilationAction
as follows:
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public sealed class TooManyReferencesAnalyzer : DiagnosticAnalyzer
{
private static DiagnosticDescriptor TooManyReferences { get; } =
new DiagnosticDescriptor(
"DEMO",
"Don't use too many references",
"The project '{0}' has {1} references",
category: "Maintainability",
defaultSeverity: DiagnosticSeverity.Warning,
isEnabledByDefault: true);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
ImmutableArray.Create(TooManyReferences);
public override void Initialize(AnalysisContext context)
{
context.RegisterCompilationAction(AnalyzeCompilation);
}
private void AnalyzeCompilation(CompilationAnalysisContext context)
{
var compilation = context.Compilation;
int referenceCount = compilation.References.Count();
if (referenceCount > 5)
{
context.ReportDiagnostic(
Diagnostic.Create(
TooManyReferences,
null,
compilation.AssemblyName,
referenceCount));
}
}
}