Muonroi.Pdf.Enterprise 1.0.7

dotnet add package Muonroi.Pdf.Enterprise --version 1.0.7
                    
NuGet\Install-Package Muonroi.Pdf.Enterprise -Version 1.0.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Muonroi.Pdf.Enterprise" Version="1.0.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Muonroi.Pdf.Enterprise" Version="1.0.7" />
                    
Directory.Packages.props
<PackageReference Include="Muonroi.Pdf.Enterprise" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Muonroi.Pdf.Enterprise --version 1.0.7
                    
#r "nuget: Muonroi.Pdf.Enterprise, 1.0.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Muonroi.Pdf.Enterprise@1.0.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Muonroi.Pdf.Enterprise&version=1.0.7
                    
Install as a Cake Addin
#tool nuget:?package=Muonroi.Pdf.Enterprise&version=1.0.7
                    
Install as a Cake Tool

Muonroi.Pdf.Enterprise

Enterprise-tier extensions for Muonroi.Pdf: per-tenant quota metering, license-backed capability gates, an HTTP template registry client, polling hot-reload, and an SSIM visual-quality scorer.

NuGet License: Commercial

Muonroi.Pdf.Enterprise sits on top of the OSS Muonroi.Pdf engine and adds capabilities that require a commercial activation proof. It decorates IMPdfService with a metering wrapper that records per-tenant PdfRendersPerDay quota via ITenantQuotaTracker, replaces the no-op feature gate with a governance-backed LicenseFeatureGate, and ships an HTTP client for the Muonroi PDF template registry together with a transport-agnostic polling hot-reload service. A pure-managed SSIM scorer is included for visual-regression quality gates. The package has a one-way dependency on the OSS engine — the OSS engine has zero awareness of this package.

Installation

dotnet add package Muonroi.Pdf.Enterprise --prerelease

Quick Start

Call order matters: AddPdf must run before AddPdfEnterprise, and AddMEnterpriseGovernance must run before both (it registers ILicenseGuard).

using Muonroi.Pdf.Extensions;

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

// 1. OSS PDF engine — registers IMPdfService (MPdfService) via TryAddSingleton.
builder.Services.AddPdf(builder.Configuration);

// 2. Governance layer — registers ILicenseGuard (required by LicenseFeatureGate).
builder.Services.AddMEnterpriseGovernance(builder.Configuration);

// 3. Enterprise decorator — replaces IMPdfService with EnterprisePdfServiceWrapper
//    (quota metering) and registers LicenseFeatureGate as IFeatureGate.
builder.Services.AddPdfEnterprise();

For development / OSS environments where no license activation is needed, skip AddPdfEnterprise and register the no-op gate directly:

// dev / OSS: all capability keys are always allowed; metering is skipped.
builder.Services.AddSingleton(AlwaysAllowFeatureGate.Instance);

Guard a feature in any service:

public class MyService(IFeatureGate gate, IMPdfService pdf)
{
    public async Task<byte[]> RenderWithRegistryAsync(string html, CancellationToken ct)
    {
        // Throws FeatureNotLicensedException if pdf.registry is not in the activation proof.
        gate.EnsureFeatureOrThrow(CapabilityKeys.PdfRegistry);

        (byte[] bytes, _) = await pdf.RenderToBytesAsync(html, new PdfRenderOptions(), ct);
        return bytes;
    }
}

Features

  • Per-tenant quota meteringEnterprisePdfServiceWrapper decorates IMPdfService and increments QuotaType.PdfRendersPerDay via ITenantQuotaTracker after every render. Metering failures are caught, logged, and swallowed so the render result is always returned.
  • License-backed capability gateLicenseFeatureGate delegates to ILicenseGuard.HasFeature, which reads the RSA-verified ActivationProof.Features[] supplied by the governance layer.
  • HTTP template registry clientHttpPdfTemplateRegistry fetches template descriptors and version payloads from the control-plane REST API (GET /api/v1/pdf-templates/{id} and /versions/{version}). Uses the named HttpClient "PdfTemplateRegistry".
  • Polling hot-reloadPdfTemplateHotReload polls a configured list of template IDs via IMPdfTemplateRegistry.LookupAsync and notifies an IAsyncObserver<TemplateChange> whenever a version changes or a template disappears. Works against any registry implementation; no push transport required.
  • SSIM visual-quality scorerSsimScorer.Compare computes mean structural similarity (Wang/Bovik 2004, Rec.709 luma) between two interleaved 8-bit RGB pixel buffers. Returns 1.0 for identical buffers; use as a canary gate threshold.
  • Capability key constantsCapabilityKeys defines pdf.designer, pdf.registry, and pdf.canary as typed constants for use with IFeatureGate.

Configuration

DI registration

// Register the named HttpClient the registry resolves from the factory.
builder.Services.AddHttpClient(PdfTemplateRegistryOptions.HttpClientName, client =>
{
    client.BaseAddress = new Uri("https://control-plane.example.com/");
});

// Register HttpPdfTemplateRegistry as IMPdfTemplateRegistry.
builder.Services.AddSingleton<PdfTemplateRegistryOptions>(new PdfTemplateRegistryOptions
{
    AccessTokenFactory = async ct => await tokenProvider.GetTokenAsync(ct)
});
builder.Services.AddSingleton<IMPdfTemplateRegistry, HttpPdfTemplateRegistry>();

Hot-reload

var options = new PdfTemplateHotReloadOptions
{
    PollInterval = TimeSpan.FromSeconds(30),   // default: 30 s
    TemplateIds  = ["invoice-v2", "receipt-v1"]
};

// PdfTemplateHotReload.StartAsync is the loop entry point; wrap in a hosted service.
var hotReload = new PdfTemplateHotReload(registry, myObserver, options);
_ = Task.Run(() => hotReload.StartAsync(appLifetime.ApplicationStopping));

Options reference

Type Property Default Purpose
PdfTemplateRegistryOptions HttpClientName (const) "PdfTemplateRegistry" Named HttpClient key
PdfTemplateRegistryOptions AccessTokenFactory null (no auth) Per-request bearer token factory
PdfTemplateHotReloadOptions PollInterval 30 s How often tracked templates are re-checked
PdfTemplateHotReloadOptions TemplateIds [] (idle) Template identifiers to watch

API Reference

Type Purpose
IFeatureGate Contract for capability checks (IsEnabled, EnsureFeatureOrThrow)
FeatureNotLicensedException Thrown by EnsureFeatureOrThrow when a capability is not licensed
CapabilityKeys String constants pdf.designer, pdf.registry, pdf.canary
AlwaysAllowFeatureGate No-op gate for OSS/dev — every capability returns true
LicenseFeatureGate Production gate backed by ILicenseGuard (registered by AddPdfEnterprise)
EnterprisePdfServiceWrapper IMPdfService decorator that records per-tenant quota after each render
IMPdfTemplateRegistry Client contract: LookupAsync, ResolveAsync, SubscribeAsync
HttpPdfTemplateRegistry REST implementation of IMPdfTemplateRegistry
PdfTemplateRegistryOptions Configuration for HttpPdfTemplateRegistry
PdfTemplateHotReload Polling-based hot-reload over any IMPdfTemplateRegistry
PdfTemplateHotReloadOptions Configuration for PdfTemplateHotReload
IMPdfTemplateHotReload Contract implemented by PdfTemplateHotReload
IAsyncObserver<T> Async observer contract used by registry subscription and hot-reload
TemplateDescriptor Summary record: TemplateId, Name, LatestVersion, Tags
TemplateVersion Full record with Content payload and PublishedAt timestamp
TemplateChange Change notification: TemplateId, NewVersion, ChangeKind
TemplateChangeKind Updated or Deleted
SsimScorer Static SSIM scorer: Compare(rgbA, rgbB, width, height) → double

Samples

  • Quickstart.Pdf.Advanced — ASP.NET Core API demonstrating AlwaysAllowFeatureGate, CapabilityKeys, SsimScorer, and IMPdfTemplateRegistry alongside the OSS PDF engine and the design-system template provider.

Compatibility

  • Target framework: net8.0
  • License: Commercial — requires activation. See LICENSE-COMMERCIAL.
  • Muonroi.Pdf — OSS HTML/CSS-to-PDF engine; must be registered before this package
  • Muonroi.Pdf.AbstractionsIMPdfService, PdfRenderOptions, and PdfRenderResult contracts shared by both layers
  • Muonroi.Governance.Enterprise — provides ILicenseGuard and AddMEnterpriseGovernance; required before calling AddPdfEnterprise

License

Commercial license — requires a valid Muonroi activation proof. Contact leanhphi1706@gmail.com or see LICENSE-COMMERCIAL for terms.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.7 80 6/22/2026
1.0.0-alpha.16 57 6/22/2026