Миграция на версию 3.0.0
Существует ряд критических изменений между версиями 2.20.0 и 3.0.0, которые могут потребовать изменения на уровне источника. Напомним, что существует два типа критических изменений:
- Двоичный файл: если двоичный файл больше не может использоваться в качестве замены.
- Источник: когда источник больше не компилируется
Изменения, внесенные в версию 3.0.0, были либо удалены в пакете SDK на некоторое время, либо изменения, необходимые для архитектуры (в первую очередь для улучшения поддержки AOT и обрезки). Большинство из этих изменений должны быть на стороне двоичных критических изменений, но по-прежнему поддерживают компиляцию и ожидаемое поведение с предыдущим кодом. Тем не менее, есть несколько источников критических фрагментов, о которых следует знать.
Критические изменения
Поддержка .NET Standard 1.3 прекращена
Ни для каких целевых объектов по-прежнему не требуется .NET Standard 1.3. Вместо этого можно использовать .NET Standard 2.0. Проект по-прежнему поддерживает платформа .NET Framework 3.5 и любую платформу, поддерживаемую .NET Standard 2.0.
Необходимое действие. При использовании .NET Standard 1.3 обновите до поддерживаемой версии .NET.
Целевые платформы изменились
Чтобы упростить создание пакетов, созданные TFM были изменены для некоторых пакетов. Тем не менее, не должно быть явных изменений для пользователей, так как общие поддерживаемые платформы (помимо .NET Standard 1.3, указанные выше) остаются прежними.
Необходимое действие: нет
OpenXmlPart/OpenXmlContainer/OpenXmlPackage больше не имеют открытых конструкторов
Они никогда не инициализировали правильное поведение и никогда не должны были быть предоставлены.
Необходимое действие: используйте .Create(...)
методы, а не конструктор.
Поддержка платформы для типов OpenXML теперь находится в пакете DocumentFormat.OpenXml.Framework.
Начиная с версии 3.0.0, вспомогательная платформа для пакета SDK Open XML теперь находится в автономном пакете DocumentFormat.OpenXml.Framework.
Необходимое действие. Если вы хотите использовать только OpenXmlPackage
типы, вам больше не нужно добавлять все статические классы и можно просто ссылаться на библиотеку платформы.
System.IO.Packaging больше не используется напрямую
Возникли проблемы с получением необходимого поведения из пространства имен System.IO.Packaging. Начиная с версии 3.0 для доступа к свойствам DocumentFormat.OpenXml.Packaging
пакета будет использоваться новый набор интерфейсов в пространстве имен.
Примечание.
В настоящее время эти типы помечены как устаревшие, но только в том смысле, что мы оставляем за собой право изменять их форму за отзыв. Пожалуйста, будьте осторожны используйте эти типы, так как они могут измениться в будущем. В какой-то момент мы удалим ограничения, и они будут считаться стабильными API. Дополнительные сведения см. здесь .
Необходимое действие. При использовании OpenXmlPackage.Package
возвращается пакет больше не типа System.IO.Packaging.Package
, а .DocumentFormat.OpenXml.Packaging.IPackage
Методы в частях для добавления дочерних частей теперь являются методами расширения
Существует ряд повторяющихся методов, которые будут добавлять части четко определенным образом. Чтобы консолидировать это, если часть поддерживает ISupportedRelationship<T>
, методы расширения могут быть записаны для поддержки определенного поведения, которое может обеспечить часть. Существующие методы для этого должны быть прозрачно перенацеливать на новые методы расширения после компиляции.
Необходимое действие: нет
OpenXmlAttribute теперь является структурой только для чтения.
Этот тип используется для использования изменяемых элементов получения и наборов. Как структуру, это было легко неправильно, и должно было быть сделано только чтение с самого начала.
Необходимое действие. Если ожидается изменить OpenXmlAttribute на месте, создайте новый.
EnumValue<TEnum> теперь содержит структуры
Начиная с версии 3.0.0, EnumValue<T>
заключает в оболочку пользовательский тип, содержащий сведения о значении перечисления. Ранее эти типы хранились в значениях перечисления в системе типов C#, но для доступа требовалось отражение, что приводило к очень большим приложениям, скомпилированным AOT.
Необходимое действие. Аналогичная область API доступна, однако доступные значения перечисления для этого значения больше не являются константами и не будут доступны в нескольких сценариях (т. е. значения атрибутов).
Обычное изменение, которое требуется, заключается в том, что операторы switch больше не работают:
switch (theCell.DataType.Value)
{
case CellValues.SharedString:
// Handle the case
break;
}
Становится:
if (theCell.DataType.Value == CellValues.SharedString)
{
// Handle the case
}
OpenXmlElementList теперь является структурой
OpenXmlElementList теперь является структурой. Он по-прежнему реализует IEnumerable<OpenXmlElement>
в дополнение к, IReadOnlyList<OpenXmlElement>
если доступно.
Необходимое действие. Так как это структура, вместо нее будут OpenXmlElementList?
шаблоны кода, которые могут иметь null
результат. Компилятор помечает проверки NULL, а само значение необходимо будет распутать, например:
- OpenXmlElementList? slideIds = part?.Presentation?.SlideIdList?.ChildElements;
+ OpenXmlElementList slideIds = part?.Presentation?.SlideIdList?.ChildElements ?? default;
или
- OpenXmlElementList? slideIds = part?.Presentation?.SlideIdList?.ChildElements;
+ OpenXmlElementList slideIds = (part?.Presentation?.SlideIdList?.ChildElements).GetValueOrDefault();
IdPartPair теперь является структурой только для чтения
Этот тип используется для перечисления пар в части и вызывает много ненужных выделений. Это изменение должно быть прозрачным после повторной компиляции.
Необходимое действие. Так как теперь это структура, необходимо обновить код обработки null.
OpenXmlPartReader больше не знает обо всех частях
В предыдущих версиях знал OpenXmlPartReader обо всех строго типизированных части. Чтобы уменьшить взаимозависимость, необходимую для более совершенных сценариев AOT, теперь у нас есть типизированные средства чтения для известных пакетов: WordprocessingDocumentPartReader
, SpreadsheetDocumentPartReader
и PresentationDocumentPartReader
.
Необходимое действие. При необходимости замените использование средствами чтения для конкретного OpenXmlPartReader
документа. При создании средства чтения частей из известного пакета используйте конструкторы, которые принимают существующие OpenXmlPart
, которые затем создают ожидаемые строго типизированные части.
Атрибуты для сведений о схеме удалены
SchemaAttrAttribute
и ChildElementInfoAttribute
были удалены из типов, а сами типы больше не присутствуют.
Необходимые действия. Если эти типы были необходимы, обратитесь к нам на GitHub , чтобы определить оптимальный вариант для вас.
OpenXmlPackage.Close удален
Это не повлекло ничего полезного, кроме вызова .Dispose()
, но вызвало путаницу по поводу того, какой вызов должен быть вызван. Теперь эта функция удаляется с ожиданием вызова .Dispose()
, предпочтительно с помощью шаблона использования.
Необходимое действие: удалите вызов и убедитесь, что пакет удален должным образом
OpenXmlPackage.CanSave теперь является свойством экземпляра
Это свойство использовалось как статическое свойство, зависящее от платформы. Теперь он может изменяться для каждого экземпляра пакета в зависимости от параметров и резервного хранилища.
Необходимое действие. Замените использование статического свойства экземпляром.
OpenXmlPackage.PartExtensionProvider изменен
Это свойство предоставляет словарь, разрешающий доступ к изменению используемых расширений. Теперь это поддерживается IPartExtensionFeature
.
Необходимое действие: замените использование на OpenXmlPackage.Features.GetRequired<IPartExtensionFeature>()
.
Пакеты с MarkupCompatibilityProcessMode.ProcessAllParts теперь фактически обрабатывают все части
Ранее существовала эвристика, которая может свести к минимуму обработку, если никакие части не были загружены. Однако это приводило к сценариям, например сценариям, в которых кто-то вручную редактировал XML-код, чтобы фактически не обрабатываться после сохранения. Версия 3.0.0 исправляет это поведение и обрабатывает все части, если это было сделано.
Необходимое действие. Если требуется обрабатывать только загруженные части, измените на MarkupCompatibilityProcessMode.ProcessLoadedPartsOnly