Класс System.Runtime.Versioning.ComponentGuaranteesAttribute

В этой статье приводятся дополнительные замечания к справочной документации по этому API.

Разработчики ComponentGuaranteesAttribute компонентов и библиотек классов используются для указания уровня совместимости, который потребители своих библиотек могут ожидать в нескольких версиях. Он указывает уровень гарантии того, что будущая версия библиотеки или компонента не прерывает существующий клиент. Затем клиенты могут использовать ComponentGuaranteesAttribute в качестве помощи в разработке собственных интерфейсов, чтобы обеспечить стабильность между версиями.

Примечание.

Среда CLR не использует этот атрибут каким-либо образом. Его значение состоит в формальном документе намерения автора компонента. Средства времени компиляции также могут использовать эти объявления для обнаружения ошибок во время компиляции, которые в противном случае прерывают объявленную гарантию.

Уровни совместимости

Поддерживает ComponentGuaranteesAttribute следующие уровни совместимости, представленные членами ComponentGuaranteesOptions перечисления:

  • Нет совместимости версий с версиями (ComponentGuaranteesOptions.None). Клиент может ожидать, что будущие версии прервают существующий клиент. Дополнительные сведения см . в разделе "Отсутствие совместимости " далее в этой статье.

  • Совместимость между версиями и версиями (ComponentGuaranteesOptions.SideBySide). Компонент протестирован для работы, если в одном домене приложения загружается несколько версий сборки. Как правило, будущие версии могут нарушить совместимость. Однако при внесении критических изменений старая версия не изменяется, но существует вместе с новой версией. Параллельное выполнение — это ожидаемый способ выполнения существующих клиентов при внесении критических изменений. Дополнительные сведения см . в разделе о параллельной совместимости далее в этой статье.

  • Стабильная совместимость версий с версией (ComponentGuaranteesOptions.Stable). Будущие версии не должны прерывать клиент, а параллельное выполнение не должно быть необходимо. Однако если клиент непреднамеренно разбит, возможно, можно использовать параллельное выполнение для устранения проблемы. Дополнительные сведения см. в разделе "Стабильная совместимость ".

  • Совместимость версий и версий Exchange (ComponentGuaranteesOptions.Exchange). Чрезвычайный уход за тем, чтобы гарантировать, что будущие версии не разорвать клиент. Клиент должен использовать только эти типы в сигнатуре интерфейсов, которые используются для взаимодействия с другими сборками, развернутыми независимо друг от друга. Ожидается, что только одна версия этих типов находится в определенном домене приложения, что означает, что если клиент прерывает работу, параллельное выполнение не может устранить проблему совместимости. Дополнительные сведения см. в разделе совместимости типов Exchange.

В следующих разделах подробно рассматриваются все уровни гарантии.

Без совместимости

Пометка компонента, как ComponentGuaranteesOptions.None указывает, что поставщик не гарантирует совместимость. Клиенты должны избегать принятия зависимостей от предоставляемых интерфейсов. Этот уровень совместимости полезен для типов, которые являются экспериментальными или общедоступными, но предназначены только для компонентов, которые всегда обновляются одновременно. None явным образом указывает, что этот компонент не должен использоваться внешними компонентами.

Совместимость параллельно

Пометка компонента, указывающая ComponentGuaranteesOptions.SideBySide , что компонент протестирован для работы при загрузке нескольких версий сборки в один домен приложения. Критические изменения допускаются до тех пор, пока они вносятся в сборку с большим номером версии. Компоненты, привязанные к старой версии сборки, должны продолжать привязываться к старой версии, а другие компоненты могут привязаться к новой версии. Кроме того, можно обновить компонент, объявленный SideBySide как деструктивно изменяющий старую версию.

Стабильная совместимость

Пометка типа, указывающая ComponentGuaranteesOptions.Stable , что тип должен оставаться стабильным в разных версиях. Однако можно также использовать параллельные версии стабильного типа, которые будут существовать в том же домене приложения.

Стабильные типы поддерживают высокий двоичный индикатор совместимости. Из-за этого поставщики должны избегать критических изменений в стабильных типах. Допустимы следующие типы изменений:

  • Добавление полей частного экземпляра или удаление полей из типа, если это не нарушает формат сериализации.
  • Изменение несериализируемого типа на сериализуемый тип. (Однако сериализуемый тип нельзя изменить на несериализируемый тип.)
  • Создание новых, более производных исключений из метода.
  • Повышение производительности метода.
  • Изменение диапазона возвращаемых значений, если изменение не негативно влияет на большинство клиентов.
  • Исправление серьезных ошибок, если бизнес-обоснование является высоким, а количество пострадавших клиентов низко.

Так как новые версии стабильных компонентов не должны прерывать существующие клиенты, обычно в домене приложения требуется только одна версия стабильного компонента. Однако это не является обязательным требованием, так как стабильные типы не используются как известные типы обмена, на которые согласуются все компоненты. Таким образом, если новая версия стабильного компонента непреднамеренно прерывает некоторый компонент, и если другие компоненты нуждаются в новой версии, это может быть возможно, чтобы устранить проблему, загрузив старый и новый компонент.

Stable обеспечивает более надежную гарантию совместимости версий, чем None. Это обычное значение по умолчанию для компонентов с несколькими версиями.

Stable можно сочетать с SideBySideтем, что компонент не прерывает совместимость, но проверяется для работы при загрузке нескольких версий в определенном домене приложения.

После того как тип или метод помечается как Stable, его можно обновить до Exchange. Однако его нельзя уменьшить до None.

Совместимость типов Exchange

Маркировка типа как ComponentGuaranteesOptions.Exchange обеспечивает более надежную гарантию совместимости версий, чем Stableи следует применять к наиболее стабильной из всех типов. Эти типы предназначены для обмена между независимыми встроенными компонентами во всех границах компонентов в оба времени (любая версия среды CLR или любая версия компонента или приложения) и пробел (кросспроцессный, кросс-CLR в одном процессе, между доменами приложений в одном среде CLR). Если критическое изменение выполняется в тип exchange, невозможно устранить проблему, загрузив несколько версий типа.

Типы Exchange должны быть изменены только в том случае, если проблема очень серьезна (например, серьезная проблема безопасности) или вероятность разрыва очень низка (то есть, если поведение уже было нарушено случайным образом, что код не мог задуматься о зависимости). Вы можете внести следующие изменения в тип exchange:

  • Добавьте наследование новых определений интерфейса.

  • Добавьте новые частные методы, реализующие методы недавно унаследованных определений интерфейса.

  • Добавьте новые статические поля.

  • Добавьте новые статические методы.

  • Добавьте новые методы, отличные от виртуальных экземпляров.

Ниже рассматриваются критические изменения и не допускаются для примитивных типов:

  • Изменение форматов сериализации. Требуется терпимая сериализация версий.

  • Добавление или удаление полей частного экземпляра. Это рискует изменить формат сериализации типа и критический клиентский код, который использует отражение.

  • Изменение сериализации типа. Несериализируемый тип может быть не сериализуем, и наоборот.

  • Создание различных исключений из метода.

  • Изменение диапазона возвращаемых значений метода, если определение члена не вызывает эту возможность и четко указывает, как клиенты должны обрабатывать неизвестные значения.

  • Исправление большинства ошибок. Потребители типа будут полагаться на существующее поведение.

После того как компонент, тип или член помечается гарантиейExchange, его нельзя изменить на либоNoneStable.

Как правило, типы exchange — это базовые типы (например Int32String , в .NET) и интерфейсы (например IList<T>, , IEnumerable<T>и IComparable<T>) которые обычно используются в общедоступных интерфейсах.

Типы Exchange могут публично предоставлять только другие типы, которые также помечены совместимостью Exchange . Кроме того, типы обмена не могут зависеть от поведения API Windows, подверженных изменению.

Гарантии компонентов

В следующей таблице показано, как характеристики и использование компонента влияют на ее гарантию совместимости.

Характеристики компонентов Exchange Стабильный Параллельно нет
Можно использовать в интерфейсах между компонентами независимой версии. Y N N N
Можно использовать (приватно) сборкой, которая независимо используется. Y Y Y N
Может иметь несколько версий в одном домене приложения. N Y Y Y
Может вносить критические изменения N N Y Y
Протестировано, чтобы убедиться, что несколько версий сборки можно загрузить вместе. N N Y N
Может вносить критические изменения на месте. N N N Y
Может вносить очень безопасные неисключаемые изменения в обслуживание. Y Y Y Y

Применение атрибута

Можно применить к ComponentGuaranteesAttribute сборке, типу или члену типа. Его приложение является иерархическим. То есть по умолчанию гарантия, определяемая Guarantees свойством атрибута на уровне сборки, определяет гарантию всех типов в сборке и всех членов этих типов. Аналогичным образом, если гарантия применяется к типу, по умолчанию она также применяется к каждому элементу типа.

Эта наследуемая гарантия может быть переопределена путем применения ComponentGuaranteesAttribute отдельных типов и элементов типа. Однако гарантирует, что переопределение по умолчанию может ослабить только гарантию; они не могут укрепить его. Например, если сборка помечена None гарантией, его типы и члены не имеют гарантии совместимости, и любая другая гарантия, применяемая к типам или элементам в сборке, игнорируется.

Проверка гарантии

Свойство Guarantees возвращает элемент ComponentGuaranteesOptions перечисления, помеченный атрибутом FlagsAttribute . Это означает, что вы должны проверить флаг, который вас интересует, маскируя потенциально неизвестные флаги. Например, в следующем примере проверяется, помечен ли тип как 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

В следующем примере проверяется, помечен ли тип как Stable или 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

В следующем примере тесты с типом помечены как None (т. е. ни 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