2014-09-13 6 views
3

Я создаю расширение Visual Studio, и я хочу [Экспортировать] другую реализацию данного интерфейса, на основе которой выполняется версия Visual Studio, например, одна реализация для Visual Studio 2010 и 2012, а другая для Visual Studio 2013 и Visual Studio «14».Расширяемость Visual Studio - разные версии MEF для каждой версии Visual Studio?

Я понимаю, что я мог бы просто развернуть различную DLL для каждой версии Visual Studio, но мне интересно, есть ли способ избежать этого - отправка одной и той же DLL и того же vsixmanifest, но динамическое расширение с помощью [Export] правильная версия интерфейса.

Что является самым красноречивым способом для этого?

ответ

2

Это не ясно из вашего вопроса, что вы на самом деле нужно иметь отдельный экспорт. Несколько вариантов для поддержки нескольких версий Visual Studio доступны:

  1. Определить минимальную версию Visual Studio вы хотите поддержать, и ссылаться только immutable and/or versioned assemblies от этой версии Visual Studio и раньше. Возможно, ваше расширение будет работать в нескольких версиях без каких-либо изменений или особых соображений. Это лучший вариант, когда «разумно» возможно.

  2. Экспортируйте один элемент, но реализуйте его с помощью сборок, предназначенных для определенных версий Visual Studio. Например, для расширения Inheritance Margin требуется ссылка на непереведенную сборку, поэтому мне нужно включить отдельные реализации для каждой поддерживаемой версии Visual Studio. Он реализуется путем предоставления single common exported object CSharpInheritanceTaggerProvider, но реализация самого тегатора делегируется на dynamically selected assembly.

  3. Экспортировать несколько элементов, но выполнять только операции, относящиеся к текущей версии Visual Studio. Расширение GitDiffMargin использует эту функцию для размещения элемента управления прокруткой в ​​наиболее подходящем месте. Хотя сборка не требует ссылки на непереведенные сборки, начиная с Visual Studio 2013, оптимальное расположение для этого поля в пользовательском интерфейсе изменилось, а атрибуты метаданных MEF статически определяют размещение.

2

Вы можете экспортировать один класс, который реализует интерфейс, и иметь эту функцию класса в качестве прокси-сервера для фактической реализации в соответствии с версией визуальной студии. Например:

[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(); 
    } 
} 
+0

Для справки это похоже на то, что @JaredPar делает в VsVim, используя Factory вместо прокси-сервера. Существует интерфейс ISharedService и [SharedServiceFactory.cs] (https://github.com/jaredpar/VsVim/blob /848f333b942eaa2ddde2cbfb08362d03d0491f7a/Src/VsVimShared/Implementation/SharedService/SharedServiceFactory.cs), который «Импортирует» все различные реализации и выбирает правильный для каждой версии VS. –

0

Я не пробовал, просто думал, что это в течение нескольких минут, возможно, она может работать:

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)) 
    { 
    } 
} 

, то вы могли бы использовать это как;

[VsSpecificExport(typeof(IWpfTextViewCreationListener), VisualStudioVersion.VS14)] 
public class MyTextViewCreationListener: IWpfTextViewCreationListener 
{ 

} 

Основная идея заключается в том, что «VsSpecificExport» атрибут решает wheenever мы на правильной «Visual Studio версии», и если мы не будем, мы будем экспортировать класс «DummySentil», что абсолютно ничего не делает и его никто не использует.

+0

Это интересный подход - мне было бы интересно узнать, работает ли он. –

+0

Я подозреваю, что это не будет работать, поскольку атрибуты не являются «динамическими», например, они будут помещены в метаданные сборки во время компиляции. –