Condividi tramite


Classe System.Runtime.Versioning.ComponentGuaranteesAttribute

Questo articolo fornisce osservazioni supplementari alla documentazione di riferimento per questa API.

Viene ComponentGuaranteesAttribute usato dagli sviluppatori di componenti e librerie di classi per indicare il livello di compatibilità previsto dai consumer delle librerie in più versioni. Indica il livello di garanzia che una versione futura della libreria o del componente non interrompa un client esistente. I client possono quindi usare come ComponentGuaranteesAttribute supporto per progettare le proprie interfacce per garantire la stabilità tra le versioni.

Nota

Common Language Runtime (CLR) non usa questo attributo in alcun modo. Il suo valore consiste nel documentare formalmente l'intento dell'autore del componente. Gli strumenti in fase di compilazione possono anche usare queste dichiarazioni per rilevare errori in fase di compilazione che altrimenti interromperebbero la garanzia dichiarata.

Livelli di compatibilità

ComponentGuaranteesAttribute Supporta i livelli di compatibilità seguenti, rappresentati dai membri dell'enumerazione ComponentGuaranteesOptions :

  • Nessuna compatibilità da versione a versione (ComponentGuaranteesOptions.None). Il client può aspettarsi che le versioni future interrompano il client esistente. Per altre informazioni, vedere la sezione Nessuna compatibilità più avanti in questo articolo.

  • Compatibilità side-by-side da versione a versione (ComponentGuaranteesOptions.SideBySide). Il componente è stato testato per funzionare quando più versioni dell'assembly vengono caricate nello stesso dominio applicazione. In generale, le versioni future possono interrompere la compatibilità. Tuttavia, quando vengono apportate modifiche di rilievo, la versione precedente non viene modificata ma esiste insieme alla nuova versione. L'esecuzione side-by-side è il modo previsto per fare in modo che i client esistenti funzionino quando vengono apportate modifiche di rilievo. Per altre informazioni, vedere la sezione Compatibilità side-by-side più avanti in questo articolo.

  • Compatibilità da versione a versione stabile (ComponentGuaranteesOptions.Stable). Le versioni future non devono interrompere il client e non deve essere necessaria l'esecuzione side-by-side. Tuttavia, se il client è inavvertitamente interrotto, potrebbe essere possibile usare l'esecuzione side-by-side per risolvere il problema. Per altre informazioni, vedere la sezione Compatibilità stabile.

  • Compatibilità da versione a versione di Exchange (ComponentGuaranteesOptions.Exchange). Viene eseguita una cura straordinaria per garantire che le versioni future non interrompano il client. Il client deve usare solo questi tipi nella firma delle interfacce usate per la comunicazione con altri assembly distribuiti indipendentemente l'uno dall'altro. È prevista una sola versione di questi tipi in un determinato dominio applicazione, il che significa che se un client si interrompe, l'esecuzione side-by-side non può risolvere il problema di compatibilità. Per altre informazioni, vedere la sezione Compatibilità dei tipi di Exchange.

Le sezioni seguenti illustrano in modo più dettagliato ogni livello di garanzia.

Nessuna compatibilità

Contrassegnare un componente come ComponentGuaranteesOptions.None indica che il provider non garantisce la compatibilità. I client devono evitare di assumere dipendenze dalle interfacce esposte. Questo livello di compatibilità è utile per i tipi sperimentali o esposti pubblicamente, ma destinati solo ai componenti sempre aggiornati contemporaneamente. None Indica in modo esplicito che questo componente non deve essere utilizzato da componenti esterni.

Compatibilità side-by-side

Contrassegnando un componente come ComponentGuaranteesOptions.SideBySide indica che il componente è stato testato per funzionare quando più versioni dell'assembly vengono caricate nello stesso dominio applicazione. Le modifiche di rilievo sono consentite purché vengano apportate all'assembly con il numero di versione maggiore. I componenti associati a una versione precedente dell'assembly continueranno a essere associati alla versione precedente e altri componenti possono essere associati alla nuova versione. È anche possibile aggiornare un componente dichiarato in SideBySide modo distruttivo modificando la versione precedente.

Compatibilità stabile

Contrassegnando un tipo come ComponentGuaranteesOptions.Stable indica che il tipo deve rimanere stabile tra le versioni. Tuttavia, può anche essere possibile che le versioni side-by-side di un tipo stabile esistano nello stesso dominio applicazione.

I tipi stabili mantengono una barra di compatibilità binaria elevata. Per questo motivo, i provider devono evitare di apportare modifiche di rilievo ai tipi stabili. I tipi di modifiche seguenti sono accettabili:

  • Aggiunta di campi di istanza privata a o rimozione di campi da un tipo, purché non interrompa il formato di serializzazione.
  • Modifica di un tipo non serializzabile in un tipo serializzabile. Non è tuttavia possibile modificare un tipo serializzabile in un tipo non serializzabile.
  • Generazione di eccezioni nuove e più derivate da un metodo.
  • Miglioramento delle prestazioni di un metodo.
  • La modifica dell'intervallo di valori restituiti, purché la modifica non influisca negativamente sulla maggior parte dei client.
  • Correzione di bug gravi, se la motivazione aziendale è elevata e il numero di clienti interessati negativamente è basso.

Poiché non è previsto che le nuove versioni dei componenti stabili interrompano i client esistenti, in genere è necessaria una sola versione di un componente stabile in un dominio applicazione. Tuttavia, questo non è un requisito, perché i tipi stabili non vengono utilizzati come tipi di scambio noti su cui tutti i componenti sono d'accordo. Pertanto, se una nuova versione di un componente stabile interrompe inavvertitamente alcuni componenti e se altri componenti necessitano della nuova versione, potrebbe essere possibile risolvere il problema caricando sia il componente precedente che quello nuovo.

Stable offre una garanzia di compatibilità della versione più forte rispetto a None. È un valore predefinito comune per i componenti con più versioni.

Stable può essere combinato con SideBySide, che indica che il componente non interromperà la compatibilità, ma viene testato per funzionare quando più di una versione viene caricata in un determinato dominio applicazione.

Dopo che un tipo o un metodo è contrassegnato come Stable, può essere aggiornato a Exchange. Non è tuttavia possibile effettuare il downgrade a None.

Compatibilità dei tipi di Exchange

Contrassegnare un tipo come ComponentGuaranteesOptions.Exchange fornisce una garanzia di compatibilità della versione più forte di Stablee deve essere applicato al più stabile di tutti i tipi. Questi tipi devono essere usati per l'interscambio tra componenti compilati in modo indipendente in tutti i limiti dei componenti in entrambi i casi (qualsiasi versione di CLR o qualsiasi versione di un componente o di un'applicazione) e lo spazio (cross-process, cross-CLR in un unico processo, dominio tra applicazioni in un unico CLR). Se viene apportata una modifica di rilievo a un tipo di scambio, è impossibile risolvere il problema caricando più versioni del tipo.

I tipi di scambio devono essere modificati solo quando un problema è molto grave (ad esempio un problema di sicurezza grave) o la probabilità di interruzione è molto bassa (ovvero, se il comportamento è già stato interrotto in modo casuale che il codice non avrebbe potuto prendere una dipendenza da). È possibile apportare i tipi di modifiche seguenti a un tipo di scambio:

  • Aggiungere l'ereditarietà delle nuove definizioni di interfaccia.

  • Aggiungere nuovi metodi privati che implementano i metodi delle nuove definizioni di interfaccia ereditate.

  • Aggiungere nuovi campi statici.

  • Aggiungere nuovi metodi statici.

  • Aggiungere nuovi metodi di istanza non virtuale.

Di seguito sono considerate modifiche di rilievo e non sono consentite per i tipi primitivi:

  • Modifica dei formati di serializzazione. È necessaria la serializzazione a tolleranza di versione.

  • Aggiunta o rimozione di campi di istanza privata. Questo rischio comporta la modifica del formato di serializzazione del tipo e l'interruzione del codice client che usa la reflection.

  • Modifica della serializzabilità di un tipo. Un tipo non serializzabile potrebbe non essere serializzabile e viceversa.

  • Generazione di eccezioni diverse da un metodo .

  • La modifica dell'intervallo dei valori restituiti di un metodo, a meno che la definizione del membro non generi questa possibilità e indichi chiaramente come i client devono gestire valori sconosciuti.

  • Correzione della maggior parte dei bug. I consumer del tipo si basano sul comportamento esistente.

Dopo che un componente, un tipo o un membro è contrassegnato con la Exchange garanzia, non può essere modificato in Stable o None.

In genere, i tipi di scambio sono i tipi di base (ad esempio Int32 e String in .NET) e le interfacce (ad esempio IList<T>, IEnumerable<T>e IComparable<T>) comunemente usate nelle interfacce pubbliche.

I tipi di Exchange possono esporre pubblicamente solo altri tipi contrassegnati anche con Exchange compatibilità. Inoltre, i tipi di scambio non possono dipendere dal comportamento delle API di Windows soggette a modifiche.

Garanzie dei componenti

La tabella seguente indica in che modo le caratteristiche e l'utilizzo di un componente influiscono sulla garanzia di compatibilità.

Caratteristiche dei componenti Exchange Stable Side-by-Side None
Può essere usato nelle interfacce tra componenti che vengono usati in modo indipendente. Y N N N
Può essere usato (privatamente) da un assembly che esegue le versioni in modo indipendente. S Y Y N
Può avere più versioni in un singolo dominio applicazione. N S Y S
Può apportare modifiche di rilievo N N S S
Testata per fare in modo che più versioni dell'assembly possano essere caricate insieme. N N Y N
Può apportare modifiche che causano un'interruzione. N N N Y
Può apportare modifiche di manutenzione non di rilievo molto sicure. S Y Y S

Applicare l'attributo

È possibile applicare a ComponentGuaranteesAttribute un assembly, a un tipo o a un membro del tipo. L'applicazione è gerarchica. Ovvero, per impostazione predefinita, la garanzia definita dalla Guarantees proprietà dell'attributo a livello di assembly definisce la garanzia di tutti i tipi nell'assembly e di tutti i membri in tali tipi. Analogamente, se la garanzia viene applicata al tipo, per impostazione predefinita si applica anche a ogni membro del tipo.

Questa garanzia ereditata può essere sostituita applicando a ComponentGuaranteesAttribute singoli tipi e membri di tipo. Tuttavia, garantisce che l'override dell'impostazione predefinita possa indebolire solo la garanzia; non possono rafforzarlo. Ad esempio, se un assembly è contrassegnato con la None garanzia, i relativi tipi e membri non hanno alcuna garanzia di compatibilità e qualsiasi altra garanzia applicata a tipi o membri nell'assembly viene ignorata.

Testare la garanzia

La Guarantees proprietà restituisce un membro dell'enumerazione ComponentGuaranteesOptions , contrassegnata con l'attributo FlagsAttribute . Ciò significa che è necessario verificare la presenza del flag a cui si è interessati mascherando i flag potenzialmente sconosciuti. Ad esempio, nell'esempio seguente viene verificato se un tipo è contrassegnato come 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

Nell'esempio seguente viene verificato se un tipo è contrassegnato come Stable o 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

Nell'esempio seguente viene contrassegnato None un tipo con un tipo , ovvero né StableExchange.

// 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