Три дня гуглил и не нашёл как загрузить сборку в отдельный домен.
Через CreateInstanceAndUnwrap НИКАКИМИ выкрутасами не получалось загрузить DLL-ку (из нетекущего каталога).
От безисходности догадался применить CreateInstanceFromAndUnwrap — и всё заработало!
var doMEN = AppDomain.CreateDomain("doMEN");
var instanceBad = doMEN.CreateInstanceAndUnwrap(@"c:\test.dll", "TestNamespace.TestClass"); // не работает
var instanceGood = doMEN.CreateInstanceFromAndUnwrap(@"c:\test.dll", "TestNamespace.TestClass"); // работает
Может кому пригодиться это "открытие".
Как правильно использовать CreateInstanceAndUnwrap?
Здравствуйте, Alatey, Вы писали:
A>Может кому пригодиться это "открытие".
Вы путаете
"имя сборки" (его использует CreateInstanceAndUnwrap) и "имя файла сборки" (используется в CreateInstanceFromAndUnwrap, Assembly.LoadFrom).
При загрузке сборки по имени через CreateInstanceAndUnwrap работают правила загрузки сборок, аналогичные методу Assembly.Load (т. е. в каталоге приложения, затем в подкаталоге, наименование которого совпадает с имененем файла сборки, затем в probing-путях, указанных в конфиге). При загрузке по имени файла через CreateInstanceFromAndUnwrap загрузка в конечном счете делается через Assembly.LoadFrom.
Если вы в конечном счете будете использовать CreateInstanceFromAndUnwrap, нужно учитывать потенциальные грабли, на которые можно наступить (можно загрузить одну сборку из разных файлов в один домен несколько раз).
Здравствуйте, Alatey, Вы писали:
A>Как правильно использовать CreateInstanceAndUnwrap?
Хрень какая-то, а не открытие.
Почитайте CLR via C#, там целая глава есть посвященная вашему вопросу.
Если вкратце, то Вам нужно сделать отдельный proxy класс — MarshalByRefObject.
Я его кладу в отдельную сборку, которая загружается в ОБА домена, поскольку оба должны знать этот тип.
public class Proxy : MarshalByRefObject
{
public static Proxy Create(AppDomain domain)
{
Assembly proxyAssembly = domain.Load(typeof(Proxy).Assembly.FullName);
string qname = typeof(Proxy).FullName;
return (Proxy)domain.CreateInstanceAndUnwrap(proxyAssembly.FullName, qname);
}
}
Когда новый домен будет загружать прокси assembly он будет ее загружать в default-context, делая Assembly.Load(assemblyName).
Вызывающий код получается такой:
domain = AppDomain.CreateDomain(domainName, null);
proxy = Proxy.Create(domain);
Дальше можно загружать сборки только в целевой домен, если это делает за вас прокси. Соответственно туда нужно добавить метод для этого.
Но обязательно нужно изучить КАК работает MarshalByRefObject — это важно чтобы понимать performance & security implications.
Удачи!
Здравствуйте, HowardLovekraft, Вы писали:
HL>Здравствуйте, SemiCoder, Вы писали:
SC>>Хрень какая-то
HL>Это точно. Какое отношение имеет загрузка сборки из "из нетекущего каталога" к MBR?
Вы ответили на первый вопрос. Я на второй. Что нет так-то?
A>Как правильно использовать CreateInstanceAndUnwrap?