Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este artigo fornece comentários complementares à documentação de referência para esta 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. Indica o nível de garantia de que uma versão futura da biblioteca ou componente não interromperá um cliente existente. Em seguida, os clientes podem usar o ComponentGuaranteesAttribute como um auxílio na criação de suas próprias interfaces a fim de garantir a estabilidade em todas as versões.
Observação
O CLR (Common Language Runtime) não usa esse atributo de forma alguma. Seu valor está na documentação formal da intenção do autor do 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, interromperiam a garantia declarada.
Níveis de compatibilidade
O ComponentGuaranteesAttribute oferece suporte aos seguintes níveis de compatibilidade, que são representados por membros da enumeração ComponentGuaranteesOptions:
Nenhuma compatibilidade de versão para versão (ComponentGuaranteesOptions.None). O cliente pode esperar que as versões futuras comprometam o cliente existente. Para obter mais informações, consulte a seção Sem compatibilidade mais adiante neste artigo.
Compatibilidade lado a lado entre versões (ComponentGuaranteesOptions.SideBySide). O componente foi testado para funcionar quando mais de uma versão do assembly é carregada no mesmo domínio do aplicativo. Em geral, versões futuras podem interromper a compatibilidade. No entanto, quando alterações significativas 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 funcionem quando alterações significativas são feitas. Para obter mais informações, consulte a seção de compatibilidade lado a lado mais adiante neste artigo.
Compatibilidade estável entre versões (ComponentGuaranteesOptions.Stable). As versões futuras não devem interromper o cliente e a execução lado a lado não deve ser necessária. No entanto, se o cliente for interrompido 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). Cuidados extraordinários são tomados para garantir que as versões futuras não prejudiquem o cliente. O cliente deve usar apenas 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 for interrompido, a execução lado a lado não poderá corrigir o problema de compatibilidade. Para obter mais informações, consulte a seção de compatibilidade de tipos 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 faz garantias sobre compatibilidade. Os clientes devem evitar usar dependências nas interfaces expostas. Esse nível de compatibilidade é útil para tipos experimentais ou expostos publicamente, mas que se destinam apenas a componentes que são 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. Alterações interruptivas são permitidas desde que sejam feitas no assembly que tenha o número de versão maior. Os componentes associados a uma versão antiga do assembly devem continuar a ser associados à versão antiga, e outros componentes podem se associar à nova versão. Também é possível atualizar um componente que foi declarado como SideBySide através da modificação destrutiva da 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 poderá ser possível que versões simultâneas de um tipo estável existam no mesmo domínio de aplicação.
Tipos estáveis mantêm uma barra de compatibilidade binária alta. Por isso, os provedores devem evitar fazer alterações significativas em tipos estáveis. Os seguintes tipos de alterações são aceitáveis:
- Adicionando campos de instância privada ou removendo campos de um tipo, desde que isso não interrompa 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.)
- Gerar novas exceções mais derivadas de um método.
- Melhorando o desempenho de um método.
- Alterando o intervalo de valores retornados, desde que a alteração não afete negativamente a maioria dos clientes.
- Corrigindo bugs graves, se a justificativa comercial 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 interrompa 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, pois os tipos estáveis não são usados como tipos de troca conhecidos que todos os componentes concordam. Portanto, se uma nova versão de um componente estável interromper inadvertidamente algum componente e, se outros componentes precisarem da nova versão, poderá ser possível corrigir o problema carregando o componente antigo e novo.
Stable fornece uma garantia de compatibilidade de versão mais forte do que None. É 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, ele não pode ser rebaixado para None.
Compatibilidade de tipo do Exchange
Marcar um tipo como ComponentGuaranteesOptions.Exchange fornece uma garantia de compatibilidade de versão mais forte do que Stablee deve ser aplicado ao mais estável de todos os tipos. Esses tipos devem ser usados para intercâmbio entre componentes criados independentemente em todos os limites de componentes tanto no tempo (qualquer versão do CLR ou qualquer versão de um componente ou aplicativo) quanto no espaço (entre processos, entre CLR em um único processo, entre domínios de aplicativo em um CLR). Se uma alteração significativa for feita em um tipo de troca, é impossível corrigir o problema carregando várias versões do tipo.
Os tipos de trocas devem ser alterados somente quando um problema for muito sério (como um grave problema de segurança) ou a probabilidade de interrupção for muito baixa (ou seja, se o comportamento já tiver sido quebrado de uma forma aleatória da qual o código não poderia ter tomado uma dependência de maneira concebível). Você pode fazer os seguintes tipos de alterações em um tipo de troca:
Adicione 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.
A seguir, são consideradas alterações interruptivas e não são permitidas para tipos primitivos:
Alterando formatos de serialização. A serialização tolerante à versão é necessária.
Adicionando ou removendo 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.
Alteração da capacidade de serialização de um tipo. Um tipo não serializável não pode ser tornado serializável, e vice-versa.
Lançamento de exceções diferentes de um método.
Alterando o intervalo dos valores retornados de um método, a menos que a definição de membro gere essa possibilidade e indique claramente como os clientes devem lidar com valores desconhecidos.
Corrigindo a maioria dos bugs. Os consumidores desse tipo dependerão do comportamento existente.
Depois que um componente, tipo ou membro é marcado com a Exchange garantia, ele não pode ser alterado para um Stable ou None.
Normalmente, os tipos de troca são os tipos básicos (como Int32 e String no .NET) e interfaces (como IList<T>, IEnumerable<T>e IComparable<T>) que são comumente usadas em interfaces públicas.
Os tipos do Exchange podem expor publicamente apenas outros tipos que também estão marcados como compatíveis. Além disso, os tipos de troca não podem depender do comportamento das APIs do Windows que estã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 do componente | Troca | Estável | Lado a lado | Nenhum |
|---|---|---|---|---|
| Pode ser usado em interfaces entre componentes que têm versões independentes. | S | N | N | N |
| Pode ser usado (privadamente) por um assembly que faz versões de forma independente. | S | S | S | N |
| Pode ter várias versões em um único domínio de aplicativo. | N | S | S | S |
| Pode fazer alterações significativas | N | N | S | S |
| Testado para garantir que múltiplas versões do assembly possam ser carregadas juntas. | N | N | S | N |
| Pode fazer mudanças disruptivas no local. | N | N | N | S |
| Pode fazer alterações de manutenção sem interrupção muito seguras no local. | S | S | S | S |
Aplicar o atributo
Você pode aplicar o ComponentGuaranteesAttribute a um assembly, um tipo ou um membro de tipo. Seu aplicativo é hierárquico. Ou seja, por padrão, a garantia definida pela propriedade Guarantees do atributo ao nível do assembly define a garantia de todos os tipos no assembly, assim como de todos os membros desses tipos. Da mesma forma, se a garantia for aplicada ao tipo, por padrão, ela também se aplicará a cada membro do tipo.
Essa garantia herdada pode ser substituída aplicando o ComponentGuaranteesAttribute a tipos individuais e membros de tipo. No entanto, as garantias que substituem o padrão só podem enfraquecer a garantia; elas não podem fortalecê-las. Por exemplo, se um assembly for marcado com a garantia None, seus tipos e membros não terão nenhuma garantia de compatibilidade e qualquer outra garantia aplicada a tipos ou membros no assembly será ignorada.
Testar a garantia
A Guarantees propriedade retorna um membro da ComponentGuaranteesOptions enumeração, que é marcada com o FlagsAttribute atributo. Isso significa que é necessário testar o sinalizador no qual você está interessado mascarando sinalizadores potencialmente desconhecidos. 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($"{typ.Name} is marked as {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 está marcado como Stable ou Exchange.
// Test whether guarantee is Stable or Exchange.
if ((guarantee & (ComponentGuaranteesOptions.Stable | ComponentGuaranteesOptions.Exchange)) > 0)
Console.WriteLine($"{typ.Name} is marked as Stable or Exchange.");
' 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 se um tipo está marcado como None (isto é, nem Stable nem Exchange).
// Test whether there is no guarantee (neither Stable nor Exchange).
if ((guarantee & (ComponentGuaranteesOptions.Stable | ComponentGuaranteesOptions.Exchange)) == 0)
Console.WriteLine($"{typ.Name} has no compatibility 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