Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Загрузка сборки в домен из произвольного каталога

70K
18 октября 2011 года
Saimon2k
3 / / 14.06.2011
Здравствуйте, хотел обратиться к Вам со следующей проблемой.
Генерирую две сборки с помощью встроенного C# компилятора кода. Первая запускаемая, а вторая с так называемыми вспомогательными пользовательскими функциями.
Проблема именно в том, чтобы загрузить их одновременно в домен, для возможности дальнейшей выгрузки, т.к. загруженную сборку можно выгрузить лишь выгрузив её домен. Загрузка сборок должна производиться из определенного каталога, который не связан с приложением (Допустим C:\Libraries). В этом главная проблема, потому что если положить сборки в каталог запускаемого приложения, то все загружается легко.

Запускаемая библиотека:
Код:
public partial class Runner
{
    public static string Run()
    {
        return "SomeMethod:" + ClassLib.SomeMethod();
    }

    public string GetVersion()
    {
        return "v01";
    }
}


 
Код:
public class ClassLib //: MarshalByRefObject
{
    public static string SomeMethod()
    {
        return "Invoke SomeMethod";
    }
}


Перепробовал не мало способов, и мои пояснения. Поправьте, если я не прав.

Загрузка в текущий домен, что изначально не подходит, но все же привел его. Как я понял данным метод загружается вне контекста, где дополнительно невозможно загружать другие сборки
 
Код:
Assembly assembly = Assembly.LoadFile(path_run);


Подписываюсь на событие при невозможности загрузки из каталога приложения. Обманный ход, но не работает.
 
Код:
AppDomain ad = AppDomain.CreateDomain("sd");
ad.AssemblyResolve += delegate(object sender, ResolveEventArgs args) { return Assembly.LoadFile(args.Name); };
Assembly assembly = ad.Load(path_run);
Invoke(assembly);


Метод Invoke я произвожу поиск класса и его метода по сборке и потом запускаю. Что то вроде этого
 
Код:
var result = assembly.GetType("TestInvoke.Run.Runner").GetMethod("Run").Invoke(null, null);


Метод CreateInstanceFromAndUnwrap. Как я понял, то необходимо объявлять через интерфейс, наследоваться от MarshalByRefObject и применение флага [Serializable]. Это работает, но жутко не удобно, потому что в реальном приложении объявления этого флага [Serializable] необходимо у 90% всех классов! o_O
Код:
AppDomain ad = AppDomain.CreateDomain("sd1");
try
{
    IRunner runner = (IRunner)ad.CreateInstanceFromAndUnwrap(
        Path.GetDirectoryName(path_run) + "\\TplRunerI.dll",
        "TestInvoke.Run.Runner");
    object result = runner.GetVersion();
    Console.WriteLine(result as string);
}
finally
{
    AppDomain.Unload(ad);
}


Пробовал и с применением класса AppDomainSetup, в котором можно указать ApplicationBase - каталог с приложением, а именно там сначала проводится поиск необходимых сборок. Но как будто он не реагирует на это поле.

Вот мой тестовый проект.
http://depositfiles.com/files/25mk9qtff
5
18 октября 2011 года
hardcase
4.5K / / 09.08.2005
LoadFile загружает сборку вне контекста в текущий домен приложения. Как правило для загрузки сборок используют метод LoadFrom - он выполняет поиск зависимостей в том каталоге из которого сборка загружается.

В целом же совершенно не понятно какую проблему вы решаете.
70K
19 октября 2011 года
Saimon2k
3 / / 14.06.2011
Проблема заключается в загрузке двух зависимых библиотек в домен.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог