Como descarregar um assembly do AppDomain primário?

Eu gostaria de saber como descarregar um assembly que é carregado no AppDomain principal.

Eu tenho o seguinte código:

var assembly = Assembly.LoadFrom( FilePathHere ); 

Eu preciso / quero poder descarregar essa assembly quando terminar.

Obrigado pela ajuda.

Você não pode descarregar um assembly de um appdomain. Você pode destruir appdomains, mas uma vez que um assembly é carregado em um appdomain, ele está lá para a vida útil do appdomain.

Veja a explicação de Jason Zander sobre Por que não há um método Assembly.Unload?

Se você estiver usando o 3.5, você pode usar o AddIn Framework para facilitar o gerenciamento / chamada em diferentes AppDomains (que você pode descarregar, descarregar todos os assemblies). Se você estiver usando versões anteriores, precisará criar um novo appdomain para descarregá-lo.

Eu também sei que isso é muito antigo, mas pode ajudar alguém que está tendo esse problema! Aqui está uma maneira que encontrei para fazer isso! ao invés de usar:

 var assembly = Assembly.LoadFrom( FilePathHere ); 

usa isto:

 var assembly = Assembly.Load( File.ReadAllBytes(FilePathHere)); 

Isso realmente carrega o “conteúdo” do arquivo de assembly, em vez do arquivo em si. O que significa que NÃO há um bloqueio de arquivo colocado no arquivo de assembly! Portanto, agora ele pode ser copiado, excluído ou atualizado sem fechar seu aplicativo ou tentar usar um AppDomain ou Marshaling separado!

PROS: Muito simples de corrigir com um 1 Liner de código! CONS: Não é possível usar AppDomain, Assembly.Location ou Assembly.CodeBase.

Agora você só precisa destruir todas as instâncias criadas na assembly. Por exemplo:

 assembly = null; 

Você não pode descarregar uma assembly sem descarregar todo o AppDomain. Aqui está o porquê :

  1. Você está executando esse código no domínio do aplicativo. Isso significa que há potencialmente sites de chamadas e pilhas de chamadas com endereços que esperam continuar funcionando.

  2. Digamos que você conseguiu rastrear todas as alças e referências para o código já em execução por uma assembly. Supondo que você não tenha o código, uma vez que você liberou a assembly com sucesso, você liberou apenas os metadados e o IL. O código JIT ainda é alocado no heap do carregador de domínio do aplicativo (os methods JIT são alocados sequencialmente em um buffer na ordem em que são chamados).

  3. A última questão diz respeito ao código que foi carregado compartilhado, caso contrário, mais formalmente conhecido como “domínio neutro” (check-out / compartilhado na ferramenta ngen). Nesse modo, o código de uma assembly é gerado para ser executado a partir de qualquer domínio de aplicativo (nada com fio).

É recomendável que você projete seu aplicativo em torno do limite de domínio do aplicativo naturalmente, onde o descarregamento é totalmente suportado.

Você deve carregar seus assemblies temporários em outro AppDomain e quando não estiver em uso, você poderá descarregar esse AppDomain . É seguro e rápido.

Se você quiser ter um código temporário que possa ser descarregado posteriormente, dependendo de suas necessidades, a class DynamicMethod pode fazer o que você deseja. Isso não te dá aulas, no entanto.

Aqui está um bom exemplo de como compilar e executar dll durante o tempo de execução e, em seguida, descarregar todos os resources: http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm

Eu sei que é antigo, mas pode ajudar alguém. Você pode carregar o arquivo do stream e liberá-lo. Isso funcionou para mim. Eu encontrei a solução AQUI .

Espero que ajude.

Como alternativa, se a assembly foi carregada em primeiro lugar, para verificar as informações da assembly como a publicKey, a melhor maneira seria não carregá-la e, em vez disso, verificar as informações carregando apenas o AssemblyName primeiro:

 AssemblyName an = AssemblyName.GetAssemblyName ("myfile.exe"); byte[] publicKey = an.GetPublicKey(); CultureInfo culture = an.CultureInfo; Version version = an.Version; 

EDITAR

Se você precisar refletir os tipos na assembly sem obter o assembly no domínio do aplicativo, você pode usar o método Assembly.ReflectionOnlyLoadFrom . isso permitirá que você examine os tipos na assembly, mas não permita instanciá-los, e também não carregará a assembly no AppDomain.

Veja este exemplo como explicação

 public void AssemblyLoadTest(string assemblyToLoad) { var initialAppDomainAssemblyCount = AppDomain.CurrentDomain.GetAssemblies().Count(); //4 Assembly.ReflectionOnlyLoad(assemblyToLoad); var reflectionOnlyAppDomainAssemblyCount = AppDomain.CurrentDomain.GetAssemblies().Count(); //4 //Shows that assembly is NOT loaded in to AppDomain with Assembly.ReflectionOnlyLoad Assert.AreEqual(initialAppDomainAssemblyCount, reflectionOnlyAppDomainAssemblyCount); // 4 == 4 Assembly.Load(assemblyToLoad); var loadAppDomainAssemblyCount = AppDomain.CurrentDomain.GetAssemblies().Count(); //5 //Shows that assembly is loaded in to AppDomain with Assembly.Load Assert.AreNotEqual(initialAppDomainAssemblyCount, loadAppDomainAssemblyCount); // 4 != 5 }