2014-10-02 6 views
0

Я перехожу к функциям проекта к плагинам с исходящим интерфейсом и входящим абстрактным классом, реализованным хостом. Каждый плагин сохраняет свою конфигурацию в своем собственном классе, который переносится и сохраняется хостом. Эти классы конфигурации редактируются пользователем внутри PropertyGrid, затем сохраняются или передаются обратно в плагин перед выполнением.Предоставление TypeConverter через интерфейс или абстрактный класс

Конфигурации довольно стандартизированы и разделяют многие из тех же свойств, поэтому я пытаюсь предоставить соответствующие TypeConverters непосредственно из главной программы, так что каждый плагин не должен реализовывать свои собственные. Плагинов и класс конфигурации выглядеть примерно так:

Public Class MyPlugin 
    Implements IPlugin 

    Private _myData As PluginData 
    Private _host As HostMethods 

    ''..stuff.. 

    <Serializable()> _ 
    Public Class PluginData 
     Friend _someData As String 

     <TypeConverter(GetType(HostMethods.MyTypeConverter)), _ 
      DisplayName("My string data"), _ 
      DefaultValue("String one")> _ 
     Public Property SomeData() As String 
      Get : Return _someData : End Get 
      Set(ByVal value As String) : _someData = value : End Set 
     End Property 
    End Class 
End Class 

«HostMethods» является абстрактным классом, который хозяин переопределяет обеспечить функциональность плагинов, и является довольно стандартным:

Public MustInherit Class HostMethods 
    '..stuff.. 

    Public MustInherit Class MyTypeConverter : End Class 
End Class 

Тогда, Конечно, хост наследует этот класс, создает экземпляр и передает ссылку на каждый плагин, чтобы обеспечить его методы:

Friend Class HostServices 
    Inherits HostMethods 
    '..stuff.. 

    Public Shadows Class MyTypeConverter 
     Inherits ComponentModel.StringConverter 

     Public Overloads Overrides Function Get StandardValuesSupported(...etc... 
    End Class 
End Class 

При установке <TypeConverter(GetType(HostMethods.MyTypeConverter))> PropertyGrid видит только пустой класс, определенный в реферате, и я не могу переместить код ни в плагин, ни в абстракцию без круговой ссылки, так что что было бы правильным способом показать MyTypeConverter плагину? Я передаю ссылку на экземпляр HostServices плагинам при инициализации («_host»), но понятия не имею, могу ли я легко установить атрибут TypeConverter во время выполнения, и предпочел бы, чтобы атрибут был установлен в design- время.


Update: Я экспериментировал с добавлением атрибута во время выполнения (например: this question), но это не работает для меня в конце концов, потому что у меня не будет никакого способа знать какие свойства назначить для TypeConverters. Присвоение атрибуту необходимо, чтобы дизайнеры плагинов могли выбирать соответствующие преобразования для своих свойств.

Кроме того, я рассмотрел такие решения, как this one, которые включают в себя ручное решение имен сборок, но, похоже, для этого потребуется, чтобы мой конвертер типов находился в той же сборке, что и плагин.

ответ

0

На сегодняшний день я не смог сразу решить эту проблему, но для тех, кто может наткнуться на это с такой же вопрос, мой обходной путь следующим образом:

Я создал функцию в «HostMethods», которая возвращает те же данные, что и TypeConverter.

Public Overrides Function GetTypeConverterData() As String() 
    Return myTypeConverterData 'as appropriate... 
End Function 

Каждый плагин затем реализует свой собственный TypeConverter (вещь, которую я пытался избежать в целом), в случае необходимости, который извлекает данные из хоста, изменяет его по мере необходимости, а затем возвращает его стандартным способом.

Public Class MyPlugin 
    ''..other plugin stuff.. 

    <Serializable()> _ 
    Public Class PluginData 
     Friend _someData As String 

     <TypeConverter(GetType(MyPlugin.MyTypeConverter)), _ 
      DisplayName("My string data"), _ 
      DefaultValue("String one")> _ 
     Public Property SomeData() As String 
      Get : Return _someData : End Get 
      Set(ByVal value As String) : _someData = value : End Set 
     End Property 
    End Class 

    Public Class myTypeConverter 
     Inherits ComponentModel.StringConverter 

     Public Overloads Overrides Function GetStandardValuesSupported(..etc.. 
      Return True 
     End Function 

     Public Overloads Overrides Function GetStandardValues(..etc.. 
      Return MyPlugin._host.GetTypeConverterData() 
      'and/or other code, as necessary... 
     End Function 
    End Class 
End Class 

Это не идеальный вариант, но по крайней мере он прост.