Reputation: 1193
I have a custom Roslyn analyzer which inherits from DiagnosticAnalyzer
. It is packed in VSIX extension which contains custom Package
class. I'd like to pass an instance of a class with the settings (CodeAnalysisSettings
instance) from the package to my DiagnosticAnalyzer
.
I've tried to use MEF for that purpose. I've registered an instance of my settings class in VS Package using the following code:
protected override void Initialize()
{
base.Initialize();
IComponentModel componentModel = Package.GetGlobalService(typeof(SComponentModel)) as IComponentModel;
new CompositionContainer(componentModel.DefaultCatalog).ComposeExportedValue(
new CodeAnalysisSettings(...));
}
Analyzer looks as follows:
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class MyAnalyzer : DiagnosticAnalyzer
{
[Import]
public CodeAnalysisSettings Settings { get; set; }
}
Settings class:
[Export]
public class CodeAnalysisSettings
{
public CodeAnalysisSettings()
{
}
public bool RecursiveAnalysisEnabled { get; }
}
For some reason Settings
property is not imported - its value is always null.
Please help.
Upvotes: 2
Views: 926
Reputation: 3904
The Microsoft VSIX Community Toolkit has a Dependency Injection Nuget package that adds DI to your VSIX extension. It allows you to add your own IOC container or use theirs.
VSIX Community Toolkit Package on GitHub
Upvotes: 1
Reputation: 1193
I've ended up using a service locator (CommonServiceLocator package) that consumes MEF container as a source.
Since VS infrastructure doesn't allow adding new registrations (IComponentModel.DefaultCatalog
throws an exception which tells that this functionality is not supported anymore), I've created a new container inside Package.Initialize()
:
var container = new CompositionContainer(CompositionOptions.Default, componentModel.DefaultExportProvider);
container.ComposeExportedValue<CodeAnalysisSettings>(new CodeAnalysisSettings(...));
var serviceLocator = new MefServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => serviceLocator);
Roslyn diagnostic consumes this dependency:
var settings = CodeAnalysisSettings.Default;
if (ServiceLocator.IsLocationProviderSet)
settings = ServiceLocator.GetInstance<CodeAnalysisSettings>();
Upvotes: 1