#c# #reflection
#c# #отражение
Вопрос:
Я использую VS2008 с C # для разработки своего приложения. В моем приложении есть сценарий, в котором я должен загружать сборки dot net во время выполнения, поэтому я использую assembly.loadfrom («имя сборки») для загрузки сборки. Теперь сценарий таков: в моем приложении есть выпадающий список с двумя вариантами. Когда пользователь выберет опцию 1 и нажмет на кнопку «Перейти», assemblya загрузится. и аналогично, если пользователь выберет опцию 2 и нажмет на кнопку «ПЕРЕЙТИ», assembly2 будет загружен. Обе сборки имеют одинаковое имя, но разные расположения и версии.
Проблема: Когда я выбираю опцию 1, загружается assembly1, и я могу успешно вызвать метод, но когда я выбираю опцию 2, сборка загружается, но при вызове метода я получаю сообщение об ошибке, что метод не загружен. Проблема в том, что ни один вариант, который я выбираю, не работает должным образом, а второй вариант имеет проблему с методом вызова.
Мои выводы: Я обнаружил, что если я использую опцию loadfrom для загрузки сборки и снова использую ту же опцию для загрузки другой сборки, она возвращает тот же контекст, и, следовательно, функция возвращает сборку, уже загруженную в память. следовательно, мы должны использовать LoadFile вместо Loadfrom. Я изменил loadfrom на loadfile, но до сих пор я получаю то же поведение.
Ответ №1:
Я только что выполнил простой тест:
Я создал два ассебли с кодом:
первый ассебли (вызывается 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!");
}
}
}
вторая сборка (тоже вызывается 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("Im a new Test!");
}
}
}
И вызывающее приложение (форма с двумя кнопками):
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(@".test1test1.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(@".test2test1.dll");
}
object inst = _assembly2.CreateInstance("Test1.Class1");
inst.GetType().InvokeMember("SayHello", System.Reflection.BindingFlags.InvokeMethod, null, inst, null);
}
}
}
После этого a поместил сборки и вызывающее приложение следующим образом:
AppDir
|
- CallerApp.exe
|
- test1
| |
| - test1.dll <-- my first assembly
|
- test2
|
- test1.dll <-- my second assembly
Во время тестирования у меня нет ошибок, и методы, которые я вызываю, дали мне соответствующие результаты. Может быть, вы используете другую технику создания экземпляра / вызова метода, чем я?
Я полагаю, что ваша проблема связана с контекстом привязки, способом, которым вы вызываете методы или создаете экземпляры. Есть хороший пост в блоге о контексте привязки — http://blogs.msdn.com/b/suzcook/archive/2003/05/29/57143.aspx это может вам помочь.
Комментарии:
1. Привет, Антон, я не знаю, когда я использую ваш способ вызова метода, я получаю сообщение об ошибке, что метод не найден. Изначально я создавал объект methodinfo с помощью GetMethod() . а затем использовал его для вызова метода. В том случае это вызвало у меня основную проблему, о которой я заявил. Но когда я попробовал ваш способ, я получаю метод, который не найден. Пожалуйста, помогите мне. Я здесь сильно застрял.
2. @user744497: не могли бы вы раскрыть часть вашего кода, которая загружает сборки и вызывает метод. Также, пожалуйста, опишите пути к сборкам для загрузки
Ответ №2:
Попробуйте использовать сборку.Загрузите и укажите строгое имя сборки.
Assembly library = Assembly.Load("library, Version=2.0.0.0, Culture=Neutral, PublicKeyToken=9b184fc90fb9648d");