public partial class Runner
{
public static string Run()
{
return "SomeMethod:" + ClassLib.SomeMethod();
}
public string GetVersion()
{
return "v01";
}
}
Загрузка сборки в домен из произвольного каталога
Генерирую две сборки с помощью встроенного C# компилятора кода. Первая запускаемая, а вторая с так называемыми вспомогательными пользовательскими функциями.
Проблема именно в том, чтобы загрузить их одновременно в домен, для возможности дальнейшей выгрузки, т.к. загруженную сборку можно выгрузить лишь выгрузив её домен. Загрузка сборок должна производиться из определенного каталога, который не связан с приложением (Допустим C:\Libraries). В этом главная проблема, потому что если положить сборки в каталог запускаемого приложения, то все загружается легко.
Запускаемая библиотека:
Код:
Код:
public class ClassLib //: MarshalByRefObject
{
public static string SomeMethod()
{
return "Invoke SomeMethod";
}
}
{
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);
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);
}
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
В целом же совершенно не понятно какую проблему вы решаете.
Проблема заключается в загрузке двух зависимых библиотек в домен.