Compartilhar via


Funcionalidades personalizadas do SDK

As funcionalidades no SDK Open XML estão disponíveis a partir da v2.14.0 que permite que o comportamento e o estado estejam contidos no documento ou parte e personalizados sem reimplementar o pacote ou parte que contém. Isto é acedido através Features da propriedade em pacotes, peças e elementos.

Esta é uma implementação do padrão de estratégia que facilita a substituição de comportamentos de imediato. É modelado após as funcionalidades do pedido no ASP.NET Core.

Herança de funcionalidades

Os pacotes, as peças e os elementos têm a sua própria coleção de funcionalidades. No entanto, também herdarão a parte que contém e o pacote, se estiver disponível.

Para realçar isto, veja o caso de teste abaixo:

OpenXmlPackage package = /* Create a package */;

var packageFeature = new PrivateFeature();
package.Features.Set<PrivateFeature>(packageFeature);

var part = package.GetPartById("existingPart");
Assert.Same(part.Features.GetRequired<PrivateFeature>(), package.Features.GetRequired<PrivateFeature>());

part.Features.Set<PrivateFeature>(new());
Assert.NotSame(part.Features.GetRequired<PrivateFeature>(), package.Features.GetRequired<PrivateFeature>());


private sealed class PrivateFeature
{
}

Observação

A coleção de funcionalidades nos elementos é só de leitura. Isto deve-se a problemas de memória se for tornado gravável. Se for necessário, contacte-nos https://github.com/dotnet/open-xml-sdk para nos informar sobre o seu cenário.

Visualizar Funcionalidades Registadas

As implementações in-box do IFeatureCollection fornecem uma vista de depuração útil para que possa ver que funcionalidades estão disponíveis e quais são as respetivas propriedades/campos:

Vista de Depuração de Funcionalidades

Funcionalidades Disponíveis

As funcionalidades atualmente disponíveis são descritas abaixo e em que âmbito estão disponíveis:

IDisposableFeature

Esta funcionalidade permite registar ações que têm de ser executadas quando um pacote ou uma peça é destruído ou eliminado:

OpenXmlPackage package = GetSomePackage();
package.Features.Get<IDisposableFeature>().Register(() => /* Some action that is called when the package is disposed */);

OpenXmlPart part = GetSomePart();
part.Features.Get<IDisposableFeature>().Register(() => /* Some action that is called when the part is removed or closed */);

Os pacotes e as peças terão as suas próprias implementações desta funcionalidade. Os elementos irão obter a funcionalidade para a respetiva parte de contenção, se disponível.

IPackageEventsFeature

Esta funcionalidade permite receber notificações de eventos de quando um pacote é alterado:

OpenXmlPackage package = GetSomePackage();
package.TryAddPackageEventsFeature();

var feature = package.Features.GetRequired<IPackageEventsFeature>();

Observação

Pode haver alturas em que o pacote é alterado, mas um evento não é acionado. Nem todas as áreas foram identificadas onde faria sentido gerar um evento. Se encontrar um, submeta um problema.

IPartEventsFeature

Esta funcionalidade permite receber notificações de eventos de quando um evento está a ser criado. Esta é uma funcionalidade que é adicionada à parte ou ao pacote:

OpenXmlPart part = GetSomePackage();
package.AddPartEventsFeature();

var feature = part.Features.GetRequired<IPartEventsFeature>();

Geralmente, suponha que pode haver uma implementação singleton para os eventos e verifique se a parte é a parte correta.

Observação

Pode haver alturas em que a peça é alterada, mas um evento não é acionado. Nem todas as áreas foram identificadas onde faria sentido gerar um evento. Se encontrar um, submeta um problema.

IPartRootEventsFeature

Esta funcionalidade permite receber notificações de eventos de quando uma parte raiz está a ser modificada/carregada/criada/etc. Esta é uma funcionalidade que é adicionada à funcionalidade de nível de peça:

OpenXmlPart part = GetSomePart();
part.AddPartRootEventsFeature();

var feature = part.Features.GetRequired<IPartRootEventsFeature>();

Geralmente, suponha que pode haver uma implementação singleton para os eventos e verifique se a parte é a parte correta.

Observação

Pode haver alturas em que a raiz da peça é alterada, mas um evento não é acionado. Nem todas as áreas foram identificadas onde faria sentido gerar um evento. Se encontrar um, submeta um problema.

IRandomNumberGeneratorFeature

Esta funcionalidade permite que um serviço partilhado gere números aleatórios e preencha uma matriz.

IParagraphIdGeneratorFeature

Esta funcionalidade permite a população e o controlo de elementos que contêm IDs de parágrafo. Por predefinição, isto irá garantir a exclusividade dos valores e garantir que os valores existentes são válidos de acordo com as restrições da norma. Para utilizar esta funcionalidade:

WordprocessingDocument document = CreateWordDocument();
document.TryAddParagraphIdFeature();

var part = doc.AddMainDocumentPart();
var body = new Body();
part.Document = new Document(body);

var p = new Paragraph();
body.AddChild(p); // After adding p.ParagraphId will be set to a unique, valid value

Esta funcionalidade também pode ser utilizada para garantir a exclusividade entre vários documentos com uma ligeira alteração:

using var doc1 = CreateDocument1();
using var doc2 = CreateDocument2();

var shared = doc1
    .AddSharedParagraphIdFeature()
    .Add(doc2);

// Add item to doc1
var part1 = doc1.AddMainDocumentPart();
var body1 = new Body();
var p1 = new Paragraph();
part1.Document = new Document(body1);
body1.AddChild(p1);

// Add item with same ID to doc2
var part2 = doc2.AddMainDocumentPart();
var body2 = new Body();
var p2 = new Paragraph { ParagraphId = p1.ParagraphId };
part2.Document = new Document(body2);
body2.AddChild(p2);

// Assert
Assert.NotEqual(p1.ParagraphId, p2.ParagraphId);
Assert.Equal(2, shared.Count);