Как добавить собственный анализатор roslyn из локально размещенной DLL?

Я создал проект Roslyn Analyzer, который генерирует пакет nuget и его DLL. Я хочу использовать эту DLL в отдельном проекте анализа кода. Как я могу это сделать? Например, у меня есть следующий код:

MSBuildLocator.RegisterDefaults();
var filePath = @"C:\Users\user\repos\ConsoleApp\ConsoleApp.sln";
var msbws = MSBuildWorkspace.Create();
var soln = await msbws.OpenSolutionAsync(filePath);
var errors = new List<Diagnostic>();
foreach (var proj in soln.Projects)
{
    var analyzer = //Here i want to load analyzer from DLL present locally.
    var compilation = await proj.GetCompilationAsync();
    var compWithAnalyzer = compilation.WithAnalyzers(analyzer.GetAnalyzersForAllLanguages());
    var res = compWithAnalyzer.GetAllDiagnosticsAsync().Result;
    errors.AddRange(res.Where(r => r.Severity == DiagnosticSeverity.Error).ToList());
}

Я пробовал следовать

var analyzer = new AnalyzerFileReference("Path to DLL", new AnalyzerAssemblyLoader());

Но здесь AnalyzerAssemblyLoader показывает ошибку, так как он недоступен для своего уровня защиты (класс внутренний).

Пожалуйста, предложите мне, если мы можем сделать это.


person EnigmaticJohn    schedule 16.06.2020    source источник
comment
Что произойдет, если вы сделаете класс общедоступным?   -  person Paulo Morgado    schedule 16.06.2020
comment
Этот класс определен в Microsoft.CodeAnalysis, поэтому я не могу его изменить.   -  person EnigmaticJohn    schedule 16.06.2020


Ответы (1)


опция .WithAnalyzers() позволит вам передать экземпляр анализатора. Если вы ссылаетесь на DLL локально, вы можете просто создать анализатор, как и любой другой объект, и передать его в компиляцию.

    var analyzer = new MyAnalyzer();
    var compilation = await proj.GetCompilationAsync();
    var compWithAnalyzer = compilation.WithAnalyzers(ImmutableArray.Create<DiagnosticAnalyzer>(analyzer));

Если вы не ссылаетесь на сборку, но хотите загрузить ее во время выполнения, вы можете использовать обычные методы на основе System.Reflection для получения экземпляра анализатора:

var assembly = Assembly.LoadFrom(@"<path to assembly>.dll");
var analyzers = assembly.GetTypes()
                        .Where(t => t.GetCustomAttribute<DiagnosticAnalyzerAttribute>() is object)
                        .Select(t => (DiagnosticAnalyzer) Activator.CreateInstance(t))
                        .ToArray();

compWithAnalyzers = compilation.WithAnalyzers(ImmutableArray.Create(analyzers));
person Chris Sienkiewicz    schedule 16.06.2020