Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo se proporcionan comentarios adicionales a la documentación de referencia de esta API.
ComponentGuaranteesAttribute Lo usan los desarrolladores de componentes y bibliotecas de clases para indicar el nivel de compatibilidad que los consumidores de sus bibliotecas pueden esperar en varias versiones. Indica el nivel de garantía de que una versión futura de la biblioteca o componente no interrumpirá un cliente existente. Después, los clientes pueden usar ComponentGuaranteesAttribute como ayuda para diseñar sus propias interfaces para garantizar la estabilidad entre versiones.
Nota:
Common Language Runtime (CLR) no usa este atributo de ninguna manera. Su valor radica en documentar formalmente la intención del autor del componente. Las herramientas en tiempo de compilación también pueden usar estas declaraciones para detectar errores en tiempo de compilación que interrumpirían la garantía declarada.
Niveles de compatibilidad
ComponentGuaranteesAttribute admite los siguientes niveles de compatibilidad, que se representan mediante miembros de la ComponentGuaranteesOptions enumeración:
No hay compatibilidad de versión a versión (ComponentGuaranteesOptions.None). El cliente puede esperar que las versiones futuras rompan el cliente existente. Para obtener más información, consulte la sección Sin compatibilidad más adelante en este artículo.
Compatibilidad de versión a versión en paralelo (ComponentGuaranteesOptions.SideBySide). El componente se ha probado para funcionar cuando se carga más de una versión del ensamblado en el mismo dominio de aplicación. En general, las versiones futuras pueden interrumpir la compatibilidad. Sin embargo, cuando se realizan cambios importantes, la versión anterior no se modifica, pero existe junto con la nueva versión. La ejecución en paralelo es la forma esperada de hacer que los clientes existentes funcionen cuando se realizan cambios importantes. Para obtener más información, consulte la sección Compatibilidad en paralelo más adelante en este artículo.
Compatibilidad estable de versión a versión (ComponentGuaranteesOptions.Stable). Las versiones futuras no deben interrumpir el cliente y no debe ser necesaria la ejecución en paralelo. Sin embargo, si el cliente se interrumpe accidentalmente, es posible usar la ejecución en paralelo para corregir el problema. Para obtener más información, consulte la sección Compatibilidad estable .
Compatibilidad de versiones a versión de Exchange (ComponentGuaranteesOptions.Exchange). Se tiene especial cuidado para asegurarse de que las versiones futuras no afectarán negativamente al cliente. El cliente solo debe usar estos tipos en la firma de interfaces que se usan para la comunicación con otros ensamblados que se implementan independientemente entre sí. Solo se espera que una versión de estos tipos esté en un dominio de aplicación determinado, lo que significa que si un cliente se interrumpe, la ejecución en paralelo no puede corregir el problema de compatibilidad. Para obtener más información, consulte la sección Compatibilidad de tipos de Exchange .
En las secciones siguientes se describe cada nivel de garantía con mayor detalle.
Sin compatibilidad
Marcar un componente como ComponentGuaranteesOptions.None indica que el proveedor no garantiza la compatibilidad. Los clientes deben evitar depender de las interfaces expuestas. Este nivel de compatibilidad es útil para los tipos que son experimentales o que se exponen públicamente, pero están diseñados solo para componentes que siempre se actualizan al mismo tiempo. None indica explícitamente que los componentes externos no deben usar este componente.
Compatibilidad en paralelo
Marcar un componente como ComponentGuaranteesOptions.SideBySide indica que el componente se ha probado para funcionar cuando se carga más de una versión del ensamblado en el mismo dominio de aplicación. Los cambios disruptivos se permiten siempre y cuando se realicen en el ensamblado que tenga el número de versión mayor. Se espera que los componentes enlazados a una versión anterior del ensamblado sigan enlazando a la versión anterior y otros componentes pueden enlazar a la nueva versión. También es posible actualizar un componente declarado como SideBySide modificando de forma destructiva la versión anterior.
Compatibilidad estable
Marcar un tipo como ComponentGuaranteesOptions.Stable indica que el tipo debe permanecer estable entre versiones. Sin embargo, también puede ser posible que existan versiones en paralelo de un tipo estable en el mismo dominio de aplicación.
Los tipos estables mantienen una barra de compatibilidad binaria alta. Por este motivo, los proveedores deben evitar realizar cambios importantes en tipos estables. Los siguientes tipos de cambios son aceptables:
- Agregar campos de instancia privada a, o quitar campos de, un tipo, siempre y cuando esto no interrumpa el formato de serialización.
- Cambiar un tipo no serializable a un tipo serializable. (Sin embargo, un tipo serializable no se puede cambiar a un tipo no serializable).
- Lanzar nuevas excepciones más derivadas desde un método.
- Mejora del rendimiento de un método.
- Cambiar el intervalo de valores devueltos, siempre y cuando el cambio no afecte negativamente a la mayoría de los clientes.
- Corregir errores graves, si la justificación comercial es alta y el número de clientes afectados negativamente es bajo.
Dado que no se espera que las nuevas versiones de componentes estables interrumpan los clientes existentes, normalmente solo se necesita una versión de un componente estable en un dominio de aplicación. Sin embargo, esto no es un requisito, ya que los tipos estables no se usan como tipos de intercambio bien conocidos en los que todos los componentes están de acuerdo. Por lo tanto, si una nueva versión de un componente estable interrumpe accidentalmente algún componente y, si otros componentes necesitan la nueva versión, puede ser posible corregir el problema cargando el componente antiguo y nuevo.
Stable proporciona una garantía de compatibilidad de versiones más sólida que None. Es un valor predeterminado común para los componentes de varias versiones.
Stable se puede combinar con SideBySide, que indica que el componente no interrumpirá la compatibilidad, pero se prueba para funcionar cuando se carga más de una versión en un dominio de aplicación determinado.
Después de marcar un tipo o método como Stable, se puede actualizar a Exchange. Sin embargo, no se puede degradar a None.
Compatibilidad de tipos de Exchange
Marcar un tipo como ComponentGuaranteesOptions.Exchange proporciona una garantía de compatibilidad de versiones más sólida que Stable, y se debe aplicar al más estable de todos los tipos. Estos tipos están diseñados para usarse en el intercambio entre componentes construidos de forma independiente, superando todas las barreras de componentes tanto temporales (cualquier versión de CLR o de un componente o aplicación) como espaciales (entre procesos, entre distintos CLR en un proceso, y entre dominios de aplicación en un mismo CLR). Si se realiza un cambio importante en un tipo de intercambio, es imposible corregir el problema cargando varias versiones del tipo.
Los tipos de Exchange solo deben cambiarse cuando un problema es extremadamente grave (como un serio problema de seguridad) o cuando la probabilidad de que ocurra una interrupción es muy baja, es decir, si el comportamiento ya estaba roto de una manera aleatoria que el código no podría haber concebido tomar como dependencia. Puede realizar los siguientes tipos de cambios en un tipo de intercambio:
Agregue la herencia de nuevas definiciones de interfaz.
Agregue nuevos métodos privados que implementen los métodos de las definiciones de interfaz recién heredadas.
Agregue nuevos campos estáticos.
Agregue nuevos métodos estáticos.
Agregue nuevos métodos de instancia que no son virtuales.
Se consideran cambios disruptivos y no se permiten para tipos primitivos los siguientes:
Cambiar los formatos de serialización. Se requiere una serialización tolerante a versiones.
Agregar o quitar campos de instancia privada. Esto corre el riesgo de cambiar el formato de serialización del tipo y romper el código de cliente que utiliza la reflexión.
Cambiar la serializabilidad de un tipo. Un tipo no serializable no puede hacerse serializable, y viceversa.
Lanzar excepciones diferentes desde un método.
Cambiar el intervalo de valores devueltos de un método, a menos que la definición de miembro genere esta posibilidad e indique claramente cómo los clientes deben controlar valores desconocidos.
Corregir la mayoría de los errores. Los consumidores de este tipo se basarán en el comportamiento ya establecido.
Después de que un componente, tipo o miembro se marque con la garantía Exchange, no se puede cambiar a Stable ni a None.
Normalmente, los tipos de intercambio son los tipos básicos (como Int32 y String en .NET) e interfaces (como IList<T>, IEnumerable<T>y IComparable<T>) que se usan normalmente en interfaces públicas.
Los tipos de Exchange solo pueden exponer públicamente otros tipos que también estén marcados con compatibilidad mediante Exchange. Además, los tipos de intercambio no pueden depender del comportamiento de las API de Windows que son propensas a cambiar.
Garantías de componentes
En la tabla siguiente se indica cómo afectan las características y el uso de un componente a su garantía de compatibilidad.
| Características de componentes | Intercambio | Estable | Lado a lado | Ninguno |
|---|---|---|---|---|
| Se puede usar en interfaces entre los componentes cuyas versiones son independientes. | Y | N | N | N |
| Puede ser utilizado (de forma privada) por un ensamblado que versiona de manera independiente. | Y | Y | Y | N |
| Puede tener varias versiones en un solo dominio de aplicación. | N | Y | Y | Y |
| Puede realizar cambios importantes | N | N | Y | Y |
| Se han probado para asegurar que se puedan cargar varias versiones del ensamblado simultáneamente. | N | N | Y | N |
| Puede realizar cambios importantes en su lugar. | N | N | N | Y |
| Puede realizar cambios de mantenimiento muy seguros que no alteren el funcionamiento existente. | Y | Y | Y | Y |
Aplicación del atributo
Puede aplicar el ComponentGuaranteesAttribute a un ensamblado, un tipo o un miembro de tipo. Su aplicación es jerárquica. Es decir, de forma predeterminada, la garantía definida por la Guarantees propiedad del atributo en el nivel de ensamblado define la garantía de todos los tipos del ensamblado y de todos los miembros de esos tipos. De forma similar, si la garantía se aplica al tipo, de forma predeterminada también se aplica a cada miembro del tipo.
Esta garantía heredada se puede invalidar aplicando el ComponentGuaranteesAttribute a tipos individuales y miembros de tipos. Sin embargo, las garantías que anulan el valor predeterminado solo pueden debilitar la garantía; no pueden fortalecerla. Por ejemplo, si un ensamblado está marcado con la None garantía, sus tipos y miembros no tienen ninguna garantía de compatibilidad, y se omite cualquier otra garantía que se aplique a los tipos o miembros del ensamblado.
Prueba de la garantía
La Guarantees propiedad devuelve un miembro de la ComponentGuaranteesOptions enumeración, que está marcado con el FlagsAttribute atributo . Esto significa que debe probar la marca que le interesa enmascarando las marcas potencialmente desconocidas. Por ejemplo, en el ejemplo siguiente se comprueba si un 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
En el ejemplo siguiente se comprueba si un tipo está marcado como Stable o 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
En el ejemplo siguiente se comprueba si un tipo está marcado como None (es decir, ni StableExchange).
// 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