I've loaded an external DLL into your project like this
Dim assembly As Assembly = Assembly.LoadFile(libraryPath & "filename.dll")
Dim type As Type = assembly.[GetType]("NameSpace.ClassName")
// i'm loading as a form here but can be any control
Dim frm As Form = TryCast(Activator.CreateInstance(type), Form)
What are the best practices if you're loading a class or a control inside the loaded form (above) that resides also inside the same assembly ?
for instance: Lets say you loaded an assembly consisted of several forms. You load the assembly and create the instance of one of the forms, frm. But inside the loaded form, frm is also loaded another 2nd form, frm2 also belonging to the same assembly. How do i instantiate the second form? do i need to load the assembly again ?
Edit: The assembly is a. Net 4.8 class library, that holds several forms, modules and abstract classes. Is being loaded into a winforms also in. Net 4.8. This question applies to both VB and C#. But on my case I'm coding on VB.
You can load your external assembly in the StartUp event of your application.
Open Project->Properties->Application
and click the View Application Events
button.
This will open or generate the ApplicationEvents.vb
class file (you'll see, in some comments, the events that are more often handled using the My.Application
class).
Here, we add a handler to the StartUp event: this event is raised before the application startup form is loaded and shown.
We define a Public
class object that references the external Library containing the Form resources.
This public class object is visible by all other classes in the Application, through the My.Application
reference.
This class exposes a Public Method, LoadForm()
, that allows to load an external Form by Name.
Imports System.IO
Imports System.Reflection
Imports Microsoft.VisualBasic.ApplicationServices
Namespace My
Partial Friend Class MyApplication
Public FormResources As ResourceBag
Protected Overrides Function OnStartup(e As StartupEventArgs) As Boolean
FormResources = New ResourceBag()
Return MyBase.OnStartup(e)
End Function
Friend Class ResourceBag
Private Shared libraryPath As String = "[Your Library path]"
Private Shared asm As Assembly = Nothing
Public Sub New()
Dim resoursePath As String = Path.Combine(libraryPath, "[Your .dll Name].dll")
If File.Exists(resoursePath) Then
asm = Assembly.LoadFile(resoursePath)
End If
End Sub
Public Function LoadForm(formName As String) As Form
If asm Is Nothing Then Throw New BadImageFormatException("Resource Library not loaded")
Return TryCast(Activator.CreateInstance(asm.GetType($"[Library Namespace].{formName}")), Form)
End Function
End Class
End Class
End Namespace
Now, let's assume you have a Form named Form1
in your external library.
You can make Form1
load another Form from the external Library or a Form from your assembly using either the LoadForm()
method (it creates an instance of a Form in the external library) or the New
keyword to create an instance of local Form class.
► If Form1 of the external Library already shows another Form from the same Library, e.g., clicking a Button, there's nothing we have to do: the external new Form is generated as usual.
In the sample code that follows, we are instead adding two Buttons to the external Form1 class:
Form2
, from the external library, using the public method previously defined: Using extForm1 As Form = My.Application.FormResources.LoadForm("Form1")
Form2
, which is instead part of the current Application, using the New keyword: Dim f2 As New Form2()
► The external Form1 instance is created with a Using statement because the ShowDialog()
method is used to show the new Form: this requires that we dispose of the Form when it closes, otherwise it cannot dispose of itself when show like this.
If you use Show()
or Show(Me)
, the Using
block needs to be removed otherwise the Form will be closed instantly. The Form and its Controls/components will be disposed of when it closes anyway.
► The Form2
Form class of your Application cannot have Controls added from the Application Settings (these Control will be disposed of and generate an exception if the Form is shown a second time)
Using extForm1 As Form = My.Application.FormResources.LoadForm("Form1")
If extForm1 IsNot Nothing Then
Dim btnExt = New Button() With {
.Location = New Point(20, 50),
.Size = New Size(100, 30),
.Text = "Lib Form2"
}
AddHandler btnExt.Click,
Sub()
Dim f2ext = My.Application.FormResources.LoadForm("Form2")
f2ext.Show()
End Sub
Dim btn = New Button() With {
.Location = New Point(140, 50),
.Size = New Size(100, 30),
.Text = "My Form2"
}
AddHandler btn.Click,
Sub()
Dim f2 As New Form2()
f2.Show()
End Sub
extForm1.Controls.AddRange({btnExt, btn})
btnExt.BringToFront()
btn.BringToFront()
extForm1.StartPosition = FormStartPosition.CenterParent
extForm1.ShowDialog(Me)
End If
End Using