Sistema de Plugins

Extiende el visor con plugins

El núcleo de Doconut se mantiene ligero; la funcionalidad opcional se entrega como plugins — paquetes NuGet separados que aportan visores o servicios y se activan mediante su licencia. Esta página explica el modelo de registro, cómo funciona la restricción de licencias en tiempo de ejecución y cómo conectar su propio visor.

Este modelo es nuevo en esta versión. La biblioteca .NET Standard anterior no tenía registro de plugins: la conversión vivía en el propio visor y las licencias de plugins se instalaban mediante llamadas estáticas Viewer.SetLicensePlugin(...). Ninguno es un mecanismo de registro aquí.

Registro de un plugin

Cada paquete de plugin expone una clase de plugin. La registra una vez, al iniciar:

csharp
builder.Services.AddDoconut(options =>
{
    options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
    options.AddPlugin<Doconut.Plugins.Dicom.DicomPlugin>();
});

AddPlugin<TPlugin>() instancia el plugin e invoca su callback Register contra el registro de plugins mantenido en DoconutOptions. Todo lo que un plugin aporta está etiquetado con la capacidad requerida del plugin. AddDoconut() valida los plugins registrados inmediatamente: una licencia faltante, un archivo legacy TRIAL, o una licencia paga sin la capacidad provocan que el inicio falle con InvalidOperationException. Un registro Temporal/Demo se conserva después de la expiración, pero sus capacidades en tiempo de ejecución se revocan tras la fecha de expiración.

El contrato

Un plugin implementa una interfaz deliberadamente pequeña:

csharp
public interface IDoconutPlugin
{
    string Name { get; }                          // p.ej. "Doconut DICOM Viewer"
    LicenseCapability RequiredCapability { get; } // la puerta de licencia
    void Register(IDoconutPluginBuilder builder); // contribuir con visores/servicios
}

Dentro de Register, el constructor acepta dos tipos de contribuciones:

  • builder.RegisterViewer(".dcm", () => new DicomViewer()) — un visor para una extensión de archivo,
  • builder.RegisterService<TContract>(() => …) — un servicio tipado que otras partes del pipeline pueden buscar.

Capacidades y restricción

Las capacidades son las unidades de licencia. Converter y Dicom se entregan como plugins opcionales; Search y Annotation son funciones incorporadas restringidas de la misma manera. El visor base no es una capacidad — es el prerrequisito, expuesto como IsViewerLicensed en el servicio de licencias.

La validación al iniciar normalmente impide que un plugin sin licencia entre en el pipeline de solicitudes. La fábrica de visores también aplica dos reglas defensivas en tiempo de ejecución, que son relevantes si los derechos cambian después del inicio:

  • El plugin sobrescribe un visor incorporado (un plugin reclama una extensión que también maneja el registro incorporado): con la capacidad licenciada, el visor del plugin prevalece; sin ella, Doconut retrocede silenciosamente al visor incorporado. Los usuarios aún ven su documento — simplemente no obtienen la función del plugin.
  • Formato solo de plugin (p. ej., .dcm — DICOM no tiene visor incorporado): sin la capacidad la llamada de apertura falla de forma crítica:
text
LicenseException: This document type requires the 'Dicom' plugin license.

Una licencia Temporal activa otorga todas las capacidades (con visualización base limpia y sin marcas de agua). Esta es una fuente clásica de sorpresas al lanzar: registrar los mismos plugins con una licencia comprada que omite una de sus capacidades hace que AddDoconut() falle durante el inicio. Compare IsCapabilityGranted(...) con su plan antes de desplegar. Por otro lado: con ninguna licencia, no se otorga nada — una licencia faltante no es una licencia Temporal.

La misma restricción aparece del lado del cliente: Viewer.ReferenceScripts() y ReferenceCss() emiten los paquetes de script/estilo para las funciones restringidas por licencia (búsqueda, anotación, …) solo cuando la licencia las habilita, de modo que la UI del widget permanezca consistente con lo que el servidor realmente hará.

Mapa de funciones y complementos

La UI del producto usa “plugin” como una etiqueta amplia de función, pero el registro del servidor difiere:

FunciónCómo se habilitaCapacidadContribuye
AnotaciónIntegrado en el visor; incluye recursos de anotaciónAnnotationAutoría en el navegador, persistencia de sesión y exportaciones incrustadas
BúsquedaIntegrado en visores de formatos buscables; incluye recursos de búsqueda y habilita extracción donde sea necesarioSearchÍndice de texto nativo, resaltados y navegación de resultados
ConvertidorInstale Doconut.NETStandard.Converter y registre ConverterPluginConverterServicio de conversión C# y widget web opcional
DICOMInstale Doconut.NETStandard.Dicom y registre DicomPluginDicomVisualización de imágenes médicas para .dcm y .ima

La Anotación y la Búsqueda normal no utilizan AddPlugin<TPlugin>(); sus paquetes se emiten solo cuando la licencia otorga la capacidad correspondiente. Convertidor y DICOM son las implementaciones optativas IDoconutPlugin lanzadas para este conjunto de documentación.

Los artefactos .NET Standard aprobados contienen Doconut.NETStandard.Converter y Doconut.NETStandard.Dicom en la misma versión que el paquete central.

Paquetes de complementos lanzados

ComplementoPaqueteCapacidadContribuye
ConvertidorDoconut.NETStandard.ConverterConverterCapacidad de conversión de documentos
DICOMDoconut.NETStandard.DicomDicomVisualización de imágenes médicas (.dcm — formato solo de plugin)

Cada uno tiene una página dedicada bajo Complementos con su configuración y uso.

Visores personalizados — su propio manejador de formato

Puede conectar un visor al pipeline sin escribir un paquete de plugin, directamente desde Program.cs:

csharp
builder.Services.AddDoconut(options =>
{
    options.RegisterViewer(
        ".myext",
        () => new MyCustomViewer(),               // implementa IFormatViewer
        () => new ImageConfig { ImageResolution = 150 }); // configuración predeterminada opcional
});

Los visores personalizados tienen precedencia sobre todo — tanto los incorporados como los plugins — y no están restringidos por licencia (son su código). La fábrica recurre a un ImageConfig cuando no proporciona una configuración predeterminada.

Conclusiones

  • Los plugins se registran explícitamente y su LicenseCapability se valida durante AddDoconut() — una autorización faltante o insuficiente que no sea temporal falla rápidamente.
  • Los plugins de estilo sobrescritura se degradan de forma elegante; los formatos solo de plugin fallan con un LicenseException.
  • Una licencia Temporal activa desbloquea todo; la producción desbloquea lo que compró. Verifique con IDoconutLicenseService antes de lanzar.

¿Fue útil esta página?