Problem with loading assembly at runtime using reflection
I am using VS2008 with C# to develop my application. In my app there is a scenarion where I have to load dot net assemblies at runtime hence I am using assembly.loadfrom("assembly name") to load the assembly. Now the scenario is: In my application there is a dropdown having two options. When user selects option1 and click on "Go" button assemblya will load. and similarly if user selects option2 and click on "GO" button assembly2 will be loaded. Both the assemblies have same name but different locations and versions.
The problem: When I selects option1, assembly1 gets loaded and I can invok开发者_开发百科e method successfully, but when I selects option2 assembly gets loaded but while invoking the method I am getting error tht the method is not loaded. The issue isny option I selects first works properly and second option has a problem with invoke method.
My findings: I had find that if I use loadfrom option to load assembly and again sue the same option to load another assembly it returns the same context and hence the function returns the assembly already loaded in the memory. hence we should use LoadFile instead of Loadfrom. I had changed loadfrom to loadfile but atill i am getting the same behaviour.
I just performed simple test:
I have create two asseblies with code:
first assebly (called test1.dll
)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Test1
{
public class Class1
{
public void SayHello()
{
System.Windows.Forms.MessageBox.Show("Test!");
}
}
}
second assembly (called test1.dll
too):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Test1
{
public class Class1
{
public void SayHello()
{
System.Windows.Forms.MessageBox.Show("Im a new Test!");
}
}
}
And caller application(form with two buttons):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Asseblies
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private System.Reflection.Assembly _assembly1 = null;
private System.Reflection.Assembly _assembly2 = null;
private void button1_Click(object sender, EventArgs e)
{
if (System.Object.Equals(_assembly1,null))
{
_assembly1 = System.Reflection.Assembly.LoadFrom(@".\test1\test1.dll");
}
object inst = _assembly1.CreateInstance("Test1.Class1");
inst.GetType().InvokeMember("SayHello", System.Reflection.BindingFlags.InvokeMethod, null, inst, null);
}
private void button2_Click(object sender, EventArgs e)
{
if (System.Object.Equals(_assembly2, null))
{
_assembly2 = System.Reflection.Assembly.LoadFrom(@".\test2\test1.dll");
}
object inst = _assembly2.CreateInstance("Test1.Class1");
inst.GetType().InvokeMember("SayHello", System.Reflection.BindingFlags.InvokeMethod, null, inst, null);
}
}
}
After that a have put assemblies and caller app in follow way:
AppDir
|
- CallerApp.exe
|
- test1
| |
| - test1.dll <-- my first assembly
|
- test2
|
- test1.dll <-- my second assembly
During test I have no errors and methods I call yielded me appropriate results. May be you are using different instance creation/method invocation technique than me?
I belive that your problem belongs on binding context, the way you are invoking methods or creating instances. There is a good blog post about binding context - http://blogs.msdn.com/b/suzcook/archive/2003/05/29/57143.aspx its may help you.
Try to use Assembly.Load and specify the strong name of the assembly.
Assembly library = Assembly.Load("library, Version=2.0.0.0, Culture=Neutral, PublicKeyToken=9b184fc90fb9648d");
精彩评论