Проблема с загрузкой сборки во время выполнения с использованием отражения - PullRequest
1 голос
/ 09 мая 2011

Я использую VS2008 с C # для разработки своего приложения.В моем приложении есть сценарий, в котором я должен загружать сборки из точечной сети во время выполнения, поэтому я использую assembly.loadfrom («имя сборки») для загрузки сборки.Теперь сценарий таков: в моем приложении есть выпадающий список с двумя вариантами.Когда пользователь выбирает вариант 1 и нажимает кнопку «Перейти», сборка загрузится.и аналогично, если пользователь выбирает вариант 2 и нажимает кнопку «GO», сборка2 будет загружена.Обе сборки имеют одинаковые имена, но разные местоположения и версии.

Проблема: Когда я выбираю option1, Assembly1 загружается, и я могу успешно вызывать метод, но когда я выбираю option2, сборка загружается, но при вызове метода Iполучаю ошибку, что метод не загружен.Опция isny option, которую я выбираю, первая работает правильно, а вторая опция имеет проблему с методом invoke.

Мои выводы: я обнаружил, что если я использую опцию loadfrom для загрузки сборки и снова подаю иск на ту же опцию для загрузки другой сборкион возвращает тот же контекст и, следовательно, функция возвращает сборку, уже загруженную в память.следовательно, мы должны использовать LoadFile вместо Loadfrom.Я изменил loadfrom на loadfile, но все же я получаю то же поведение.

Ответы [ 2 ]

1 голос
/ 09 мая 2011

Я только что выполнил простой тест:

Я создал две сборки с кодом:
первая сборка (называемая 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(@".\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);
        }
    }
}

После этого приложение и приложение для вызывающего абонента размещаются следующим образом:

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 это может вам помочь.

0 голосов
/ 09 мая 2011

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

Assembly library = Assembly.Load("library, Version=2.0.0.0, Culture=Neutral, PublicKeyToken=9b184fc90fb9648d");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...