依赖注入Roslyn分析器

时间:2018-08-20 14:41:20

标签: c# dependency-injection mef roslyn vsix

我有一个自定义的Roslyn分析器,该分析器继承自DiagnosticAnalyzer。它包装在VSIX扩展中,该扩展包含自定义Package类。我想将具有设置的类实例(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属性未导入-其值始终为null。

请帮助。

1 个答案:

答案 0 :(得分:1)

我最终使用了使用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);

罗斯林诊断消耗了这种依赖性:

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