Click here to Skip to main content
15,894,825 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I searched the site and found several articles of how to execute methods inside a dynamically loaded DLL using InvokeMember method.

But my question is:

Is there a way to dynamically load a managed/C# DLL file, instanciate an object of the a class within the DLL and call the object's methods the normal way?


Here is an example of what I am looking for:


In DLL file (that is to be loaded dynamically):
C#
public string DoGreeting() { return "Hello World"; }


In Application or ASP.NET Web Site:

C#
Assembly asm = Assembly.LoadFrom(strAbsolutePathToDllFile);
... myObject = DoSomeMagicUsingTheAssemblyToConvertObjectToCorrectType(asm);


// Output the result using application:
MessageBox.Show(myObject.DoGreeting());

// or

// Output the result using ASP.NET:
Response.Write(myObject.DoGreeting());


The DLL file could be a library that is to be used by both applications and ASP.NET web sites (containing only core functions - not web related).

In the examples I found the class name (actually the assembly, class name, method name and arguments) is also used which is also okay since I wrote the source code for both my DLL file and project (application and/or ASP.NET web site).
Posted

With Reflection, of course you can. A little problem appears when you need not only to load such assemblies (I call them plug-ins, by their most typical use), but also unload them. As unloading of assembly is not allowed, the problem is only solvable throw a separate Application Domain which you can unload, but it leads to the need to work through IPC. If you don't need to unload anything (which is also often the case, say, you define what plug-in to use in some configuration file and use them all the run time), the whole thing is fairly simple, if you do it right.

Only avoid finding anything by name, this is an error-prone approach, better define and implement some plug-in interface.

I explain most of the aspects of it all in my past answers:
What is the use of plugin in general[^],
Create WPF Application that uses Reloadable Plugins...[^],
AppDomain refuses to load an assembly[^],
code generating using CodeDom[^],
Create WPF Application that uses Reloadable Plugins...[^],
Dynamically Load User Controls[^] (simple part explained here, you may want to start with this answer),
C# Reflection InvokeMember on existing instance[^] (and also this one),
Projects and DLL's: How to keep them managable?[^],
Gathering types from assemblies by it's string representation[^].

Don't be afraid: it's not really very hard; it's just that I had many questions on the topic.

—SA
 
Share this answer
 
Comments
Live Long And Prosper 27-Feb-13 15:34pm    
Hi SA. Thank you for your solution. I will read up on the articles and hopefully be able to achieve my goal! I will return soon :-)
Sergey Alexandrovich Kryukov 27-Feb-13 15:35pm    
Sure. And when you see it makes sense (it does, a lot of experience is put in related technologies), please accept the answer formally (green button).
—SA
Live Long And Prosper 28-Feb-13 12:34pm    
Will do - I expect to find the time to test this weekend and will return as soon as possible.
Sergey Alexandrovich Kryukov 28-Feb-13 12:47pm    
Great. Good luck.
—SA
And now, one alternative: using Microsoft Managed Extensibility Framework:
http://en.wikipedia.org/wiki/Managed_Extensibility_Framework[^],
http://mef.codeplex.com/[^].

—SA
 
Share this answer
 
use this as the class change the name to fit
C#
namespace myNamespace
{
internal class MyClass
{
MyClass()
{
}
private static string DoGreeting()
{
return "helloworld";
}
private static string DoGreeting2(string value)
{
if(value == null)
{
value = "";
}
return value;
}
}}


now to use this in code you would use

C#
const BindingFlags MyBinding = (BindingFlags)(-20);
            Assembly asm = Assembly.LoadFrom(Application.StartupPath + "\\myClass.dll");
            object obj = asm.CreateInstance("myNamespace.myClass", true, MyBinding, null, null, null,null);
            string result = (string)obj.GetType().GetMethod("DoGreeting", MyBinding).Invoke(null, null);
            MessageBox.Show(result);


and to use method 2 just do the same as the first while passing the string value to display as such

C#
const BindingFlags MyBinding = (BindingFlags)(-20);
            Assembly asm = Assembly.LoadFrom(Application.StartupPath + "\\myClass.dll");
            object obj = asm.CreateInstance("myNamespace.myClass", true, MyBinding, null, null, null,null);
            string result = (string)obj.GetType().GetMethod("DoGreeting2", MyBinding).Invoke(null, new object[]{"Hello America"});
            MessageBox.Show(result);
 
Share this answer
 
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900