Visual Studio extensibility - different MEF versions for Visual Studio version?
I am creating a Visual Studio extension and I want to [Export] a different implementation of this interface that the Visual Studio version runs on, for example one implementation for Visual Studio 2010 and 2012 and another for Visual Studio 2013 and Visual Studio "14".
I realize that I could just deploy a different DLL for each version of Visual Studio, but I'm wondering if there is a way to avoid this - sending the same DLL and the same vsixmanifest, but dynamically expanding my [Export] version of the interface.
What's the most eloquent way to do this?
source to share
It is not clear from your question that you really need to have a separate export. Several options are available to support multiple versions of Visual Studio:
-
Determine the minimum version of Visual Studio you want to support and only reference unmodifiable and / or assembly versions from that version of Visual Studio and earlier. Perhaps your extension will work in multiple versions without any changes or special considerations. This is the best option when "reasonable" is possible.
-
Export one item, but implement it using assemblies designed for specific versions of Visual Studio. For example, the Inheritance Margin extension requires an untranslated assembly reference, so I need to include separate implementations for each supported version of Visual Studio. It is implemented by providing a single shared exported object
CSharpInheritanceTaggerProvider
, but the implementation of the tagger itself is delegated to the dynamically selected assembly . -
Export multiple items, but only perform operations specific to the current version of Visual Studio. The GitDiffMargin extension uses this feature to position the scroll control in the most appropriate place. Although an assembly does not require reference to untranslated assemblies, starting in Visual Studio 2013, the optimal location for this field in the user interface has changed, and the MEF metadata attributes statically determine the location.
source to share
You can export one class that implements the interface, and have that class function as a proxy for the actual implementation according to the Visual Studio version. For example:
[Export(typeof(IMyInterface))]
public class ProxyClass : IMyInterface
{
private IMyInterface impl;
public ProxyClass()
{
if (IsVs2014())
{
impl = new Vs2014Impl();
}
else
{
impl = new Vs2013Impl();
}
}
public void DoSomething()
{
impl.DoSomething();
}
}
source to share
I haven't tried this, just thought about it after a few minutes, maybe it might work:
public enum VisualStudioVersion
{
Unknown,
VS2010,
VS2012,
VS2013,
VS14
}
public class VsSpecificExportAttribute : ExportAttribute
{
// the place for this is not right,
// but you can figure this out on your own.
private static VisualStudioVersion _currentVisualStudioVersion =
VisualStudioVersion.VS2013;
class DummySentil{}
public VsSpecificExportAttribute(Type typeToExport,
VisualStudioVersion visualStudioVersion)
: base(visualStudioVersion == _currentVisualStudioVersion ?
typeToExport : typeof(DummySentil))
{
}
}
then you can use it like:
[VsSpecificExport(typeof(IWpfTextViewCreationListener), VisualStudioVersion.VS14)]
public class MyTextViewCreationListener: IWpfTextViewCreationListener
{
}
The basic idea is that the "VsSpecificExport" attribute decides that we are on the correct "visual studio version", and if not, we are going to export a "DummySentil" class that uses absolutely nothing and is not used by anyone.
source to share