|
Hi there,
I have no idea how to approach this, so maybe someone can give me a hint where to start with this ...
I have some .dll files the user can select from at run-time ( say with a OpenFileDialog object ). Now I want to open those files, read the class information stored within and create an object from it. As there might ( or most likely will ) be more than one class inside the .dll file, I want to create an object only for that one class ( and there is exactly one such class per such .dll file ) that implements a specific interface - known to me via a class library.
I need this to dynamically load plugins into my program that I do not know of at compile time. Handling the objects once they've been created is easy but how in the world do I get that kind of information out of the .dll file ? Is there something preimplemented for this purpose ? Maybe something like a class parser for .dll files ? I have no experience with this kind of run-time plugin loading ...
Thanks in advance, Amnu
|
| Amnu Tuesday, September 02, 2008 3:46 PM |
Hi !
Use the Assembly.CreateInstance method. Pass the name of the class you want to instantiate as a parameter.
If you want to check for it upfront, there are methods in the Assembly class for this also.
- terje
|
| OsirisTerje Tuesday, September 02, 2008 6:17 PM |
I beleive you're looking to add references during runtime. Here is another thread that answers that. http://bytes.com/forum/thread48951.html
Once the .dll is referenced,you can then create a new instance...
A.D.T. |
| BeforeAndAfter1974 Tuesday, September 02, 2008 7:32 PM |
This is the same thing really.
You don't really "add references" at runtime. All options here use reflection one way or another.
Either code:
Assembly someDll = Assembly.Load("someDLL.dll"); // Or use LoadFrom, whatever suits you
A) MyClass my = (MyClass)someDll.CreateInstance("MyClass");
or code using types, which is really the same stuff
B) MyClass my = (MyClass)Activator.CreateInstance(someDll.GetType("MyClass"));
The first one A) uses the system activator internally, but gives you a little less code to write.
The CreateInstance method uses Type.InvokeMember internally, so if you need that level, see http://msdn.microsoft.com/en-us/library/k3a58006(VS.71).aspx
- terje |
| OsirisTerje Tuesday, September 02, 2008 8:07 PM |
If the class name differs between the assemblies and the only thing in common is that all are implementing the same interface, you can use the Assembly.GetTypes to get all the types declared in that assembly, then iterate through them to find which of these types implements your interface. Some thing like this (this is probably not the most efficient way to do this but it works...):
Assembly asm = Assembly.LoadFrom("ClassLibrary2.dll");Type[] tArr = asm.GetTypes();Type type= null;foreach (Type t in tArr){
if (typeof(IMyInterface).IsAssignableFrom(t))
{
type = t;
break;
}
}if (type != null){
MessageBox.Show("Found it! " + type.Name);
} now, you can use Activator.CreateInstance with the type you found. Guys, if there's a more efficient way to get the type from an assembly that implements a certain Interface - I will be more than happy to learn. hth, Lior.
|
| Lior Salem Wednesday, September 03, 2008 8:25 AM |
Hi !
Use the Assembly.CreateInstance method. Pass the name of the class you want to instantiate as a parameter.
If you want to check for it upfront, there are methods in the Assembly class for this also.
- terje
|
| OsirisTerje Tuesday, September 02, 2008 6:17 PM |
I beleive you're looking to add references during runtime. Here is another thread that answers that. http://bytes.com/forum/thread48951.html
Once the .dll is referenced,you can then create a new instance...
A.D.T. |
| BeforeAndAfter1974 Tuesday, September 02, 2008 7:32 PM |
This is the same thing really.
You don't really "add references" at runtime. All options here use reflection one way or another.
Either code:
Assembly someDll = Assembly.Load("someDLL.dll"); // Or use LoadFrom, whatever suits you
A) MyClass my = (MyClass)someDll.CreateInstance("MyClass");
or code using types, which is really the same stuff
B) MyClass my = (MyClass)Activator.CreateInstance(someDll.GetType("MyClass"));
The first one A) uses the system activator internally, but gives you a little less code to write.
The CreateInstance method uses Type.InvokeMember internally, so if you need that level, see http://msdn.microsoft.com/en-us/library/k3a58006(VS.71).aspx
- terje |
| OsirisTerje Tuesday, September 02, 2008 8:07 PM |
If the class name differs between the assemblies and the only thing in common is that all are implementing the same interface, you can use the Assembly.GetTypes to get all the types declared in that assembly, then iterate through them to find which of these types implements your interface. Some thing like this (this is probably not the most efficient way to do this but it works...):
Assembly asm = Assembly.LoadFrom("ClassLibrary2.dll");Type[] tArr = asm.GetTypes();Type type= null;foreach (Type t in tArr){
if (typeof(IMyInterface).IsAssignableFrom(t))
{
type = t;
break;
}
}if (type != null){
MessageBox.Show("Found it! " + type.Name);
} now, you can use Activator.CreateInstance with the type you found. Guys, if there's a more efficient way to get the type from an assembly that implements a certain Interface - I will be more than happy to learn. hth, Lior.
|
| Lior Salem Wednesday, September 03, 2008 8:25 AM |
To all of you, thank you very much. You exactly hit the point. I will try to get started on this matter asap and incorporate your solutions. Your help is appreciated :-)
Amnu
|
| Amnu Thursday, September 04, 2008 8:08 AM |