Migración a la versión 3.0.0

Hay una serie de cambios importantes entre v2.20.0 y v3.0.0 que pueden requerir cambios en el nivel de origen. Como recordatorio, hay dos tipos de cambios importantes:

  1. Binario: cuando un binario ya no se puede usar como reemplazo
  2. Origen: cuando el origen ya no se compila

Los cambios realizados en la versión 3.0.0 eran una eliminación de obsoleaciones presentes en el SDK durante un tiempo o cambios necesarios por motivos arquitectónicos (especialmente para mejorar la compatibilidad y el recorte de AOT). La mayoría de estos cambios deben estar en el lado del cambio de interrupción binario , al tiempo que admiten la compilación y el comportamiento esperado con el código anterior. Sin embargo, hay algunas chnages de origen que se deben tener en cuenta.

Cambios importantes

Se ha quitado la compatibilidad con .NET Standard 1.3

Ningún destino que todavía sea compatible requiere .NET Standard 1.3 y puede usar .NET Standard 2.0 en su lugar. El proyecto sigue siendo compatible con .NET Framework 3.5+ y cualquier plataforma compatible con .NET Standard 2.0.

Acción necesaria: si usa .NET Standard 1.3, actualice a una versión compatible de .NET.

Las plataformas de destino han cambiado

Para simplificar la creación de paquetes, los TFM creados se han cambiado para algunos de los paquetes. Sin embargo, no debe haber ningún cambio aparente en los usuarios, ya que las plataformas admitidas en general (además de .NET Standard 1.3 indicada anteriormente) siguen siendo las mismas.

Acción necesaria: Ninguno

OpenXmlPart/OpenXmlContainer/OpenXmlPackage ya no tienen constructores públicos

Estos nunca inicializaron el comportamiento correcto y nunca deberían haberse expuesto.

Acción necesaria: use .Create(...) métodos en lugar de constructor.

El marco de trabajo compatible con tipos OpenXML se encuentra ahora en el paquete DocumentFormat.OpenXml.Framework.

A partir de la versión 3.0.0, el marco auxiliar para el SDK de Open XML ahora está dentro de un paquete independiente, DocumentFormat.OpenXml.Framework.

Acción necesaria: si desea trabajar solo OpenXmlPackage con tipos, ya no es necesario incorporar todas las clases estáticas y simplemente puede hacer referencia a la biblioteca de marcos.

System.IO.Packaging ya no se usa directamente

Ha habido problemas con la obtención del comportamiento que necesitamos del espacio de nombres System.IO.Packaging. A partir de v3.0, se usará un nuevo conjunto de interfaces en el DocumentFormat.OpenXml.Packaging espacio de nombres para acceder a las propiedades del paquete.

Nota:

Estos tipos están marcados actualmente como obsoletos, pero solo en el sentido de que nos reservamos el derecho de cambiar su forma por comentarios. Tenga cuidado al usar estos tipos, ya que pueden cambiar en el futuro. En algún momento, quitaremos las obsolescencias y se considerarán API estables. Consulte aquí para obtener más información.

Acción necesaria: si usa OpenXmlPackage.Package, el paquete devuelto ya no es de tipo System.IO.Packaging.Package, sino de DocumentFormat.OpenXml.Packaging.IPackage.

Los métodos de los elementos para agregar elementos secundarios ahora son métodos de extensión

Había una serie de métodos duplicados que agregarían partes de maneras bien definidas. Para consolidar esto, si una parte admite ISupportedRelationship<T>, se pueden escribir métodos de extensión para admitir un comportamiento específico que puede proporcionar esa parte. Los métodos existentes para esto deben volverse a dirigir de forma transparente a los nuevos métodos de extensión tras la compilación.

Acción necesaria: Ninguno

OpenXmlAttribute es ahora una estructura de solo lectura.

Este tipo solía tener captadores y establecedores mutables. Como estructura, esto era fácil de usar de forma incorrecta y debería haberse hecho de solo lectura desde el principio.

Acción necesaria: si espera mutar un OpenXmlAttribute en su lugar, cree uno nuevo en su lugar.

EnumValue<TEnum> ahora contiene structs

A partir de v3.0.0, EnumValue<T> encapsula un tipo personalizado que contiene la información sobre el valor de enumeración. Anteriormente, estos tipos se almacenaban en valores de enumeración en el sistema de tipos de C#, pero requerían reflexión para acceder, lo que provocaba aplicaciones compiladas de AOT muy grandes.

Acción necesaria: hay disponible una superficie de API similar, pero los valores de enumeración expuestos para esto ya no son constantes y no estarán disponibles en algunos escenarios que hubieran estado (es decir, valores de atributo).

Un cambio común que se requiere es que las instrucciones switch ya no funcionan:

switch (theCell.DataType.Value)
{
  case CellValues.SharedString:
    // Handle the case
    break;
}

Se convierte:

if (theCell.DataType.Value == CellValues.SharedString)
{
  // Handle the case
}

OpenXmlElementList es ahora una estructura

OpenXmlElementList es ahora una estructura. Sigue implementando IEnumerable<OpenXmlElement> además de IReadOnlyList<OpenXmlElement> cuando está disponible.

Acción necesaria: dado que se trata de una estructura, los patrones de código que pueden tener un null resultado ahora serán en OpenXmlElementList? su lugar. El compilador marcará las comprobaciones null y el propio valor deberá desencapsarse, por ejemplo:

- OpenXmlElementList? slideIds = part?.Presentation?.SlideIdList?.ChildElements;
+ OpenXmlElementList slideIds = part?.Presentation?.SlideIdList?.ChildElements ?? default;

o

- OpenXmlElementList? slideIds = part?.Presentation?.SlideIdList?.ChildElements;
+ OpenXmlElementList slideIds = (part?.Presentation?.SlideIdList?.ChildElements).GetValueOrDefault();

IdPartPair es ahora una estructura de solo lectura.

Este tipo se usa para enumerar pares dentro de un elemento y ha causado muchas asignaciones innecesarias. Este cambio debe ser transparente tras la recompilación.

Acción necesaria: dado que ahora es una estructura, el código de control null tendrá que actualizarse.

OpenXmlPartReader ya no conoce todos los elementos

En versiones anteriores, OpenXmlPartReader sabía sobre todos los elementos fuertemente tipados. Para reducir el acoplamiento necesario para mejores escenarios de AOT, ahora hemos escrito lectores para paquetes conocidos: WordprocessingDocumentPartReader, SpreadsheetDocumentPartReadery PresentationDocumentPartReader.

Acción necesaria: reemplace el uso de por lectores específicos del OpenXmlPartReader documento si es necesario. Si crea un lector de elementos a partir de un paquete conocido, use los constructores que toman un existente OpenXmlPart que, a continuación, creará los elementos fuertemente tipados esperados.

Se han quitado los atributos de la información de esquema

SchemaAttrAttribute y ChildElementInfoAttribute se han quitado de los tipos y los propios tipos ya no están presentes.

Acción necesaria: si se requieren estos tipos, póngase en contacto con nosotros en GitHub para identificar la mejor manera de avanzar.

Se ha quitado OpenXmlPackage.Close

Esto no hizo nada útil además de llamar a .Dispose(), pero causó confusión sobre cuál debe llamarse. Ahora se quita con la expectativa de llamar a .Dispose(), preferiblemente con el patrón using.

Acción necesaria: quitar la llamada y asegurarse de que el paquete se elimina correctamente

OpenXmlPackage.CanSave es ahora una propiedad de instancia

Esta propiedad solía ser una propiedad estática que dependía del marco. Ahora, puede cambiar la instancia por paquete en función de la configuración y el almacén de respaldo.

Acción necesaria: reemplace el uso de la propiedad estática por la instancia.

Se ha cambiado OpenXmlPackage.PartExtensionProvider

Esta propiedad proporcionaba un diccionario que permitía el acceso para cambiar las extensiones usadas. Ahora está respaldado por .IPartExtensionFeature

Acción necesaria: reemplace el uso por OpenXmlPackage.Features.GetRequired<IPartExtensionFeature>().

Los paquetes con MarkupCompatibilityProcessMode.ProcessAllParts ahora procesan realmente todos los elementos

Anteriormente, había una heurística para minimizar potencialmente el procesamiento si no se había cargado ninguna pieza. Sin embargo, esto hizo que escenarios como los en los que alguien edita manualmente el XML no procesara realmente al guardar. v3.0.0 corrige este comportamiento y procesa toda la parte si se ha optado por ello.

Acción necesaria: si solo desea que se procesen los elementos cargados, cambie a MarkupCompatibilityProcessMode.ProcessLoadedPartsOnly