DoconutHost
The composition root for System.Web
DoconutHost (namespace Doconut) is a static class that owns Doconut's services for the whole worker process. ASP.NET Core applications build those services into the framework's own container; classic ASP.NET has no container, so DoconutHost builds one and keeps it. The DocImage.axd handler and the resource module resolve everything they need from it, and so does your code.
| Member | Purpose |
|---|---|
static void Initialize(Action<DoconutOptions>? configure = null, Action<IServiceCollection>? configureServices = null) | Builds the services — once |
static IServiceProvider Services { get; } | The built container |
static bool IsInitialized { get; } | true once Initialize has run |
static void Shutdown() | Stops background work and disposes the container |
Initialize
Call it from Application_Start in Global.asax.cs:
// Global.asax.cs, Application_Start - once per worker process. A second call is a no-op:
// the first call's options win.
Doconut.DoconutHost.Initialize(
options =>
{
options.LicensePath = HostingEnvironment.MapPath("~/wwwroot/Doconut.Viewer.lic");
},
services =>
{
// Optional. Runs after Doconut's own registrations and before the container is built,
// so it can add services or replace one Doconut registered.
services.AddMemoryCache();
});configurereceives the DoconutOptions: license, security switches, plugins, widgets.configureServicesis optional. It runs after Doconut has registered its own services and before the container is built, so it can add services —AddDoconutDistributedfor a web farm is the usual one — or replace a registration Doconut made.
The first call wins. Initialize is idempotent: a second call returns immediately, and neither of its delegates runs. That keeps a duplicated Application_Start harmless, but it also means configuration cannot be changed by calling Initialize again — recycle the application pool instead.
An exception thrown here — a plugin without a license, invalid options, an incomplete farm configuration — happens inside Application_Start. ASP.NET then answers every request with an empty 500, and the exception is recorded only in the Windows event log (Application log, source ASP.NET).
Services and IsInitialized
System.Web has no constructor injection for controllers, pages, or handlers, so resolve Doconut's services where you use them:
// System.Web has no constructor injection: resolve Doconut services where you use them.
var viewer = Doconut.DoconutHost.Services.GetRequiredService<Viewer>();
// Registered only when the Converter plugin is (see the plugin page).
var converter = Doconut.DoconutHost.Services.GetRequiredService<DocumentConverter>();Services throws InvalidOperationException (DoconutHost.Initialize must be called in Application_Start (Global.asax) before any Doconut request is served.) when read before Initialize. Code that may run earlier — a module, a static constructor — can check IsInitialized first.
What your code typically resolves:
| Service | Lifetime | Role |
|---|---|---|
Viewer | Transient | Open, close, annotations, resource helpers — see Viewer |
DocumentConverter | Transient | Conversion — registered only with the Converter plugin |
IDoconutLicenseService | Singleton | The loaded license and its capabilities — see Licensing |
DoconutOptions | Singleton | The options passed to Initialize |
HealthCheckService | Singleton | Runs the "doconut" health check (below) |
Resolve from DoconutHost.Services, never from a container of your own. Registering Doconut into another container builds a second, separate set of services that the handler and the module never see: documents opened through it are unknown to DocImage.axd.
Shutdown
// Global.asax.cs, Application_End - stops background work and disposes the container.
// Safe to call twice, and safe when Initialize never ran.
Doconut.DoconutHost.Shutdown();Shutdown stops Doconut's background work (used by the distributed mode) and disposes the container. It is safe to call twice, and safe when Initialize never ran — for example when the application pool recycles before the first request.
Health check
Doconut registers a health check named "doconut" that reports the license state. Classic ASP.NET has no health-check endpoint of its own, so expose it from a controller:
// GET /Health - Doconut registers a "doconut" health check that reports the license state:
// Healthy (valid), Degraded (trial or no license file), Unhealthy (expired).
public async Task<ActionResult> Index()
{
var health = Doconut.DoconutHost.Services.GetRequiredService<HealthCheckService>();
HealthReport report = await health.CheckHealthAsync();
Response.StatusCode = report.Status == HealthStatus.Unhealthy ? 503 : 200;
return Content(report.Status.ToString(), "text/plain");
}| Status | Meaning |
|---|---|
Healthy | A valid license is loaded |
Degraded | Trial, or no license file found |
Unhealthy | The license has expired |
The ASP.NET Core extension methods
The package also contains UseDoconut() and UseDoconutResources(), the ASP.NET Core pipeline extensions, because it shares its code with the ASP.NET Core packages. On this package both are marked [Obsolete] and are not used: a System.Web application has no request pipeline to add them to. Their replacements are the two Web.config registrations from Installation:
| ASP.NET Core | .NET Framework 4.7.2 |
|---|---|
builder.Services.AddDoconut(...) | DoconutHost.Initialize(...) in Application_Start |
app.UseDoconut() | Doconut.DocImageHandler on DocImage.axd in Web.config |
app.UseDoconutResources() | Doconut.DoconutResourceModule in Web.config |
| Constructor injection | DoconutHost.Services.GetRequiredService<T>() |
| Host shutdown | DoconutHost.Shutdown() in Application_End |
Byla tato stránka užitečná?