DoconutExtensions
Service and middleware registration
DoconutExtensions (namespace Doconut.Middleware) is the static class with the three calls every Doconut host makes: one service registration and two middleware registrations.
builder.Services.AddDoconut(options => { /* … */ });
// …
app.UseDoconutResources(); // BEFORE UseDoconut()
app.UseDoconut();AddDoconut
IServiceCollection AddDoconut(this IServiceCollection services, Action<DoconutOptions>? configure = null)Builds the DoconutOptions, validates them fail-fast (see DoconutOptions → Startup validation), and registers the full service graph:
| Service | Lifetime | Role |
|---|---|---|
DoconutOptions | Singleton | The configuration object |
IViewerFactory | Singleton | Maps extensions to format viewers |
IDocumentSessionManager | Singleton | Token → session cache (IMemoryCache is registered too) |
IDoconutLicenseService | Singleton | License loaded once at startup (precedence: LicenseStream → LicenseContent → LicensePath → auto-search) |
PageImageService | Singleton | Page-image pipeline (watermark/rotate/scale/annotations) |
| Document security (access store) | Singleton | Grants for token-to-session binding |
Viewer | Transient | The public open/close facade |
DocumentConverter | Transient | Conversion facade — requires the Converter plugin |
Health check "doconut" | — | Reports license/expiry state through ASP.NET health checks |
Two behaviors worth knowing:
- Converter requires its plugin. Resolving
DocumentConverterwithoutoptions.AddPlugin<ConverterPlugin>()throws:
InvalidOperationException: No IDocumentConverter is registered. Add the converter plugin: options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>().- Plugin entitlement is validated at startup. A missing license, legacy
TRIALfile, or paid license without a registered plugin's capability fails atAddDoconut()time. Temporary/Demo registrations survive their expiry date, while runtime gates revoke the expired capabilities.
The health check integrates with the standard ASP.NET Core mechanism — map it if you want license state on your health endpoint:
app.MapHealthChecks("/health");UseDoconut
IApplicationBuilder UseDoconut(this IApplicationBuilder app)Adds the Doconut page-image middleware. It answers every request carrying a ?token= query parameter — pages, thumbnails, search, annotations, page actions (the full request table is in Core Concepts → How the Viewer Works). When UnsafeMode is false, the document-security layer is wired in automatically before it.
The reference sample routes the widget's requests through a path branch:
app.MapWhen(
ctx => ctx.Request.Path.Value?.EndsWith("DocImage.axd", StringComparison.OrdinalIgnoreCase) == true,
branch => branch.UseDoconut());UseDoconutResources
IApplicationBuilder UseDoconutResources(this IApplicationBuilder app)Serves the embedded JS, CSS, images, and fonts at DoconutOptions.ResourcesPath (default /doconut-res). These are the files that Viewer.ReferenceCss() / ReferenceScripts() emit tags for.
Always call it before UseDoconut(). If the viewer area stays empty and the browser console shows 404s for /doconut-res/..., this call is missing or misplaced.
Ordering recap
app.UseRouting();
app.UseSession(); // required when UnsafeMode = false
app.UseDoconutResources(); // 1st Doconut call
app.UseDoconut(); // 2nd Doconut call (or via a MapWhen branch)Was this page helpful?