Проблема с загрузкой сборки во время выполнения с использованием отражения

#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");