Montagens colecionáveis para geração de tipo dinâmico
Assemblies colecionáveis são assemblies dinâmicos que podem ser descarregados sem descarregar o domínio do aplicativo no qual foram criados. Toda a memória gerenciada e não gerenciada usada por um assembly colecionável e os tipos que ele contém podem ser recuperados. Informações como o nome do assembly são removidas das tabelas internas.
Para habilitar o descarregamento, use o AssemblyBuilderAccess.RunAndCollect sinalizador ao criar um assembly dinâmico. O assembly é transitório (ou seja, não pode ser salvo) e está sujeito às limitações descritas na seção Restrições sobre assemblies colecionáveis. O Common Language Runtime (CLR) descarrega um assembly colecionável automaticamente quando você libera todos os objetos associados ao assembly. Em todos os outros aspetos, os assemblies colecionáveis são criados e usados da mesma forma que outros assemblies dinâmicos.
Vida útil das montagens colecionáveis
O tempo de vida de um assembly colecionável é controlado pela existência de referências aos tipos que ele contém e aos objetos que são criados a partir desses tipos. O common language runtime não descarrega um assembly desde que exista um ou mais dos seguintes itens (T
é qualquer tipo definido no assembly):
Um exemplo de
T
.Uma instância de uma matriz de
T
.Uma instância de um tipo genérico que tem
T
como um de seus argumentos de tipo. Isso inclui coleções genéricas deT
, mesmo que essa coleção esteja vazia.Uma instância de Type ou TypeBuilder que representa
T
.Importante
Você deve liberar todos os objetos que representam partes da montagem. O ModuleBuilder que define
T
mantém uma referência ao TypeBuilder, e o AssemblyBuilder objeto mantém uma referência ao ModuleBuilder, portanto, as referências a esses objetos devem ser liberadas. Mesmo a existência de um LocalBuilder ou um ILGenerator usado na construção deT
impede a descarga.Uma referência estática a
T
outro tipoT1
definido dinamicamente que ainda pode ser acessado pela execução de código. Por exemplo,T1
pode derivar deT
, ouT
pode ser o tipo de um parâmetro em um método deT1
.A
ByRef
a um campo estático que pertence aT
.A RuntimeTypeHandle, RuntimeFieldHandle, ou RuntimeMethodHandle que se refere a
T
ou a um componente deT
.Uma instância de qualquer objeto de reflexão que possa ser usado indiretamente ou diretamente para acessar o Type objeto que representa
T
o . Por exemplo, o Type objeto paraT
pode ser obtido de um tipo de matriz cujo tipo de elemento éT
, ou de um tipo genérico que temT
como argumento de tipo.Um método
M
na pilha de chamadas de qualquer thread, ondeM
é um método de ou um método de nível deT
módulo que é definido no assembly.Um delegado a um método estático definido em um módulo do assembly.
Se apenas um item dessa lista existir para apenas um tipo ou um método no assembly, o tempo de execução não poderá descarregar o assembly.
Nota
Na verdade, o tempo de execução não descarrega o assembly até que os finalizadores tenham sido executados para todos os itens da lista.
Para fins de controle do tempo de vida, um tipo genérico construído como List<int>
(em C#) ou List(Of Integer)
(em Visual Basic) que é criado e usado na geração de um assembly colecionável é considerado como tendo sido definido no assembly que contém a definição de tipo genérico ou em um assembly que contém a definição de um de seus argumentos de tipo. O assembly exato usado é um detalhe de implementação e está sujeito a alterações.
Restrições sobre montagens colecionáveis
As seguintes restrições se aplicam a montagens colecionáveis:
Referências estáticas
Os tipos em um assembly dinâmico ordinário não podem ter referências estáticas a tipos definidos em um assembly colecionável. Por exemplo, se você definir um tipo comum que herda de um tipo em um assembly colecionável, uma NotSupportedException exceção será lançada. Um tipo em um assembly colecionável pode ter referências estáticas a um tipo em outro assembly colecionável, mas isso estende o tempo de vida do assembly referenciado para o tempo de vida do assembly de referência.
As seguintes restrições se aplicam a assemblies colecionáveis no .NET Framework:
Interoperabilidade COM
Nenhuma interface COM pode ser definida dentro de um assembly colecionável e nenhuma instância de tipos dentro de um assembly colecionável pode ser convertida em objetos COM. Um tipo em um assembly colecionável não pode servir como um wrapper chamável COM (CCW) ou um wrapper chamável de tempo de execução (RCW). No entanto, os tipos em assemblies colecionáveis podem usar objetos que implementam interfaces COM.
Invocação da plataforma
Os métodos que têm o DllImportAttribute atributo não serão compilados quando forem declarados em um assembly colecionável. A OpCodes.Calli instrução não pode ser usada na implementação de um tipo em um assembly colecionável, e esses tipos não podem ser empacotados para código não gerenciado. No entanto, você pode chamar o código nativo usando um ponto de entrada declarado em um assembly não colecionável.
Marshaling
Os objetos (em particular, delegados) que são definidos em assemblies colecionáveis não podem ser empacotados. Esta é uma restrição para todos os tipos de emissões transitórias.
Carregamento da montagem
A emissão de reflexão é o único mecanismo suportado para carregar montagens colecionáveis. Os assemblies que são carregados usando qualquer outra forma de carregamento de assembly não podem ser descarregados.
Objetos ligados ao contexto
Não há suporte para variáveis estáticas de contexto. Os tipos em um conjunto colecionável não podem se estender ContextBoundObject. No entanto, o código em assemblies colecionáveis pode usar objetos ligados ao contexto que são definidos em outro lugar.
Dados estáticos de thread
Não há suporte para variáveis estáticas de thread.
As restrições a seguir se aplicam a assemblies colecionáveis nas versões .NET Framework e .NET anteriores ao .NET 9:
Campos estáticos com
FixedAddressValueTypeAttribute
Os campos estáticos definidos em assemblies colecionáveis não podem ter o FixedAddressValueTypeAttribute atributo aplicado.