首页 > 解决方案 > 检查项目引用的分析器

问题描述

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

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

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

另外:如果“Roslyn”方式是正确的,是否有一些关于如何创建与 Workspace API 一起使用的分析器的好资源?

提前致谢。

标签: c#roslynroslyn-code-analysis

解决方案


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

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;

然后做你的分析。要报告诊断,请在CompilationStartAnalysisContextusing上注册一个操作context.RegisterCompilationEndAction

如果您不需要查看实际项目内容进行分析,您可以简单地使用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));
        }
    }
}

推荐阅读