Export (0) Print
Expand All

ComponentGuaranteesAttribute Class

Defines the compatibility guarantee of a component, type, or type member that may span multiple versions.

System.Object
  System.Attribute
    System.Runtime.Versioning.ComponentGuaranteesAttribute

Namespace:  System.Runtime.Versioning
Assembly:  mscorlib (in mscorlib.dll)

[AttributeUsageAttribute(AttributeTargets.Assembly|AttributeTargets.Module|AttributeTargets.Class|AttributeTargets.Struct|AttributeTargets.Enum|AttributeTargets.Constructor|AttributeTargets.Method|AttributeTargets.Property|AttributeTargets.Event|AttributeTargets.Interface|AttributeTargets.Delegate, AllowMultiple = false, 
	Inherited = false)]
public sealed class ComponentGuaranteesAttribute : Attribute

The ComponentGuaranteesAttribute type exposes the following members.

  NameDescription
Public methodComponentGuaranteesAttributeInitializes a new instance of the ComponentGuaranteesAttribute class with a value that indicates a library, type, or member's guaranteed level of compatibility across multiple versions.
Top

  NameDescription
Public propertyGuaranteesGets a value that indicates the guaranteed level of compatibility of a library, type, or type member that spans multiple versions.
Public propertyTypeIdWhen implemented in a derived class, gets a unique identifier for this Attribute. (Inherited from Attribute.)
Top

  NameDescription
Public methodEqualsInfrastructure. Returns a value that indicates whether this instance is equal to a specified object. (Inherited from Attribute.)
Public methodGetHashCodeReturns the hash code for this instance. (Inherited from Attribute.)
Public methodGetTypeGets the Type of the current instance. (Inherited from Object.)
Public methodIsDefaultAttributeWhen overridden in a derived class, indicates whether the value of this instance is the default value for the derived class. (Inherited from Attribute.)
Public methodMatchWhen overridden in a derived class, returns a value that indicates whether this instance equals a specified object. (Inherited from Attribute.)
Public methodToStringReturns a string that represents the current object. (Inherited from Object.)
Top

  NameDescription
Explicit interface implemetationPrivate method_Attribute.GetIDsOfNamesMaps a set of names to a corresponding set of dispatch identifiers. (Inherited from Attribute.)
Explicit interface implemetationPrivate method_Attribute.GetTypeInfoRetrieves the type information for an object, which can be used to get the type information for an interface. (Inherited from Attribute.)
Explicit interface implemetationPrivate method_Attribute.GetTypeInfoCountRetrieves the number of type information interfaces that an object provides (either 0 or 1). (Inherited from Attribute.)
Explicit interface implemetationPrivate method_Attribute.InvokeProvides access to properties and methods exposed by an object. (Inherited from Attribute.)
Top

The ComponentGuaranteesAttribute is used by developers of components and class libraries to indicate the level of compatibility that consumers of their libraries can expect across multiple versions. It indicates the level of guarantee that a future version of the library or component will not break an existing client. Clients can then use the ComponentGuaranteesAttribute as an aid in designing their own interfaces to ensure stability across versions.

NoteNote

The common language runtime (CLR) does not use this attribute in any way. Its value lies in formally documenting the intent of the component author. Compile-time tools can also use these declarations to detect compile-time errors that would otherwise break the declared guarantee.

Levels of Compatibility

The ComponentGuaranteesAttribute supports the following levels of compatibility, which are represented by members of the ComponentGuaranteesOptions enumeration:

  • No version-to-version compatibility (ComponentGuaranteesOptions.None). The client can expect that future versions will break the existing client. For more information, see the No Compatibility section later in this topic.

  • Side-by-side version-to-version compatibility (ComponentGuaranteesOptions.SideBySide). The component has been tested to work when more than one version of the assembly is loaded in the same application domain. In general, future versions can break compatibility. However, when breaking changes are made, the old version is not modified but exists alongside the new version. Side-by-side execution is the expected way to make existing clients work when breaking changes are made. For more information, see the Side-by-Side Compatibility section later in this topic.

  • Stable version-to-version compatibility (ComponentGuaranteesOptions.Stable). Future versions should not break the client, and side-by-side execution should not be needed. However, if the client is inadvertently broken, it may be possible to use side-by-side execution to fix the problem. For more information, see the Stable Compatibility section.

  • Exchange version-to-version compatibility (ComponentGuaranteesOptions.Exchange). Extraordinary care is taken to ensure that future versions will not break the client. The client should use only these types in the signature of interfaces that are used for communication with other assemblies that are deployed independently of one another. Only one version of these types is expected to be in a given application domain, which means that if a client breaks, side-by-side execution cannot fix the compatibility problem. For more information, see the Exchange Type Compatibility section.

The following sections discuss each level of guarantee in greater detail.

Marking a component as ComponentGuaranteesOptions.None indicates that the provider makes no guarantees about compatibility. Clients should avoid taking any dependencies on the exposed interfaces. This level of compatibility is useful for types that are experimental or that are publicly exposed but are intended only for components that are always updated at the same time. None explicitly indicates that this component should not be used by external components.

Marking a component as ComponentGuaranteesOptions.SideBySide indicates that the component has been tested to work when more than one version of the assembly is loaded into the same application domain. Breaking changes are allowed as long as they are made to the assembly that has the greater version number. Components that are bound to an old version of the assembly are expected to continue to bind to the old version, and other components can bind to the new version. It is also possible to update a component that is declared to be SideBySide by destructively modifying the old version.

Marking a type as ComponentGuaranteesOptions.Stable indicates that the type should remain stable across versions. However, it may also be possible for side-by-side versions of a stable type to exist in the same application domain.

Stable types maintain a high binary compatibility bar. Because of this, providers should avoid making breaking changes to stable types. The following kinds of changes are acceptable:

  • Adding private instance fields to, or removing fields from, a type, as long as this does not break the serialization format.

  • Changing a non-serializable type to a serializable type. (However, a serializable type cannot be changed to a non-serializable type.)

  • Throwing new, more derived exceptions from a method.

  • Improving the performance of a method.

  • Changing the range of return values, as long as the change does not adversely affect the majority of clients.

  • Fixing serious bugs, if the business justification is high and the number of adversely affected clients is low.

Because new versions of stable components are not expected to break existing clients, generally only one version of a stable component is needed in an application domain. However, this is not a requirement, because stable types are not used as well-known exchange types that all components agree upon. Therefore, if a new version of a stable component does inadvertently break some component, and if other components need the new version, it may be possible to fix the problem by loading both the old and new component.

Stable provides a stronger version compatibility guarantee than None. It is a common default for multi-version components.

Stable can be combined with SideBySide, which states that the component will not break compatibility but is tested to work when more than one version is loaded in a given application domain.

After a type or method is marked as Stable, it can be upgraded to Exchange. However, it cannot be downgraded to None.

Marking a type as ComponentGuaranteesOptions.Exchange provides a stronger version compatibility guarantee than Stable, and should be applied to the most stable of all types. These types are intended to be used for interchange between independently built components across all component boundaries in both time (any version of the CLR or any version of a component or application) and space (cross-process, cross-CLR in one process, cross-application domain in one CLR). If a breaking change is made to an exchange type, it is impossible to fix the issue by loading multiple versions of the type.

Exchange types should be changed only when a problem is very serious (such as a severe security issue) or the probability of breakage is very low (that is, if the behavior was already broken in a random way that code could not have conceivably taken a dependency on). You can make the following kinds of changes to an exchange type:

  • Add inheritance of new interface definitions.

  • Add new private methods that implement the methods of newly inherited interface definitions.

  • Add new static fields.

  • Add new static methods.

  • Add new non-virtual instance methods.

The following are considered breaking changes and are not allowed for primitive types:

  • Changing serialization formats. Version-tolerant serialization is required.

  • Adding or removing private instance fields. This risks changing the serialization format of the type and breaking client code that uses reflection.

  • Changing the serializability of a type. A non-serializable type may not be made serializable, and vice versa.

  • Throwing different exceptions from a method.

  • Changing the range of a method's return values, unless the member definition raises this possibility and clearly indicates how clients should handle unknown values.

  • Fixing most bugs. Consumers of the type will rely on the existing behavior.

After a component, type, or member is marked with the Exchange guarantee, it cannot be changed to either Stable or None.

Typically, exchange types are the basic types (such as Int32 and String in the .NET Framework) and interfaces (such as IList<T>, IEnumerable<T>, and IComparable<T>) that are commonly used in public interfaces.

Exchange types may publicly expose only other types that are also marked with Exchange compatibility. In addition, exchange types cannot depend on the behavior of Windows APIs that are prone to change.

Component Guarantees: A Summary

The following table indicates how a component's characteristics and usage affect its compatibility guarantee.

Component characteristics

Exchange

Stable

Side-by-Side

None

Can be used in interfaces between components that version independently.

Y

N

N

N

Can be used (privately) by an assembly that versions independently.

Y

Y

Y

N

Can have multiple versions in a single application domain.

N

Y

Y

Y

Can make breaking changes

N

N

Y

Y

Tested to make certain multiple versions of the assembly can be loaded together.

N

N

Y

N

Can make breaking changes in place.

N

N

N

Y

Can make very safe non-breaking servicing changes in place.

Y

Y

Y

Y

Applying the Attribute

You can apply the ComponentGuaranteesAttribute to an assembly, a type, or a type member. Its application is hierarchical. That is, by default, the guarantee defined by the Guarantees property of the attribute at the assembly level defines the guarantee of all types in the assembly and all members in those types. Similarly, if the guarantee is applied to the type, by default it also applies to each member of the type.

This inherited guarantee can be overridden by applying the ComponentGuaranteesAttribute to individual types and type members. However, guarantees that override the default can only weaken the guarantee; they cannot strengthen it. For example, if an assembly is marked with the None guarantee, its types and members have no compatibility guarantee, and any other guarantee that is applied to types or members in the assembly is ignored.

Testing the Guarantee

The Guarantees property returns a member of the ComponentGuaranteesOptions enumeration, which is marked with the FlagsAttribute attribute. This means that you should test for the flag that you are interested in by masking away potentially unknown flags. For example, the following example tests whether a type is marked as Stable.

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

The following example tests whether a type is marked as Stable or 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);

The following example tests wither a type is marked as None (that is, neither Stable nor Exchange).

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

.NET Framework

Supported in: 4.5.2, 4.5.1, 4.5, 4

.NET Framework Client Profile

Supported in: 4

Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (Server Core Role not supported), Windows Server 2008 R2 (Server Core Role supported with SP1 or later; Itanium not supported)

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
Show:
© 2014 Microsoft