.net динамическая загрузка - PullRequest
0 голосов
/ 06 января 2011

Я видел некоторые другие отзывы об этом, и они говорили об интерфейсах, но я почти уверен, что вы можете сделать это с классами и базовыми классами, но я не могу это сработать.

Public Class Behavior
Private _name As String
Public ReadOnly Property Name As String
    Get
        Return _name
    End Get
End Property

Public Property EditorUpdate As Boolean

Public Sub New(ByVal name As String)
    _name = name
    EditorUpdate = False
End Sub

Public Overridable Sub Update()

End Sub

' runs right away in editor mode. also runs when in stand alone game mode right away
Public Overridable Sub Start()

End Sub

' runs after game mode is done and right before back in editor mode
Public Overridable Sub Finish()

End Sub

' runs right when put into game mode
Public Overridable Sub Initialize()

End Sub

' runs when the game is complete in stand alone mode to clean up
Public Overridable Sub Destroy()

End Sub

Конечный класс

Public Class CharacterController
Inherits Behavior.Behavior

Public Sub New()
    MyBase.New("Character Controller")

End Sub

Public Overrides Sub Update()
    ' TODO: call UpdateController()
    ' THINK: how can UpdateController() get the controller entity it's attached to?
    ' Behaviors need a way to get the entity they are attached to. Have that set when it's assigned in the ctor?
End Sub

Конечный класс

Dim plugins() As String
    Dim asm As Assembly


    plugins = Directory.GetFileSystemEntries(Path.Combine(Application.StartupPath, "Plugins"), "*.dll")

    For i As Integer = 0 To plugins.Length - 1
        asm = Assembly.LoadFrom(plugins(i))

        For Each t As Type In asm.GetTypes
            If t.IsPublic Then
                If t.BaseType.Name = "Behavior" Then
                    behaviorTypes.Add(t.Name, t)


                    Dim b As Behavior.Behavior
                    b = CType(Activator.CreateInstance(t), Behavior.Behavior)
                    'Dim o As Object = Activator.CreateInstance(t)


                End If
            End If
        Next
    Next

Когда он пытается преобразовать все, что Activator.CreateInstance (t) возвращает в базовый класс типа Поведение, я получаю недопустимое исключение приведения. Этот тип должен иметь CharacterController, который определен как дочерний элемент Behavior, так почему бы не позволить мне разыграть это? Я сделал что-то подобное раньше, но я не могу найти свой код. Чего мне не хватает?

Ответы [ 2 ]

1 голос
/ 06 января 2011

Это может быть не ответ на ваш вопрос (это также может разрешить ваше исключение - кто знает), но это то, на что нужно указать. Эти строки:

If t.IsPublic Then
    If t.BaseType.Name = "Behavior" Then

Должно быть действительно заменено на одно условие, подобное этому:

If t.IsPublic AndAlso (Not t.IsAbstract) AndAlso _
    GetType(Behavior.Behavior).IsAssignableFrom(t) Then

В противном случае, если кто-то определит случайный тип под названием «Поведение» в своей собственной сборке и выведет его из другого типа, ваш код будет думать, что это плагин. Кроме того, если кто-то получит ваш тип Behavior, а затем получит этот тип (два уровня наследования), этот код будет неправильно пропущен по этому типу. Использование метода IsAssignableFrom - это быстрый и простой способ убедиться, что один тип действительно является производным от определенного типа, который вы хотите (вместо любого типа с одинаковым именем), даже если между вашими типами в наследственное дерево. Дополнительная проверка против t.IsAbstract также гарантирует, что вы не будете пытаться создать экземпляр абстрактного подтипа вашего базового типа плагина.

0 голосов
/ 25 марта 2011

Это работает для меня:

             Dim ctor As Reflection.ConstructorInfo = _
                t.GetConstructor(New System.Type() {})
             Dim o As Object = ctor.Invoke(New Object() {})
             Dim plugin As Plugin = TryCast(o, Plugin)

(Если я найду t , я вызову конструктор без параметров.)

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

...