COM vs MEF: Visual Studio extension service providers

When writing a Visual Studio extension, you pretty much need to use Visual Studio services for everything. Put simply, a service in this context, is an object that implements an interface that exposes functionality to interact with different parts of the IDE. For instance, a common service used to deal with the Visual Studio editor is the EnvDTE.DTE.

If you are building a VSPackage then likely you have used the System.IServiceProvider interface that is initialized in your VSPackage to get instances of the COM Visual Studio services. It usually looks like this:

OleMenuCommandService commandService = this.ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService;  

Since VS2015, I believe, Managed Extensibility Framework (MEF) was introduced as a nicer way to perform dependency injection, which looks like this:

// you can import services directly into a class member, MEF will initialize it when it constructs an object off of your class
internal IClassificationTypeRegistryService ClassificationRegistry;  

There is a lot to talk about MEF, but what I want to point out in this post is that
COM and MEF services/types are not interchangeable. The IServiceProvider will only give you the COM services. The MEF imported types are not exposed by it. If you need to get a MEF-provided types from IServiceProvider, you first need to get an instance of SComponentModel a COM service capable of resolving the MEF types you need. For example:

// first the the SComponentModel from IServiceProvider
var componentModel = (IComponentModel)serviceProvider.GetService(typeof(SComponentModel));

// then we can get the MEF type we need
var adapter = (IVsEditorAdaptersFactoryService)componentModel.GetService<IVsEditorAdaptersFactoryService>();  

Alternatively, if you are in a MEF imported type and need to get access to a COM service, you could import the SVsServiceProvider interface and use it like the IServiceProvider.