Creating an object dynamically using Reflection and running in a seperate thread

S

Simon Verona

I would normally use code such as :

Dim Customer as new Customer
Dim t as new threading.thread(AddressOf Customer.DisplayCustomer)
Customer.CustomerId=MyCustomerId
t.start

Which would create a new thread to display a customer on the screen for example.

However, I have a problem with circular references in my objects which means that I have to load the customer object using reflection ie :

Dim Customer As Object

Dim dmsobj As New DmsObjects.Functions

Customer = dmsobj.LoadMeByName("DMSCustomer.dll", "DMSCustomer.Customer", Nothing) <--- this is a wrapper round some reflection code to load up the object

Customer.Customer = dms.data("ActivityLog", 5, RowNo)

customer.displaycustomer



This code works.



However, I want to do :

Dim Customer As Object

Dim dmsobj As New DmsObjects.Functions

Customer = dmsobj.LoadMeByName("DMSCustomer.dll", "DMSCustomer.Customer", Nothing)

Customer.Customer = dms.data("ActivityLog", 5, RowNo)

Dim t As New Threading.Thread(AddressOf Customer.DisplayCustomer)

t.Start()



This doesn't compile, due to latebinding, it complains that "Customer.DisplayCustomer" is not a valid method.

How can I acheive this??



Many thanks in advance.



Simon
 
C

CJ Taylor

Activator.CreateInstance


I would normally use code such as :

Dim Customer as new Customer
Dim t as new threading.thread(AddressOf Customer.DisplayCustomer)
Customer.CustomerId=MyCustomerId
t.start

Which would create a new thread to display a customer on the screen for example.

However, I have a problem with circular references in my objects which means that I have to load the customer object using reflection ie :

Dim Customer As Object

Dim dmsobj As New DmsObjects.Functions

Customer = dmsobj.LoadMeByName("DMSCustomer.dll", "DMSCustomer.Customer", Nothing) <--- this is a wrapper round some reflection code to load up the object

Customer.Customer = dms.data("ActivityLog", 5, RowNo)

customer.displaycustomer



This code works.



However, I want to do :

Dim Customer As Object

Dim dmsobj As New DmsObjects.Functions

Customer = dmsobj.LoadMeByName("DMSCustomer.dll", "DMSCustomer.Customer", Nothing)

Customer.Customer = dms.data("ActivityLog", 5, RowNo)

Dim t As New Threading.Thread(AddressOf Customer.DisplayCustomer)

t.Start()



This doesn't compile, due to latebinding, it complains that "Customer.DisplayCustomer" is not a valid method.

How can I acheive this??



Many thanks in advance.



Simon
 
S

Simon Verona

Thanks for the pointer.. Unfortunately, I can't quite work out the syntax for using this.

Is it possible to put together an example of use ? Perhaps using my code as the example????

Thanks in advance.

Simon
Activator.CreateInstance


I would normally use code such as :

Dim Customer as new Customer
Dim t as new threading.thread(AddressOf Customer.DisplayCustomer)
Customer.CustomerId=MyCustomerId
t.start

Which would create a new thread to display a customer on the screen for example.

However, I have a problem with circular references in my objects which means that I have to load the customer object using reflection ie :

Dim Customer As Object

Dim dmsobj As New DmsObjects.Functions

Customer = dmsobj.LoadMeByName("DMSCustomer.dll", "DMSCustomer.Customer", Nothing) <--- this is a wrapper round some reflection code to load up the object

Customer.Customer = dms.data("ActivityLog", 5, RowNo)

customer.displaycustomer



This code works.



However, I want to do :

Dim Customer As Object

Dim dmsobj As New DmsObjects.Functions

Customer = dmsobj.LoadMeByName("DMSCustomer.dll", "DMSCustomer.Customer", Nothing)

Customer.Customer = dms.data("ActivityLog", 5, RowNo)

Dim t As New Threading.Thread(AddressOf Customer.DisplayCustomer)

t.Start()



This doesn't compile, due to latebinding, it complains that "Customer.DisplayCustomer" is not a valid method.

How can I acheive this??



Many thanks in advance.



Simon
 
H

Herfried K. Wagner [MVP]

* "Simon Verona said:
Thanks for the pointer.. Unfortunately, I can't quite work out the syntax for using this.

For example (there are many other ways to use 'CreateInstance'):

\\\
Private Function CreateClassByName( _
ByVal PartialAssemblyName As String, _
ByVal QualifiedClassName As String _
) As Object
Return _
Activator.CreateInstance( _
[Assembly].LoadWithPartialName( _
PartialAssemblyName _
).GetType(QualifiedClassName) _
)
End Function
///

Usage:

\\\
Dim c As Control = _
DirectCast( _
CreateClassByName( _
"System.Windows.Forms", _
"System.Windows.Forms.Button" _
), _
Control _
)
With c
.Location = New Point(10, 10)
.Size = New Size(80, 26)
.Text = "Hello World"
End With
Me.Controls.Add(c)
///
 
S

Simon Verona

I'm getting very confused.

I think the code that you've put in is the code to construct the object in the first place - I have very similar code that does this.

I can't work out how to write the code that is used when creating the thread:

ie in my code:

Dim Customer As Object
Dim dmsobj As New DmsObjects.Functions
Customer = dmsobj.LoadMeByName("DMSCustomer.dll", "DMSCustomer.Customer", Nothing)
Customer.Customer = dms.data("ActivityLog", 5, RowNo)
Dim t As New Threading.Thread(AddressOf Customer.DisplayCustomer)
t.Start()

I need to know what to put in place of the AddressOf Customer.DisplayCustomer when creating the thread. I'm sure that the reflection class allows you to create a delegate pointer to a specific method, but I can't work out how! It's getting very frustrating.

Out of interest, the function dmsobj.LoadMeByName is as follows:

Public Shared Function LoadMeByName(ByVal vstrAssemblyName As String, ByVal vstrClassName As String, ByVal vArgs() As Object) As Object
'************************************************************************************
'dynamically load object from assembly for late binding purpose
' *************************************************************************************
Dim objAssembly As Reflection.Assembly
Dim objtemp As Object
Dim Params() As Object
'MsgBox(Application.StartupPath)
If Dir(Application.StartupPath & "\" & vstrAssemblyName).Equals("") Then
Err.Raise(-1, "LoadMeByName", "assembly could not found, wrong assembly name given ")
Exit Function
End If
objAssembly = objAssembly.LoadFrom(Application.StartupPath & "\" & vstrAssemblyName)
objtemp = objAssembly.CreateInstance(vstrClassName, True, Reflection.BindingFlags.CreateInstance, Nothing, vArgs, Nothing, Nothing)
If objtemp Is Nothing Then
Err.Raise(-1, "LoadMeByName", "assembly could not found, wrong assembly name given ")
Exit Function
End If
' LoadMeByName = objtemp
Return objtemp
End Function

Hopefully, somebody will take pity on me on a Friday!!

Many thanks in advance,
Simon


Herfried K. Wagner said:
* "Simon Verona said:
Thanks for the pointer.. Unfortunately, I can't quite work out the syntax for using this.

For example (there are many other ways to use 'CreateInstance'):

\\\
Private Function CreateClassByName( _
ByVal PartialAssemblyName As String, _
ByVal QualifiedClassName As String _
) As Object
Return _
Activator.CreateInstance( _
[Assembly].LoadWithPartialName( _
PartialAssemblyName _
).GetType(QualifiedClassName) _
)
End Function
///

Usage:

\\\
Dim c As Control = _
DirectCast( _
CreateClassByName( _
"System.Windows.Forms", _
"System.Windows.Forms.Button" _
), _
Control _
)
With c
.Location = New Point(10, 10)
.Size = New Size(80, 26)
.Text = "Hello World"
End With
Me.Controls.Add(c)
///
 
C

CJ Taylor

Ahh

You can create a delegate, however, I wouldn't free thread it using AddressOf.

What does your threading code look like? Do you have it yet?

i.e.

Dim myThread as new System.Threading.Thread(AddressOf myFunctionCall)

Now, you can't pass parameters to Threading start calls...

So,if your myFunctionCall is in another class, you have to instantiate it and set the proper "parameter" values... i.e using properties and then the myFunctionCall (which actually starts the execution on a new thread)

such that

Dim myObject as New myObject

myObject.Parameter1 = [a paramter]
myObject.Parameter2 = [another parameter]

Dim myThread as System.Threading.Thread

myThread = new System.Threading.Thread (AddressOf myObject.MyThreadStarterFunction)

myThread.Start()

' do some stuff - new thread executes its stuff, you do whatever else you want... Join
'just shuts the thread down (read about thread states).

myThread.join()
I'm getting very confused.

I think the code that you've put in is the code to construct the object in the first place - I have very similar code that does this.

I can't work out how to write the code that is used when creating the thread:

ie in my code:

Dim Customer As Object
Dim dmsobj As New DmsObjects.Functions
Customer = dmsobj.LoadMeByName("DMSCustomer.dll", "DMSCustomer.Customer", Nothing)
Customer.Customer = dms.data("ActivityLog", 5, RowNo)
Dim t As New Threading.Thread(AddressOf Customer.DisplayCustomer)
t.Start()

I need to know what to put in place of the AddressOf Customer.DisplayCustomer when creating the thread. I'm sure that the reflection class allows you to create a delegate pointer to a specific method, but I can't work out how! It's getting very frustrating.

Out of interest, the function dmsobj.LoadMeByName is as follows:

Public Shared Function LoadMeByName(ByVal vstrAssemblyName As String, ByVal vstrClassName As String, ByVal vArgs() As Object) As Object
'************************************************************************************
'dynamically load object from assembly for late binding purpose
' *************************************************************************************
Dim objAssembly As Reflection.Assembly
Dim objtemp As Object
Dim Params() As Object
'MsgBox(Application.StartupPath)
If Dir(Application.StartupPath & "\" & vstrAssemblyName).Equals("") Then
Err.Raise(-1, "LoadMeByName", "assembly could not found, wrong assembly name given ")
Exit Function
End If
objAssembly = objAssembly.LoadFrom(Application.StartupPath & "\" & vstrAssemblyName)
objtemp = objAssembly.CreateInstance(vstrClassName, True, Reflection.BindingFlags.CreateInstance, Nothing, vArgs, Nothing, Nothing)
If objtemp Is Nothing Then
Err.Raise(-1, "LoadMeByName", "assembly could not found, wrong assembly name given ")
Exit Function
End If
' LoadMeByName = objtemp
Return objtemp
End Function

Hopefully, somebody will take pity on me on a Friday!!

Many thanks in advance,
Simon


Herfried K. Wagner said:
* "Simon Verona said:
Thanks for the pointer.. Unfortunately, I can't quite work out the syntax for using this.

For example (there are many other ways to use 'CreateInstance'):

\\\
Private Function CreateClassByName( _
ByVal PartialAssemblyName As String, _
ByVal QualifiedClassName As String _
) As Object
Return _
Activator.CreateInstance( _
[Assembly].LoadWithPartialName( _
PartialAssemblyName _
).GetType(QualifiedClassName) _
)
End Function
///

Usage:

\\\
Dim c As Control = _
DirectCast( _
CreateClassByName( _
"System.Windows.Forms", _
"System.Windows.Forms.Button" _
), _
Control _
)
With c
.Location = New Point(10, 10)
.Size = New Size(80, 26)
.Text = "Hello World"
End With
Me.Controls.Add(c)
///
 
C

CJ Taylor

Ahhh

my bad... sorry had to re read it again...

help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.1033

has instructions on how to create a delegate... I hope this helps.


I'm getting very confused.

I think the code that you've put in is the code to construct the object in the first place - I have very similar code that does this.

I can't work out how to write the code that is used when creating the thread:

ie in my code:

Dim Customer As Object
Dim dmsobj As New DmsObjects.Functions
Customer = dmsobj.LoadMeByName("DMSCustomer.dll", "DMSCustomer.Customer", Nothing)
Customer.Customer = dms.data("ActivityLog", 5, RowNo)
Dim t As New Threading.Thread(AddressOf Customer.DisplayCustomer)
t.Start()

I need to know what to put in place of the AddressOf Customer.DisplayCustomer when creating the thread. I'm sure that the reflection class allows you to create a delegate pointer to a specific method, but I can't work out how! It's getting very frustrating.

Out of interest, the function dmsobj.LoadMeByName is as follows:

Public Shared Function LoadMeByName(ByVal vstrAssemblyName As String, ByVal vstrClassName As String, ByVal vArgs() As Object) As Object
'************************************************************************************
'dynamically load object from assembly for late binding purpose
' *************************************************************************************
Dim objAssembly As Reflection.Assembly
Dim objtemp As Object
Dim Params() As Object
'MsgBox(Application.StartupPath)
If Dir(Application.StartupPath & "\" & vstrAssemblyName).Equals("") Then
Err.Raise(-1, "LoadMeByName", "assembly could not found, wrong assembly name given ")
Exit Function
End If
objAssembly = objAssembly.LoadFrom(Application.StartupPath & "\" & vstrAssemblyName)
objtemp = objAssembly.CreateInstance(vstrClassName, True, Reflection.BindingFlags.CreateInstance, Nothing, vArgs, Nothing, Nothing)
If objtemp Is Nothing Then
Err.Raise(-1, "LoadMeByName", "assembly could not found, wrong assembly name given ")
Exit Function
End If
' LoadMeByName = objtemp
Return objtemp
End Function

Hopefully, somebody will take pity on me on a Friday!!

Many thanks in advance,
Simon


Herfried K. Wagner said:
* "Simon Verona said:
Thanks for the pointer.. Unfortunately, I can't quite work out the syntax for using this.

For example (there are many other ways to use 'CreateInstance'):

\\\
Private Function CreateClassByName( _
ByVal PartialAssemblyName As String, _
ByVal QualifiedClassName As String _
) As Object
Return _
Activator.CreateInstance( _
[Assembly].LoadWithPartialName( _
PartialAssemblyName _
).GetType(QualifiedClassName) _
)
End Function
///

Usage:

\\\
Dim c As Control = _
DirectCast( _
CreateClassByName( _
"System.Windows.Forms", _
"System.Windows.Forms.Button" _
), _
Control _
)
With c
.Location = New Point(10, 10)
.Size = New Size(80, 26)
.Text = "Hello World"
End With
Me.Controls.Add(c)
///
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top