Share via


System.Runtime.Versioning.ComponentGuaranteesAttribute classe

Este artigo fornece observações complementares à documentação de referência para essa API.

O ComponentGuaranteesAttribute é usado por desenvolvedores de componentes e bibliotecas de classes para indicar o nível de compatibilidade que os consumidores de suas bibliotecas podem esperar em várias versões. Ele indica o nível de garantia de que uma versão futura da biblioteca ou componente não quebrará um cliente existente. Os clientes podem então usar o ComponentGuaranteesAttribute como um auxílio na criação de suas próprias interfaces para garantir a estabilidade entre as versões.

Observação

O CLR (Common Language Runtime) não usa esse atributo de forma alguma. Seu valor está em documentar formalmente a intenção do autor componente. As ferramentas de tempo de compilação também podem usar essas declarações para detectar erros de tempo de compilação que, de outra forma, quebrariam a garantia declarada.

Níveis de compatibilidade

O ComponentGuaranteesAttribute suporta os seguintes níveis de compatibilidade, que são representados por membros da ComponentGuaranteesOptions enumeração:

  • Sem compatibilidade de versão para versão (ComponentGuaranteesOptions.None). O cliente pode esperar que versões futuras quebrem o cliente existente. Para obter mais informações, consulte a seção Sem compatibilidade mais adiante neste artigo.

  • Compatibilidade lado a lado de versão para versão (ComponentGuaranteesOptions.SideBySide). O componente foi testado para funcionar quando mais de uma versão do assembly é carregada no mesmo domínio de aplicativo. Em geral, versões futuras podem quebrar a compatibilidade. No entanto, quando alterações de quebra são feitas, a versão antiga não é modificada, mas existe junto com a nova versão. A execução lado a lado é a maneira esperada de fazer com que os clientes existentes trabalhem quando alterações de interrupção são feitas. Para obter mais informações, consulte a seção Compatibilidade lado a lado, mais adiante neste artigo.

  • Compatibilidade estável de versão para versão (ComponentGuaranteesOptions.Stable). Versões futuras não devem quebrar o cliente, e a execução lado a lado não deve ser necessária. No entanto, se o cliente for quebrado inadvertidamente, talvez seja possível usar a execução lado a lado para corrigir o problema. Para obter mais informações, consulte a seção Compatibilidade estável.

  • Compatibilidade de versão para versão do Exchange (ComponentGuaranteesOptions.Exchange). Um cuidado extraordinário é tomado para garantir que as versões futuras não quebrem o cliente. O cliente deve usar somente esses tipos na assinatura de interfaces que são usadas para comunicação com outros assemblies que são implantados independentemente uns dos outros. Espera-se que apenas uma versão desses tipos esteja em um determinado domínio de aplicativo, o que significa que, se um cliente quebrar, a execução lado a lado não poderá corrigir o problema de compatibilidade. Para obter mais informações, consulte a seção Compatibilidade de tipo do Exchange.

As seções a seguir discutem cada nível de garantia com mais detalhes.

Sem compatibilidade

Marcar um componente como ComponentGuaranteesOptions.None indica que o provedor não oferece garantias sobre a compatibilidade. Os clientes devem evitar ter dependências nas interfaces expostas. Esse nível de compatibilidade é útil para tipos experimentais ou expostos publicamente, mas destinados apenas a componentes sempre atualizados ao mesmo tempo. None indica explicitamente que esse componente não deve ser usado por componentes externos.

Compatibilidade lado a lado

Marcar um componente como ComponentGuaranteesOptions.SideBySide indica que o componente foi testado para funcionar quando mais de uma versão do assembly é carregada no mesmo domínio do aplicativo. As alterações de quebra são permitidas, desde que sejam feitas no assembly que tem o maior número de versão. Espera-se que os componentes vinculados a uma versão antiga do assembly continuem a se vincular à versão antiga e outros componentes possam se vincular à nova versão. Também é possível atualizar um componente que é declarado como sendo SideBySide modificando destrutivamente a versão antiga.

Compatibilidade estável

Marcar um tipo como ComponentGuaranteesOptions.Stable indica que o tipo deve permanecer estável entre as versões. No entanto, também pode ser possível que versões lado a lado de um tipo estável existam no mesmo domínio de aplicativo.

Os tipos estáveis mantêm uma barra de compatibilidade binária alta. Por causa disso, os provedores devem evitar fazer alterações de quebra em tipos estáveis. Os seguintes tipos de alterações são aceitáveis:

  • Adicionar campos de instância privada ou remover campos de um tipo, desde que isso não quebre o formato de serialização.
  • Alterando um tipo não serializável para um tipo serializável. (No entanto, um tipo serializável não pode ser alterado para um tipo não serializável.)
  • Lançando novas exceções mais derivadas de um método.
  • Melhorar o desempenho de um método.
  • Alterar o intervalo de valores de retorno, desde que a alteração não afete negativamente a maioria dos clientes.
  • Corrigir bugs graves, se a justificativa do negócio for alta e o número de clientes afetados negativamente for baixo.

Como não se espera que novas versões de componentes estáveis interrompam os clientes existentes, geralmente apenas uma versão de um componente estável é necessária em um domínio de aplicativo. No entanto, isso não é um requisito, porque os tipos estáveis não são usados como tipos de troca bem conhecidos com os quais todos os componentes concordam. Portanto, se uma nova versão de um componente estável quebrar inadvertidamente algum componente, e se outros componentes precisarem da nova versão, talvez seja possível corrigir o problema carregando o componente antigo e novo.

Stable fornece uma garantia de compatibilidade de versão mais forte do que Noneo . É um padrão comum para componentes de várias versões.

Stable pode ser combinado com SideBySide, que afirma que o componente não interromperá a compatibilidade, mas é testado para funcionar quando mais de uma versão é carregada em um determinado domínio de aplicativo.

Depois que um tipo ou método é marcado como Stable, ele pode ser atualizado para Exchange. No entanto, não pode ser rebaixado para None.

Compatibilidade de tipos do Exchange

Marcar um tipo como ComponentGuaranteesOptions.Exchange fornece uma garantia de compatibilidade de versão mais forte do que Stableo , e deve ser aplicado ao mais estável de todos os tipos. Esses tipos destinam-se a ser usados para intercâmbio entre componentes construídos independentemente em todos os limites de componentes em tempo (qualquer versão do CLR ou qualquer versão de um componente ou aplicativo) e espaço (processo cruzado, CLR cruzado em um processo, domínio entre aplicativos em um CLR). Se uma alteração de quebra for feita em um tipo de troca, é impossível corrigir o problema carregando várias versões do tipo.

Os tipos de troca devem ser alterados somente quando um problema é muito sério (como um problema de segurança grave) ou a probabilidade de quebra é muito baixa (ou seja, se o comportamento já foi quebrado de forma aleatória que o código não poderia concebivelmente ter assumido uma dependência). Você pode fazer os seguintes tipos de alterações em um tipo de troca:

  • Adicionar herança de novas definições de interface.

  • Adicione novos métodos privados que implementam os métodos de definições de interface recém-herdadas.

  • Adicione novos campos estáticos.

  • Adicione novos métodos estáticos.

  • Adicione novos métodos de instância não virtual.

Os itens a seguir são considerados alterações de quebra e não são permitidos para tipos primitivos:

  • Alterando formatos de serialização. A serialização tolerante à versão é necessária.

  • Adicionar ou remover campos de instância privada. Isso corre o risco de alterar o formato de serialização do tipo e quebrar o código do cliente que usa reflexão.

  • Alterando a serializabilidade de um tipo. Um tipo não serializável pode não ser serializável e vice-versa.

  • Lançando exceções diferentes de um método.

  • Alterar o intervalo dos valores de retorno de um método, a menos que a definição de membro aumente essa possibilidade e indique claramente como os clientes devem lidar com valores desconhecidos.

  • Corrigindo a maioria dos bugs. Os consumidores do tipo confiarão no comportamento existente.

Depois que um componente, tipo ou membro é marcado com a Exchange garantia, ele não pode ser alterado para ou StableNone.

Normalmente, os tipos de troca são os tipos básicos (como e no .NET) e interfaces (como IList<T>Int32 , IEnumerable<T>e StringIComparable<T>) que são comumente usados em interfaces públicas.

Os tipos do Exchange podem expor publicamente apenas outros tipos que também estejam marcados com Exchange compatibilidade. Além disso, os tipos de troca não podem depender do comportamento das APIs do Windows que são propensas a alterações.

Garantias de componentes

A tabela a seguir indica como as características e o uso de um componente afetam sua garantia de compatibilidade.

Características dos componentes Exchange Estável Lado a lado Nenhum
Pode ser usado em interfaces entre componentes que versão independentemente. N N N N
Pode ser usado (privadamente) por um assembly que faz versões independentes. N N Y N
Pode ter várias versões em um único domínio de aplicativo. N S N S
Pode fazer alterações significativas N N S S
Testado para fazer com que várias versões do assembly possam ser carregadas juntas. N N Y N
Pode fazer alterações de quebra no lugar. N N N S
Pode fazer alterações de manutenção muito seguras e ininterruptas no local. N N N S

Aplicar o atributo

Você pode aplicar o a um assembly, um tipo ou um membro do ComponentGuaranteesAttribute tipo. Sua aplicação é hierárquica. Ou seja, por padrão, a garantia definida pela Guarantees propriedade do atributo no nível do assembly define a garantia de todos os tipos no assembly e de todos os membros nesses tipos. Da mesma forma, se a garantia for aplicada ao tipo, por defeito, também se aplica a cada membro do tipo.

Essa garantia herdada pode ser substituída aplicando-se o a tipos individuais e membros de ComponentGuaranteesAttribute tipo. No entanto, garantias que se sobreponham à inadimplência só podem enfraquecer a garantia; não podem fortalecê-la. Por exemplo, se uma assembleia é marcada com a garantia, seus tipos e membros não têm garantia de compatibilidade, e qualquer outra garantia aplicada a tipos ou membros na assembleia é ignorada None .

Teste a garantia

A Guarantees propriedade retorna um membro da ComponentGuaranteesOptions enumeração, que é marcado com o FlagsAttribute atributo . Isso significa que você deve testar a bandeira em que está interessado, mascarando bandeiras potencialmente desconhecidas. Por exemplo, o exemplo a seguir testa se um tipo está marcado como Stable.

// Test whether guarantee is Stable.
if ((guarantee & ComponentGuaranteesOptions.Stable) == ComponentGuaranteesOptions.Stable)
   Console.WriteLine("{0} is marked as {1}.", typ.Name, guarantee);
' Test whether guarantee is Stable.
If (guarantee And ComponentGuaranteesOptions.Stable) = ComponentGuaranteesOptions.Stable Then
   Console.WriteLine("{0} is marked as {1}.", typ.Name, guarantee)
End If

O exemplo a seguir testa se um tipo é marcado como Stable ou Exchange.

// Test whether guarantee is Stable or Exchange.
if ((guarantee & (ComponentGuaranteesOptions.Stable | ComponentGuaranteesOptions.Exchange)) > 0)
   Console.WriteLine("{0} is marked as Stable or Exchange.", typ.Name, guarantee);
' Test whether guarantee is Stable or Exchange.
If (guarantee And (ComponentGuaranteesOptions.Stable Or ComponentGuaranteesOptions.Exchange)) > 0 Then
   Console.WriteLine("{0} is marked as Stable or Exchange.", typ.Name, guarantee)
End If

O exemplo a seguir testa murchar um tipo é marcado como None (ou seja, nem nem Exchangenem Stable ).

// Test whether there is no guarantee (neither Stable nor Exchange).
if ((guarantee & (ComponentGuaranteesOptions.Stable | ComponentGuaranteesOptions.Exchange)) == 0)
   Console.WriteLine("{0} has no compatibility guarantee.", typ.Name, guarantee);
' Test whether there is no guarantee (neither Stable nor Exchange).
If (guarantee And (ComponentGuaranteesOptions.Stable Or ComponentGuaranteesOptions.Exchange)) = 0 Then
   Console.WriteLine("{0} has no compatibility guarantee.", typ.Name, guarantee)
End If