Skip to content

PdfAPI.SyncFusionCore architecture

PdfAPI.SyncFusionCore is the Syncfusion-backed PDF engine of the IT.CoreServices.PDFAPI repository: it converts source documents of several formats to PDF/PDF-A, extracts page ranges, merges documents, flattens form fields, and registers the Syncfusion runtime license. It is a class library with no program entry point — the repository's top-level Web API project (PdfAPI) is the consumer that dispatches to it — and it performs no database access and no authorization work.

Responsibilities

  • Dispatch a conversion request to the converter matching the source file extension (ConverterFactory).
  • Convert eight source formats (Word, Excel, RTF, plain text, image, TIFF, HTML, PDF) to PDF or PDF/A via format-specific converters built on the Syncfusion SDK.
  • Extract selected page ranges from a source PDF into a new PDF (PdfExtractor), including ascending/descending ranges and open-ended stop pages.
  • Merge multiple document ranges into a single PDF, optionally at PDF/A conformance (PdfMerger).
  • Inspect and flatten AcroForm fields in a PDF, and build ApplicationExceptionDetail diagnostic records for callers (PdfHelper).
  • Register the Syncfusion runtime license once per process (LicenseHelper).

Component boundaries

  • Dispatch (ConverterFactory): extension-to-converter routing; recursion for the text → PDF/A path; returns a non-throwing result for an unmatched extension.
  • Conversion template (BaseConverter): cross-cutting conversion concerns — stream disposal, a per-format ConfigureConverter hook, stopwatch timing, exception capture, PdfResult assembly, and processor stamping. Note: this type is physically compiled into PdfAPI.SyncFusionCore but declares the namespace PdfAPI.Core.Convert, so consumers that reference only PdfAPI.Core cannot see it.
  • Conversion implementations (WordConverter, ExcelConverter, RtfConverter, TxtConverter, ImageConverter, TiffConverter, HtmlConverter, PdfConverter): format-specific byte-array production via the Syncfusion API; each implements ConvertItem/ConfigureConverter under the BaseConverter template.
  • Page composition (PdfExtractor, PdfMerger): page-range extraction and multi-document merge, both with optional PDF/A conformance. PdfMerger is the library's only constructor- injected type (IEnvironmentService, ILogService), constructed directly by the caller (new PdfMerger(environmentService, logService)), not via a DI container.
  • Utilities (PdfHelper, LicenseHelper): AcroForm inspection/flattening, exception-detail construction, and Syncfusion license registration.
  • Contract boundary (PdfAPI.Core): the library's only internal dependency, supplying the request/result contracts (ConvertRequest, MergeRequest, ExtractPagesRequest, PdfRequest, PdfResult, PdfOptions, Document, DocumentRange, PageRange, and related enums).

Interaction model

  • All inputs arrive as in-memory byte[] (via ConvertRequest.File, Document.File) and all outputs are produced as byte[] wrapped into a PdfAPI.Core.Document; the library never writes to disk itself, except that PdfMerger calls range.Document.Load(), which may read a range's source file from FilePath on disk when in-memory bytes are absent.
  • ConverterFactory.Convert is the single entry point for format conversion: it normalizes the file extension, constructs the matching converter, and delegates to BaseConverter.Convert, which in turn calls the converter's ConvertItem. A successful text conversion is recursively resubmitted through the PDF path so PDF/A can be applied uniformly.
  • PdfExtractor.Extract is called both directly by callers and internally by PdfMerger when a document range is partial or spans multiple page ranges.
  • PdfMerger.Merge loads each document range, extracts subsets where needed via PdfExtractor.Extract, merges the resulting documents with Syncfusion.Pdf.PdfDocument.Merge, and optionally performs a post-merge PDF/A upgrade pass; failures in that upgrade pass are logged via ILogService (SAIF.Framework.Core) rather than thrown.
  • Failure handling is asymmetric by design: BaseConverter.Convert catches every exception and returns a failed PdfResult, whereas PdfExtractor.Extract and the primary merge path let exceptions propagate to the caller.
  • LicenseHelper.LicenseSyncfusion() must be invoked once per process before any Syncfusion API use; in this repository it is called from PdfAPI\Global.asax.cs (Application_Start).
  • The library is consumed both as a project reference by the PdfAPI Web API (SyncfusionPdfService, PdfService) and, packaged as the Pdf.Local.Client NuGet package (together with PdfAPI.Core), by external NuGet consumers.

Architecture diagram

The following diagram shows high-level component interactions.

flowchart LR
  API["PdfAPI (ASP.NET Web API)<br>SyncfusionPdfService, PdfService"] --> SFC["PdfAPI.SyncFusionCore<br>ConverterFactory, PdfMerger,<br>PdfExtractor, PdfHelper"]
  SFC --> Core["PdfAPI.Core<br>request/result contracts"]
  SFC --> SF["Syncfusion 18.3<br>Pdf / DocToPDF / ExcelToPdf /<br>HtmlToPdf / Licensing"]
  SFC --> FW["SAIF.Framework.Core + Common<br>ILogService, IEnvironmentService"]
  API --> Core

Sequence diagram

The following diagram shows the primary request/response sequence for a document conversion.

sequenceDiagram
    participant Client as PdfAPI (SyncfusionPdfService)
    participant Factory as ConverterFactory
    participant Base as BaseConverter
    participant SF as Syncfusion SDK
    Client->>Factory: Convert(ConvertRequest)
    Factory->>Base: new matching converter (e.g. WordConverter), Convert(stream, request)
    Base->>SF: ConvertItem(stream, request)
    SF-->>Base: converted bytes
    Base-->>Factory: PdfResult (Status, Elapsed, Document)
    Factory-->>Client: PdfResult

Design constraints

  • BaseConverter declares namespace PdfAPI.Core.Convert while being compiled into PdfAPI.SyncFusionCore, so consumers referencing only PdfAPI.Core cannot resolve it — likely the result of a prior move between projects that left the namespace unchanged.*
  • ConfigureConverter(PdfOptions) is an abstract per-format hook that every one of the eight converters implements as an empty method, making the hook currently inert.
  • ConverterFactory.Convert is a simple factory with a switch; adding a new format requires editing the switch, as there is no registry or discovery by ConversionType.
  • Static-utility classes (ConverterFactory, PdfExtractor, PdfHelper, LicenseHelper) expose only static methods but are declared as ordinary (non-static) public classes and can be instantiated.
  • PdfMerger is the only type with constructor-injected dependencies (IEnvironmentService, ILogService); it is constructed directly with new PdfMerger(environmentService, logService) by the caller rather than resolved through Autofac.
  • The library reads no application configuration itself (no ConfigurationManager/AppSettings usage); all behavior is driven by the PdfAPI.Core request objects passed in by the caller. Its app.config carries only assembly binding redirects, whose targets (18.3460.0.35) are lower than the Syncfusion/RestSharp versions actually referenced — the file appears stale relative to the package set.*
  • The library performs no authentication or authorization work; access control for these operations is entirely the responsibility of the hosting PdfAPI application.
  • Six referenced packages (Autofac, FluentValidation, log4net, RestSharp, SAIF.Web.API.Clients, SAIF.HashUtil) have no corresponding usage in this library's source and appear to be carried over from a shared reference set.*
  • The Pdf.Local.Client nuspec pins Syncfusion dependencies at 17.4.0.46 while the project builds against 18.3.0.53, and declares an unused iTextSharp 5.5.11 dependency; it also omits the SAIF.Framework.Core/SAIF.Framework.Common dependencies required at run time.

Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.

Sources

  • PdfApi.SyncFusionCore\PdfAPI.SyncFusionCore.csproj
  • PdfApi.SyncFusionCore\packages.config
  • PdfApi.SyncFusionCore\app.config
  • PdfApi.SyncFusionCore\LicenseHelper.cs
  • PdfApi.SyncFusionCore\PdfHelper.cs
  • PdfApi.SyncFusionCore\Convert\BaseConverter.cs
  • PdfApi.SyncFusionCore\Convert\ConverterFactory.cs
  • PdfApi.SyncFusionCore\Convert\ExcelConverter.cs
  • PdfApi.SyncFusionCore\Convert\HtmlConverter.cs
  • PdfApi.SyncFusionCore\Convert\ImageConverter.cs
  • PdfApi.SyncFusionCore\Convert\PdfConverter.cs
  • PdfApi.SyncFusionCore\Convert\RtfConverter.cs
  • PdfApi.SyncFusionCore\Convert\TiffConverter.cs
  • PdfApi.SyncFusionCore\Convert\TxtConverter.cs
  • PdfApi.SyncFusionCore\Convert\WordConverter.cs
  • PdfApi.SyncFusionCore\Extract\PdfExtractor.cs
  • PdfApi.SyncFusionCore\Merge\PdfMerger.cs
  • PdfAPI\Services\Syncfusion\SyncfusionPdfService.cs
  • PdfAPI\Services\PdfService.cs
  • PdfAPI\Global.asax.cs