Originariamente inviato da S0nic
si ci avevo pensato...però
io ho optato per i plugin in modo da non dover più modificare il programma principale
però se passo su "Start" un controllo anche come optional
in alcuni casi (se non erro) mi troverò costretto sempre a modificare il programma principale
quando dovrò specificarlo...
certo, ma non volevo dirti di non usare i plugin, volevo solo consigliarti un modo per evitare che modificando il programma principale, poi ti ritrovi a dover modificare anche tutti plugin.
nel tuo scenario, stai ponendo nella dll i nomi dei controlli, e richiami quest'ultimi con i nomi all'interno del plugin compilato, oltretutto, lo stai facendo chiamando il nome del controllo direttamente tra i controlli del form, (se non ricordo male) in caso un controllo sia dentro un'altro controllo (es. dentro un tabcontrol) che sta nella form, richiamato direttamente tra i controlli diretti del form, ti genererebbe un errore in runtime perchè dovrestri chiamare prima il tabcontrol (che è quello che contiene il controllo che cerchi di chiamare), ecco perchè io ho usato il metodo .Find("nomeControllo",true) nell'esempio di prima per cercare il groupBox (true indica di cercare all'interno dei controlli del form).
quindi ti basta spostare un controllo nel programma principale e scalarlo magari di livello (metterlo dentro un'altro controllo) o cambiare nome ad un controllo ecc. che ti ritroveresti a dover riscrivere anche i plugin.
se invece tipicizzi, in caso di modifica, il tipo sarà sempre quello che determini tu nei membri che ereditano (nel form) dal tipo impostato nella dll comune che carica anche il plugin.
ti faccio un esempio riportato alla tua situazione :
DLL comune sia al plugin sia alla form :
codice:
Imports System.Windows.Forms
Public Interface IExtender
Sub Start(ByVal PropertyForm As IPropertyForm)
End Interface
Public Interface IPropertyForm
Property Control As Control
Property GroupBox1 As GroupBox
End Interface
qui ho voluto inserire 2 interfacce, la prima (IExtender) serve a chiamare dal form il metodo che crea un controllo e lo inserisce nel form stesso (anche se continuo a dire che sarebbe meglio pensarla in maniera differente
) ovvero Start, questo accetta un parametro di tipo IPropertyForm (la seconda interfaccia) che determina in questo caso in quali controlli verrà inserito il controllo creato. ho inserito 2 proprietà, la prima, GroupBox1, si riferisce direttamente ad un tipo GroupBox, che potrai tranquillamente implementare ed eventualmente sostituire dalla form SENZA dover riscrivere il plugin, il secondo, Control, l'ho inserito come prova di concetto, infatti se tu un domani dovessi decidere che i controlli dei tuoi plugin debbano andare in un TabControl (ad esempio), sarà sufficiente cambiare l'implementazione di tale proprietà del form SENZA modificare il plugin (ho usato la base Control appositamente per fare in modo che si possa usare qualsiasi controllo)
ora ti mostro il plugin vero e proprio :
codice:
Imports TestDLLComune
Imports System.Windows.Forms
Imports System.Drawing
Public Class Plugin1
Implements IExtender
Sub Start(ByVal PropertyForm As IPropertyForm) Implements IExtender.Start
Dim Button1 As New Button
Button1.Location = New Point(87, 100)
Button1.Size = New Size(75, 21)
Button1.Text = "Button1"
Button1.Visible = True
PropertyForm.GroupBox1.Controls.Add(Button1)
End Sub
End Class
Public Class Plugin2
Implements IExtender
Sub Start(ByVal PropertyForm As IPropertyForm) Implements IExtender.Start
Dim Button1 As New Button
Button1.Location = New Point(87, 100)
Button1.Size = New Size(75, 21)
Button1.Text = "Button1"
Button1.Visible = True
PropertyForm.Control.Controls.Add(Button1)
End Sub
End Class
come potrai notare, ci sono 2 plugin in realtà in questa stessa dll, questo solo per mostrarti come utilizzando la proprietà control (nella Plugin2) io ottengo lo stesso risultato della prima, ma inserendo il button prodotto in un controllo scelto dentro l'implementazione di IPropertyForm da parte del form, nel caso specifico ho voluto usare sempre un groupBox (groupBox2), ma avrei potuto mettere qualsiasi controllo(TabControl, Panel ecc.).
ora la form :
codice:
Imports TestDLLComune
Imports System.Reflection
Imports System.IO
Public Class Form1
Implements IPropertyForm
Public Property GroupBox1 As GroupBox Implements IPropertyForm.GroupBox1
Get
Return Me.GroupBoxTest
End Get
Set(ByVal value As GroupBox)
Me.GroupBoxTest = value
End Set
End Property
Public Property Control As Control Implements IPropertyForm.Control
Get
Return Me.GroupBox2
End Get
Set(ByVal value As Control)
Me.GroupBox2 = value
End Set
End Property
Sub New()
InitializeComponent()
Dim asm As Assembly
For Each pluginDLL As String In Directory.EnumerateFiles(Application.StartupPath, "*.dll")
asm = Assembly.LoadFile(pluginDLL)
Dim typeList As Type() = asm.GetTypes().Where(Function(p) p.GetInterfaces().Contains(GetType(IExtender))).ToArray()
For Each Type As Type In typeList
Dim pl As IExtender = Activator.CreateInstance(Type)
pl.Start(Me)
Next
Next
End Sub
End Class
qui ho usato la reflection per creare un istanza di ogni classe trovata in ogni assembly che implementi l'interfaccia IExtender che risiede nella stessa cartelle dell'eseguibile. per ogni istanza creata viene chiamato il metodo start che crea il controllo e lo aggiunge al form passato come parametro, ovviamente il controllo creato viene inserito nel controllo stabilito dall'implementazione della IPropertyForm implentata dalla form.
fammi sapere se ti è tutto chiaro.