MyAppDomain AssemblyResolve C#
У меня есть DLL, которую я использую в среде, где мне нужно самостоятельно обрабатывать загрузку внешних сборок. Я хочу загрузить сборку в домен приложений. Это работает нормально, когда я пытаюсь сделать это с CurrentAppDomain, но я не могу сделать это в appdomain, который я создаю сам. Фон в том, что я хочу выгрузить домен приложения в конце, чтобы сборка была "освобождена" в конце.
public ZipEx()
{
try
{
AppDomainSetup domaininfo = new AppDomainSetup();
domaininfo.ApplicationBase = System.Environment.CurrentDirectory;
Evidence adevidence = AppDomain.CurrentDomain.Evidence;
//THIS CODE WORKS
//System.AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
//System.AppDomain.CurrentDomain.Load("ICSharpCode.SharpZipLib");
//THIS CODE DOES NOT WORK
AppDomain zipDomain2 = AppDomain.CreateDomain("ADZib2", adevidence, domaininfo);
PolicyLevel polLevel = PolicyLevel.CreateAppDomainLevel();
PermissionSet permSet = new PermissionSet(PermissionState.Unrestricted);
permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.AllFlags));
polLevel.RootCodeGroup.PolicyStatement = new PolicyStatement(permSet);
zipDomain2.SetAppDomainPolicy(polLevel);
zipDomain2.AssemblyResolve += CurrentDomain_AssemblyResolve;
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show("ex in ctor" + Environment.NewLine + ex.ToString());
}
if (_loadedAssembly == null)
{
}
}
Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
System.Windows.Forms.MessageBox.Show("CurrentDomain_AssemblyResolve");
Assembly assembly = null;
bool foundAssembly = false;
int idx = args.Name.IndexOf(',');
if (idx > 0)
{
string partialName = args.Name.Substring(0, idx);
string dllName = partialName + ".dll";
//Add the directorys where the assembly hould be resolved
List<string> directorySearch = new List<string>
{
string.Format("{0}{1}{2}",Environment.CurrentDirectory,Path.DirectorySeparatorChar, dllName),
string.Format("{0}{1}{2}",AppPath,Path.DirectorySeparatorChar, dllName)
};
foreach (string fileName in directorySearch)
{
if (File.Exists(fileName))
{
foundAssembly = true;
assembly = Assembly.LoadFrom(fileName);
break;
}
}
if (assembly == null)
{
if (!foundAssembly)
{
foreach (string fileName in directorySearch)
{
}
}
else
{
}
}
}
if (assembly != null)
{
System.Windows.Forms.MessageBox.Show("assembly is not null");
}
return assembly;
}
Мой вопрос: как мне использовать домен приложения, который я создал, чтобы загрузить сборку?
1 ответ
В вашем текущем примере я не вижу ни одного незакомментированного кода, который заставил бы вновь созданный AppDomain попытаться загрузить сборку. В этом ответе я предполагаю, что в вашем нескомментированном коде отсутствует вызов Load.
Согласно примечаниям в справке для AppDomain.Load, его следует использовать только в текущем AppDomain, поскольку в противном случае он попытается загрузить сборку в ОБАХ доменах приложений, что, вероятно, приводит к тому, что вы получаете исключение. Чтобы загрузить сборку только в другой домен приложения, необходимо вызвать одну из функций CreateInstance. В этом конкретном случае я бы порекомендовал функцию CreateInstanceFromAndUnwrap, поскольку она позволит вам указать сборку как по имени, так и по типу.
Если у вас нет типа, который вы хотите создать, и сможете взаимодействовать через границы AppDomain (что кажется маловероятным, но возможным), вам, возможно, придется создать и отбросить какой-то простой тип, такой как enum или struct, чтобы заставить его работать.