检查项目引用的分析器

Analyzer that checks project references

我想创建一个解决方案来控制 C# 项目中的项目引用。理想情况下,此解决方案与 IDE 无关,因此它可以与 Visual Studio、Jetbrains Rider 甚至 VS Code 一起使用。这样做的原因是,由于人们创建了几乎任意的项目引用,我看到了完全混乱的解决方案。在项目发展到一定规模后,很难让他们直截了当。

我知道 Visual Studio Enterprise 提供了这个开箱即用的功能。不幸的是,在我目前的公司中,我们没有 VS Enterprise。因此,我想自己创建它。

那么最好的方法是什么?在做了一些研究之后,我认为利用 .NET 编译器平台 ("Roslyn") 及其工作区 API 可能是个好主意?似乎我可以将它部署为 NuGet 包,然后可以在任何 IDE 或构建自动化中使用。但也许有更简单或更好的方法,在我开始深入研究之前,我想听听您的意见。

此外:如果 "Roslyn" 方法是正确的,是否有一些关于如何创建与工作区 APIs 一起使用的分析器的好资源?

提前致谢。

在您的分析器中,注册一个编译启动操作:

public override void Initialize(AnalysisContext context)
{
    context.RegisterCompilationStartAction(Initialize);
}

private void Initialize(CompilationStartAnalysisContext context)
{
    var compilation = context.Compilation;
}

从那个编译对象,你有多种选择:

var referencedAssemblyNames = compilation.ReferencedAssemblyNames;

var references = compilation.References;

那就做你的分析吧。要报告诊断,请使用 context.RegisterCompilationEndAction.

CompilationStartAnalysisContext 上注册一个操作

如果您不需要查看实际项目内容进行分析,您可以简单地使用RegisterCompilationAction,如下所示:

[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));
        }
    }
}