7
votes

Visual Basic: créer de manière dynamique des objets à l'aide d'une chaîne comme nom

Y a-t-il un moyen de créer de manière dynamique un objet à l'aide d'une chaîne en tant que nom de classe?

Je suis venu VB depuis plusieurs années maintenant, mais pour résoudre un problème dans une autre langue, je suis obligé de développer un problème dans une autre langue, je suis obligé de développer une envelopper dans celui-ci. J'ai une méthode d'usine pour créer et renvoyer de manière dynamique un objet d'un type basé sur l'entrée d'ailleurs. L'entrée fournie est censée être le nom de la classe à partir de laquelle créer un objet de. La syntaxe normale signifie que toute la classe doit être explicitement expliquée. Pour ce faire, il pourrait littéralement être des centaines de personnes ou des cas pour gérer tous les choix de classe / objet disponibles dans les libs référencés: p> xxx pré>

J'espère que j'espère Au lieu de réduire tout ce cas de manutention à une seule ligne: c.-à-d. ... p> xxx pré>

en PHP, ceci est manipulé comme ... p>

my_type_name = "System.Windows.Forms.Button"
asmb_name = "System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
button1 = Reflection.Assembly.Load(asmb_name).CreateInstance(my_type_name)


0 commentaires

4 Réponses :


0
votes

Vérifiez la méthode Activator.createInstance (type).

Si votre entrée est le nom d'une classe, vous devriez être capable, faites ceci: P>

Dim obj As Object = Activator.CreateInstance(GetType("Name_Of_Your_Class")) 


4 commentaires

Je crois que GetType () s'attend à un type, alors jetez une erreur. Type.getType ("system.windows.forms.button") renvoie null.


Mon VB est un peu rouillé mais cela devrait certainement fonctionner. Je ne sais pas pourquoi vous obtenez NULL, mais je ne suis pas la documentation GetType pour passer une chaîne dans: msdn.microsoft.com/en-us/library/w3f99sx1.aspx


L'exemple est à peu près ce que j'utilisais à l'origine, sauf avec la méthode de type GetType à la place. Je crois que cela me laisse coincer une façon de chasser le type System.Windows.Forms.button.


Pour clarifier, Type.getType nécessite le nom de type qualifié de montage, alors quelque chose comme cela fonctionnerait: type.getype (gettype (bouton) .assemblyqualifiedName) ou type.getType ("Système. Windows.forms.button, system.windows.forms, version = 4.0.0.0, culture = neutre, PublickeyToken = B77A5C565934E589 ")



3
votes

Je suis à peu près sûr que l'activateur est utilisé pour les télécommandes. Ce que vous voulez faire, c'est utiliser la réflexion pour obtenir la constance et l'invoquer ici est un exemple http: // www.eggheadcafe.com/articles/20050717.asp

Edit: J'étais mal guidé sur l'activateur jusqu'à ce que Jwsample me corrigeait.

Je pense que votre problème est que votre L'assemblage est celui qui getTyPe utilise pour essayer de trouver un bouton. Vous devez l'appeler de la bonne assemblée.

Ceci devrait le faire xxx


3 commentaires

WOW, vous avez changé tout le contenu de votre message avec cet édition et maintenant mon commentaire précédent ressemble aux ravences d'un homme fou.


Désolé pour ça. Je le remette.


Bonnes pistes. Déteste Nitpick, mais avec Activator.CreateInstance, car il renvoie une poignée, cela nécessite que vous appeliez la méthode de la poignée de déclenchement dessus pour terminer la création de l'objet. En outre, la méthode Assembly.LoadWithPartialName est obsolète selon MSDN .microsoft.com / fr-US / Bibliothèque / ... . Dommage, parce que je pourrais vraiment l'utiliser au lieu de jouer autour d'essayer de trouver des versions, des cultures et des clés.



10
votes

Cela fera probablement ce que vous voulez / testé travailler; Basculez le type de type en haut pour voir.

Imports System.Reflection

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    '            Dim fullyQualifiedClassName as String = "System.Windows.Forms.TextBox"
    Dim fullyQualifiedClassName As String = "System.Windows.Forms.Button"
    Dim o = fetchInstance(fullyQualifiedClassName)
    ' sometime later where you can narrow down the type or interface...
    Dim b = CType(o, Control)
    b.Text = "test"
    b.Top = 10
    b.Left = 10
    Controls.Add(b)
End Sub

Private Function fetchInstance(ByVal fullyQualifiedClassName As String) As Object
    Dim nspc As String = fullyQualifiedClassName.Substring(0, fullyQualifiedClassName.LastIndexOf("."c))
    Dim o As Object = Nothing
    Try
        For Each ay In Assembly.GetExecutingAssembly().GetReferencedAssemblies()
            If (ay.Name = nspc) Then
                o = Assembly.Load(ay).CreateInstance(fullyQualifiedClassName)
                Exit For
            End If
        Next
    Catch
    End Try
    Return o
End Function


1 commentaires

Agréable. form1_load () sera effectivement traité par une autre langue pour moi via com. La ligne o = assemblage.load (AY) .CreateInstance (entièrementqualifiedClassName) devrait le faire.



0
votes

Voici un moyen vraiment facile que j'ai trouvé lors de la fouille via Internet:

dynamicControl = Activator.CreateInstance(Type.GetType("MYASSEMBLYNAME." + controlNameString))


0 commentaires