Вопрос

Я пытаюсь собрать систему плагинов с .NET и не уверен, правильно ли я это делаю.Основа системы заключается в том, что в определенном каталоге ({apppath}/Plugins/) будет несколько предварительно скомпилированных DLL, и я хочу просмотреть каждую из них с помощью отражения и для каждого доступного класса, если он наследует определенный базовый класс. (это определено еще в одной DLL, но об этом я расскажу позже), затем создайте его экземпляр и вызовите в нем определенную функцию.

Public Sub ScanPluginsInDirectory(ByVal Directory As String)

    Dim Plugins As New IO.DirectoryInfo(Directory)
    Dim Files As IO.FileInfo() = Plugins.GetFiles("*.dll")
    Dim CryptType As Type = GetType(CryptPluginBase)
    Dim PluginsData as List(Of LoadedPluginsInfo)

    For Each DllFile As IO.FileInfo In Files
        Try
            Dim thisAsm As Assembly = Assembly.LoadFrom(DllFile.FullName)
            Dim ClassDefs = thisAsm.GetTypes().Where(Function(type) CryptType.IsAssignableFrom(type))

            For Each ClassDef As Type In ClassDefs
                Dim A As Object
                A = ClassDef.Assembly.CreateInstance(ClassDef.Name)
                PluginsData.Add(New LoadedPluginsInfo(A.Plugin(), False))
            Next
        Catch ex As Exception
            Continue For
        End Try
    Next
End Sub

Конкретная проблема, с которой я столкнулся, заключается в том, что я не уверен, что это правильный способ сделать это.Будет ли работать метод, который я пытаюсь реализовать, если можно предположить, что A.Plugin() действительно существует, и любые структуры и классы, упомянутые здесь, не содержат ошибок?Если кому-то понадобится больше кода, чтобы помочь, я могу опубликовать его.

Это было полезно?

Решение

В целом стратегия должна сработать.Вызов Assembly.LoadFrom загрузит целевую сборку в процесс.Отсюда можно выполнять проверку типов и создавать экземпляры этих типов.

Я думаю, что самый простой и надежный способ создать экземпляр — использовать метод Activator.CreateInstance.

For Each def As Type in ClassDefs
  Dim inst = Activator.CreateInstance(def)
  PluginsData.Add(new LoadedPluginsInfo(inst.Plugin(), False))
Next

В зависимости от ваших целей можно было бы также переместить блок Try/Catch в цикл, а не за его пределы.Наличие блока Try/Catch вне цикла означает, что если какой-либо тип в сборке содержит ошибку, вы отбросите все типы из этой сборки.Перемещение его внутрь позволит вам отбросить только те типы, которые не работают должным образом. Однако ваше намерение может заключаться в текущем поведении.

Другие советы

Это должно сработать, я раньше использовал подобные вещи в некоторых проектах.Я специально искал конструктор и вызывал его, но в остальном это была та же идея.

Но, возможно, вы захотите посмотреть МЭФ, который позаботится о множестве вещей для архитектуры плагина (если вы готовы немного подождать релизной версии, на данный момент это все еще CTP).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top