首页 > 解决方案 > 依赖注入到 Roslyn 分析器

问题描述

我有一个自定义的 Roslyn 分析器,它继承自DiagnosticAnalyzer. 它打包在包含自定义Package类的 VSIX 扩展中。我想将具有设置(CodeAnalysisSettings实例)的类的实例从包传递到我的DiagnosticAnalyzer.

为此,我尝试使用 MEF。我已经使用以下代码在 VS Package 中注册了我的设置类的一个实例:

protected override void Initialize()
{
    base.Initialize();
    IComponentModel componentModel = Package.GetGlobalService(typeof(SComponentModel)) as IComponentModel;
    new CompositionContainer(componentModel.DefaultCatalog).ComposeExportedValue(
                new CodeAnalysisSettings(...));
}

分析器如下所示:

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class MyAnalyzer : DiagnosticAnalyzer
{
    [Import]
    public CodeAnalysisSettings Settings { get; set; }
}

设置类:

[Export]
public class CodeAnalysisSettings
{
    public CodeAnalysisSettings()
    {
    }

    public bool RecursiveAnalysisEnabled { get; }
}

由于某种原因Settings,未导入属性 - 它的值始终为空。

请帮忙。

标签: c#dependency-injectionmefroslynvsix

解决方案


我最终使用了一个使用 MEF 容器作为源的服务定位器(CommonServiceLocator 包)。

由于 VS 基础设施不允许添加新注册(IComponentModel.DefaultCatalog抛出异常,表明不再支持此功能),我在内部创建了一个新容器Package.Initialize()

var container = new CompositionContainer(CompositionOptions.Default, componentModel.DefaultExportProvider);
container.ComposeExportedValue<CodeAnalysisSettings>(new CodeAnalysisSettings(...));
var serviceLocator = new MefServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => serviceLocator);

Roslyn 诊断使用此依赖项:

var settings = CodeAnalysisSettings.Default;
if (ServiceLocator.IsLocationProviderSet)
    settings = ServiceLocator.GetInstance<CodeAnalysisSettings>();

推荐阅读