Reflection: CreateInstance(Type) of class that supports known interface - Get actual interface refer

C

Chris Morse

Hi,

I'm trying to figure out how to dynamically load an assembly and get
an IClientPlugin interface to a class. I can get an "Object"
reference to it after doing an "Activator.CreateInstance" call, but is
there any way to get an IClientPlugin reference to it?

Trying to do a "CType(obj, IClientPlugin)" throws an exception.

Here's the code that loads the assembly and calls a method called
"GetPluginName" that takes no parameters and returns a string:

//////////////////// BEGIN CODE /////////////////////////////

Dim szPluginPath As String

Dim objPluginAssembly As System.Reflection.Assembly
Dim objIClientPlugin As IClientPlugin
Dim obj As Object
Dim objResult As Object
Dim szError As String
Dim T As Type
Dim T2 As Type

szPluginPath = "C:\PLUGINS\\ANET_SystemNews.dll"
objPluginAssembly = System.Reflection.Assembly.LoadFile(szPluginPath)

For Each T In objPluginAssembly.GetTypes()

If T.IsClass() = True Then
'Class implements IClientPlugin interface?
If Not IsNothing(T.GetInterface("IClientPlugin")) Then

'YES, so create an instance of this class
obj = Activator.CreateInstance(T)

' **** objPlugin = CType(obj, IClientPlugin)

'Invoke IClientPlugin.GetPluginName()
objResult = T.InvokeMember("GetPluginName", _
Reflection.BindingFlags.Default Or _
Reflection.BindingFlags.InvokeMethod, _
Nothing, _
obj, _
Nothing)

Debug.WriteLine("Result: {0}", objResult)

End If
End If
Next

//////////////////// END CODE /////////////////////////////

I've commented out the line that causes an error, the CType(obj,
IClientPlugin) call. Here is how the client is implemented:

Public Class AppleNET_BBS_PLUGIN

Implements IClientPlugin

... IClientPlugin functions defined ...

End Class

Is there any way I can get an "IClientPlugin" reference to the
instantiated class? It would make it a lot easier to call methods:

Dim objIClientPlugin As IClientPlugin

.. create class through reflection

objIClientPlugin = ????(obj)

Thanks for any help you can offer!

// CHRIS
 
R

Rob Teixeira [MVP]

What exception where you getting?

-Rob Teixeira [MVP]


I've commented out the line that causes an error, the CType(obj,
IClientPlugin) call. Here is how the client is implemented:
Is there any way I can get an "IClientPlugin" reference to the
instantiated class?

You should be able to cast to the interface type. Please post exception
message.
 
C

Chris Morse

What exception where you getting?

-Rob Teixeira [MVP]

obj = Activator.CreateInstance(T)
Debug.WriteLine(obj.GetType().ToString())

'THIS LINE FAILS:
objPlugin = CType(obj, IClientPlugin)

It throws an "InvalidCastException" with the message
"Specified cast is not valid." But obj is an instance of my class
called "AppleNET_BBS_PLUGIN" which implements IClientPlugin.

obj.GetType().ToString() returns "ANET_SystemNews.AppleNET_BBS_PLUGIN"

Which is the right class and everything:

Public Class AppleNET_BBS_PLUGIN

Implements IClientPlugin

.. functions defined here

End Class


Any ideas? I think I'll create a new set of projects to try and work
this out.. If it doesn't work, maybe someone can take a look at it (?)

Thanks,
// CHRIS
 
C

Chris Morse

What exception where you getting?

-Rob Teixeira [MVP]

Say.. I'm wondering if it matters that the IClientPlugin interface I
am trying to use is simply defined in an "Interfaces.vb" file that
both projects use. Besides the "name" of the interface, how can .NET
know that they are really the same interface? Unless it does a
complete type comparison.. Not sure about that..

Is there anything special to do when trying to share interface
definitions across 2 projects?

Thanks,
// CHRIS
 
M

Mattias Sjögren

Say.. I'm wondering if it matters that the IClientPlugin interface I
am trying to use is simply defined in an "Interfaces.vb" file that
both projects use. Besides the "name" of the interface, how can .NET
know that they are really the same interface? Unless it does a
complete type comparison.. Not sure about that..

Yes it matters a lot. A type's identity is the combination of the
assembly it's in and the full type name. So IClientPlugin in assemblyA
is not the same as IClientPlugin in assemblyB.

Is there anything special to do when trying to share interface
definitions across 2 projects?

Put it in a separate assembly that you reference from both projects.



Mattias
 
H

Herfried K. Wagner [MVP]

C

Chris Morse

Yes it matters a lot. A type's identity is the combination of the
assembly it's in and the full type name. So IClientPlugin in assemblyA
is not the same as IClientPlugin in assemblyB.



Put it in a separate assembly that you reference from both projects.



Mattias

Thanks for the help everyone!

Creating a new "Class Library" project, putting the interfaces I want
in there, and then referencing them from each project works great.

Cheers!
// CHRIS
 
J

Jay B. Harlow [MVP - Outlook]

Chris,
Thanks for the help everyone!

Creating a new "Class Library" project, putting the interfaces I want
in there, and then referencing them from each project works great.
I find its better to reference the project (as it sounds like you did) in
the solution rather then attempting to reference the compiled DLL.

As invariable the compiled DLL is created in the incorrect order and the
AssemblyVersion attribute does not match, causing the "same" problem.

Remember the assembly version is part of the assembly name used to match the
type, allowing for side by side of newer versions of the assemblies...

For details on the "Fully Qualified Type Names" see:

http://msdn.microsoft.com/library/d...ml/cpconSpecifyingFullyQualifiedTypeNames.asp

There was an MSDN Magazine article also, but I'm not finding it just now.

Hope this helps
Jay
 
C

Chris Morse

I find its better to reference the project (as it sounds like you did) in
the solution rather then attempting to reference the compiled DLL.

As invariable the compiled DLL is created in the incorrect order and the
AssemblyVersion attribute does not match, causing the "same" problem.

I'm not sure how to do this. When I click the "References" in the
solution explorer and select "Add Reference" and then selected the
"Projects" tab in the dialog, I can only reference actual DLL files.

So I am just referencing the DLL file in the project's obj\Release
folder. Is there a way to reference the project itself or something?

thanks,
// CHRIS
 
H

Herfried K. Wagner [MVP]

* Chris Morse said:
So I am just referencing the DLL file in the project's obj\Release
folder. Is there a way to reference the project itself or something?

Have a look at the "Project dependencies..." menu item in the project's
context menu.
 

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