Compartilhar via


Assemblies de coleção para geração de tipos dinâmicos

Assemblies de coleção são assemblies dinâmicos que podem ser descarregados sem descarregar o domínio do aplicativo no qual eles foram criados. Toda a memória gerenciada e não gerenciada usada por um assembly de coleção e os tipos que ele contém pode ser recuperada. Informações como o nome do assembly são removidas das tabelas internas.

Para habilitar o descarregamento, use o sinalizador AssemblyBuilderAccess.RunAndCollect ao criar um assembly dinâmico. A montagem é transitória (ou seja, não pode ser salva) e está sujeita a limitações descritas na seção Restrições sobre assemblies colecionáveis. O CLR (Common Language Runtime) descarrega automaticamente um assembly colecionável quando você libera todos os objetos associados ao assembly. Em todos os outros aspectos, os assemblies de coleção são criados e usados da mesma maneira de outros assemblies dinâmicos.

Tempo de vida dos assemblies de coleção

O tempo de vida de um assembly de coleção é controlado pela existência de referências aos tipos que ele contém e aos objetos que são criados com base nesses tipos. O common language runtime não descarrega um assembly desde que exista um ou mais dos seguintes tipos (T é qualquer tipo definido no assembly):

  • Uma instância 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 de T, 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 TypeBuilderobjeto , e o AssemblyBuilder objeto mantém uma referência ao ModuleBuilder, portanto, as referências a esses objetos devem ser liberadas. Até mesmo a existência de um LocalBuilder ou um ILGenerator usado na construção de T impede o descarregamento.

  • Uma referência estática a T por outro tipo definido de forma dinâmica T1 que ainda pode ser acessado pelo código em execução. Por exemplo, T1 pode derivar de T, ou T pode ser o tipo de um parâmetro em um método de T1.

  • Um ByRef a um campo estático que pertence a T.

  • A RuntimeTypeHandle, RuntimeFieldHandleou RuntimeMethodHandle que se refere a T ou a um componente de T.

  • Uma instância de qualquer objeto de reflexão que poderá ser usada indireta ou diretamente para acessar o objeto Type que representa T. Por exemplo, o Type objeto para T pode ser obtido de um tipo de matriz cujo tipo de elemento é T, ou de um tipo genérico que tem T como um argumento de tipo.

  • Um método M na pilha de chamadas de qualquer thread, em que M é um método de T ou um método de nível de módulo definido no assembly.

  • Um delegado para um método estático definido em um módulo da assemblia.

Se houver apenas um item dessa lista para apenas um tipo ou um método no assembly, o runtime não poderá descarregar o assembly.

Observação

Na verdade, o runtime não descarrega o assembly até que os finalizadores tenham sido executados para todos os itens da lista.

Para fins de acompanhamento do tempo de vida, um tipo genérico construído, como List<int> (em C#) ou List(Of Integer) (no Visual Basic), criado e usado na geração de um assembly colecionável, é considerado definido no assembly que contém a definição do tipo genérico ou em um assembly que contém um dos seus argumentos de tipo. O conjunto exato usado é um detalhe de implementação e está sujeito a alterações.

Restrições de assemblies de coleção

As seguintes restrições se aplicam a montagens colecionáveis:

  • Referências estáticas

    Os tipos em um assembly dinâmico comum não podem ter referências estáticas a tipos definidos em um assembly de coleção. Por exemplo, se você definir um tipo comum herdado de um tipo em um assembly de coleção, uma exceção NotSupportedException será gerada. Um tipo em um assembly de coleção pode ter referências estáticas a um tipo em outro assembly de coleção, mas isso aumenta 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 em um assembly colecionável e nenhuma instância de tipos em um assembly colecionável pode ser convertida em objetos COM. Um tipo em um assembly de coleção não pode servir como um CCW (COM Callable Wrapper) ou RCW (Runtime Callable Wrapper). No entanto, os tipos em assemblies de coleção podem usar objetos que implementam interfaces COM.

  • Invocação de plataforma

    Os métodos que têm o atributo DllImportAttribute não serão compilados quando forem declarados em um assembly de coleção. A instrução OpCodes.Calli não pode ser usada na implementação de um tipo em um assembly de coleção e esses tipos não podem ter marshalling para um código não gerenciado. No entanto, você pode chamar o código nativo usando um ponto de entrada declarado em uma assemblagem não coletável.

  • Empacotamento

    Objetos (em particular, representantes) que são definidos em assemblies de coleção não podem ter marshaling. Essa é uma restrição de todos os tipos emitidos transitórios.

  • Carregamento de assembly

    A emissão de reflexão é o único mecanismo com suporte para o carregamento de assemblies de coleção. Assemblies carregados por meio de qualquer outra forma de carregamento do assembly não podem ser descarregados.

  • Objetos associados ao contexto

    Não há suporte para variáveis estáticas de contexto. Tipos em um assembly de coleção não podem estender ContextBoundObject. No entanto, o código em assemblies colecionáveis pode usar objetos associados ao contexto definidos em outro lugar.

  • Dados estáticos em thread

    Não há suporte para variáveis estáticas de thread.

As seguintes restrições se aplicam a assemblies colecionáveis nas versões do .NET Framework e do .NET antes do .NET 9:

  • Campos estáticos com FixedAddressValueTypeAttribute

    Campos estáticos definidos em assemblies colecionáveis não podem ter o FixedAddressValueTypeAttribute atributo aplicado.

Consulte também