---
title: DI and middleware extension methods
description: "Index of every AddPennington/UsePennington/Run* extension method across the referenced Pennington packages."
canonical_url: https://usepennington.net/reference/host/extensions/
sidecar_url: https://usepennington.net/reference/host/extensions.md
content_hash: sha256:869f4064a7d57ec966bfd180ae5eecb6303a2ca665a47c623f8fbc577b930f6b
tokens: 3821
uid: reference.host.extensions
reading_time_minutes: 2
---

Reference
# DI and middleware extension methods

Index of every AddPennington/UsePennington/Run* extension method across the referenced Pennington packages.

 
The list of public extension methods Pennington exposes for wiring the library into an ASP.NET Core host — `Add*` (DI registration), `Use*` (middleware and endpoints), and `Run*` (host entry points). Grouped below by receiver type; each method is declared in an `*Extensions` static class under its owning feature namespace.

 
## `IServiceCollection` extensions

 
DI registration entry points. The three composition roots and the options record each configures:

 
 - [AddPennington](https://usepennington.net/reference/api/pennington-extensions.md) — [PenningtonOptions](https://usepennington.net/reference/api/pennington-options.md)
 - [AddDocSite](https://usepennington.net/reference/api/doc-site-service-extensions.md) — [DocSiteOptions](https://usepennington.net/reference/api/doc-site-options.md)
 - [AddBlogSite](https://usepennington.net/reference/api/blog-site-service-extensions.md) — [BlogSiteOptions](https://usepennington.net/reference/api/blog-site-options.md)
 
 
The full set follows, each tagged with its owning package.

 
`AddApiMetadataFromCompiledAssembly` `IServiceCollection AddApiMetadataFromCompiledAssembly(this IServiceCollection services, Action<CompiledAssemblyApiOptions> configure)` 
Package `Pennington.ApiMetadata.Reflection`

Convenience overload: registers under the `"default"` name for sites documenting a single library.
`AddApiMetadataFromCompiledAssembly` `IServiceCollection AddApiMetadataFromCompiledAssembly(this IServiceCollection services, string name, Action<CompiledAssemblyApiOptions> configure)` 
Package `Pennington.ApiMetadata.Reflection`

Registers `CompiledAssemblyApiMetadataProvider` as a keyed `IApiMetadataProvider` under `name`. Call once per library you want to document — each call builds its own `MetadataLoadContext` and xmldoc index scoped to the supplied `AssemblyDirectories`. The shared `IXmlDocParser` / `IXmlDocHtmlRenderer` services are registered once (idempotent).
`AddApiReference` `IServiceCollection AddApiReference(this IServiceCollection services, string name, Action<ApiReferenceRegistrationOptions> configure)` 
Package `Pennington.DocSite.Api`

Registers one named API-reference tree. Call once per library you want to document. Each call pairs with a matching `AddApiMetadataFrom*(name, …)` provider registration and publishes its type pages at the configured `RoutePrefix`.
`AddBlogSite` `IServiceCollection AddBlogSite(this IServiceCollection services, Func<BlogSiteOptions> configureOptions)` 
Package `Pennington.BlogSite`

Registers BlogSite services with the provided options.
`AddDataDirectory<TItem>` `IServiceCollection AddDataDirectory<TItem>(this IServiceCollection services, string name, string path)` 
Package `Pennington`

Registers every `.yml`, `.yaml`, and `.json` file in `path` as a single aggregated `IReadOnlyList` accessible through `IDataFiles` under the lookup key `name`. Each file contributes one record, or several when its root is an array; files are ordered by name. Edits, additions, and removals in the directory invalidate the cached value so the next read returns the fresh content.
`AddDataFile<T>` `IServiceCollection AddDataFile<T>(this IServiceCollection services, string name, string path)` 
Package `Pennington`

Registers `path` as a data file accessible through `IDataFiles` under the lookup key `name`. Format is inferred from the file extension (`.yml`, `.yaml`, `.json`). Edits to the file invalidate the cached value so the next read returns the fresh content.
`AddDocSite` `IServiceCollection AddDocSite(this IServiceCollection services, Func<DocSiteOptions> configureOptions)` 
Package `Pennington.DocSite`

Registers DocSite services with the provided options.
`AddFileWatched<T>` `IServiceCollection AddFileWatched<T>(this IServiceCollection services)` 
Package `Pennington`

Register a concrete service whose instance is managed by `FileWatchDependencyFactory`.
`AddFileWatched<TService, TImplementation>` `IServiceCollection AddFileWatched<TService, TImplementation>(this IServiceCollection services)` 
Package `Pennington`

Register a service whose instance is managed by `FileWatchDependencyFactory`. The factory (singleton) recreates the instance when the implementation's `OnFileChanged` returns `Recreate`. The service (transient) always returns the current instance from the factory.
`AddHead` `IServiceCollection AddHead(this IServiceCollection services)` 
Package `Pennington`

Registers the head composition rewriter. Inert until at least one `IHeadContributor` is also registered, so adding this on its own leaves head output byte-identical.
`AddHeadContributor<T>` `IServiceCollection AddHeadContributor<T>(this IServiceCollection services)` 
Package `Pennington`

Registers a single head contributor. Transient so contributors capturing a file-watched dependency (e.g. the content registry) pick up the current instance per request.
`AddLlmsSubtree` `IServiceCollection AddLlmsSubtree(this IServiceCollection services, LlmsSubtree subtree)` 
Package `Pennington`

Registers a `LlmsSubtree` so all leaves under `RoutePrefix` get split out into a dedicated `{RoutePrefix}llms.txt`. Multiple registrations are allowed; programmatic registrations override `_meta.yml`-discovered subtrees with the same prefix.
`AddMonorailCss` `IServiceCollection AddMonorailCss(this IServiceCollection services, Func<IServiceProvider, MonorailCssOptions> optionFactory)` 
Package `Pennington.MonorailCss`

Registers MonorailCSS services and the runtime class-discovery pipeline. With no configuration, the discovery pipeline force-loads every non-BCL assembly the app references, scans each one's IL, watches the project's source files in development, and loads `wwwroot/app.css` as the source CSS prefix when present. The CSS endpoint served by `UseMonorailCss` regenerates whenever the class set changes.
`AddPennington` `IServiceCollection AddPennington(this IServiceCollection services, Action<PenningtonOptions> configure)` 
Package `Pennington`

Register all Pennington services.
`AddPenningtonBook` `IServiceCollection AddPenningtonBook(this IServiceCollection services, Action<BookOptions> configure)` 
Package `Pennington.Book`

Adds PDF book generation: a per-locale book per `BookDefinition` (or one whole-site book when none are configured), served on demand at `/pdf/{slug}.pdf` in dev and emitted into the static build. Registers an `IDownloadLinkProvider` a host's chrome can advertise.
`AddTaxonomy<TFrontMatter, TKey>` `IServiceCollection AddTaxonomy<TFrontMatter, TKey>(this IServiceCollection services, Action<TaxonomyOptions<TFrontMatter, TKey>> configure)` 
Package `Pennington`

Registers a `TaxonomyContentService` configured by `configure`. Multiple `AddTaxonomy` calls with the same `TFrontMatter`/`TKey` pair coexist as long as each uses a distinct `BaseUrl`.
`AddTranslationAudit` `IServiceCollection AddTranslationAudit(this IServiceCollection services, Action<TranslationAuditOptions> configure)` 
Package `Pennington.TranslationAudit`

Register `TranslationAuditor` as an `IBuildAuditor`. Diagnostics land in the dev overlay (per-page) and in the build report (site-wide) automatically.
`AddTreeSitter` `IServiceCollection AddTreeSitter(this IServiceCollection services, Action<TreeSitterOptions> configure)` 
Package `Pennington.TreeSitter`

Adds tree-sitter based multi-language code-fragment extraction — the `:symbol` fence modifier. Services are registered only when `ContentRoot` is configured.
`AddWordBreak` `IServiceCollection AddWordBreak(this IServiceCollection services, Action<WordBreakOptions> configure)` 
Package `Pennington`

Registers `WordBreakHtmlRewriter` in the shared HTML rewriting pipeline, so long identifiers in the configured elements get `<wbr>` break opportunities without an extra DOM parse.
`AddYamlContext` `IServiceCollection AddYamlContext(this IServiceCollection services, YamlSerializerContext context)` 
Package `Pennington`

Register a source-generated `YamlSerializerContext` so the types it covers deserialize without reflection (NativeAOT/trim-friendly). Types not covered by any registered context fall back to reflection. Satellite templates call this for their own front-matter records; end users call it for theirs.
`ReplaceContentRenderer<TOld, TNew>` `IServiceCollection ReplaceContentRenderer<TOld, TNew>(this IServiceCollection services)` 
Package `Pennington`

Replaces every registered `IContentRenderer` with `TNew`, resolved through DI as a transient. The `TOld` type parameter documents the renderer being swapped out — it is informational and unused at runtime, but lets the call site read as "replace TOld with TNew".
`ReplaceContentRenderer<TOld, TNew>` `IServiceCollection ReplaceContentRenderer<TOld, TNew>(this IServiceCollection services, Func<IServiceProvider, TNew> factory)` 
Package `Pennington`

Replaces every registered `IContentRenderer` with one produced by `factory`. Use this overload when the new renderer takes ctor arguments DI cannot resolve (e.g. a version string or per-site constant).
## `WebApplication` extensions

 
Middleware and endpoint wiring. The template `Use*` methods each wrap a fixed sequence, listed below.

 
`RunBlogSiteAsync` `Task RunBlogSiteAsync(this WebApplication app, string[] args)` 
Package `Pennington.BlogSite`

Runs the BlogSite: either serves the app or performs a static build, based on command-line args.
`RunDocSiteAsync` `Task RunDocSiteAsync(this WebApplication app, string[] args)` 
Package `Pennington.DocSite`

Runs the DocSite: either serves the app or performs a static build, based on command-line args.
`RunOrBuildAsync` `Task RunOrBuildAsync(this WebApplication app, string[] args)` 
Package `Pennington`

Runs the host: serves live (no verb), builds the static site (`build`), or runs a diagnostic command (`diag <sub>`). Everything flows through one System.CommandLine pipeline, so `--help` / `--version` work at the root and every subcommand. Build and diag run one-shot against a started in-memory host that is disposed afterward; serve hands off to `RunAsync`.
`UseBlogSite` `WebApplication UseBlogSite(this WebApplication app)` 
Package `Pennington.BlogSite`

Wires BlogSite middleware, Razor components, and RSS endpoint into the request pipeline.
`UseDocSite` `WebApplication UseDocSite(this WebApplication app)` 
Package `Pennington.DocSite`

Wires DocSite middleware and Razor components into the request pipeline.
`UseLiveReload` `WebApplication UseLiveReload(this WebApplication app)` 
Package `Pennington`

Adds live reload WebSocket support for development. Skipped during static build (see `PenningtonCli`).
`UseLocaleRouting` `WebApplication UseLocaleRouting(this WebApplication app)` 
Package `Pennington`

Adds locale detection and URL path rewriting middleware. Must be called `MapRazorComponents` so that Blazor routing sees the locale-stripped path (e.g., `/gen-z/schedule` becomes `/schedule`). Called automatically by `UsePennington` when it hasn't been called yet, but at that point it is too late for Blazor endpoint routing. Sites that use `@page` directives with locale prefixes must call this explicitly.
`UseMonorailCss` `WebApplication UseMonorailCss(this WebApplication app, string path)` 
Package `Pennington.MonorailCss`

Maps the MonorailCSS stylesheet endpoint. The endpoint pulls the current class set from the discovery pipeline registered in `AddMonorailCss`, generates CSS, and serves it.
`UsePennington` `WebApplication UsePennington(this WebApplication app)` 
Package `Pennington`

Configure the Pennington middleware pipeline.
### `UseDocSite` middleware order

 
`UseDocSite` registers this sequence before mapping the Razor component endpoint:

 
 1. `UseLocaleRouting`
 2. `UseAntiforgery`
 3. `UseStaticFiles`
 4. `UseMonorailCss`
 5. `UsePennington`
 6. `MapRazorComponents<App>()`
 
 
### `UseBlogSite` middleware order

 
`UseBlogSite` registers the same sequence minus locale routing, which BlogSite does not wire:

 
 1. `UseAntiforgery`
 2. `UseStaticFiles`
 3. `UseMonorailCss`
 4. `UsePennington`
 5. `MapRazorComponents<App>()`
 
 
For why each step lands where it does, see [Dev mode and build mode share one code path](https://usepennington.net/explanation/core/dev-vs-build.md).

 
## `Run*` host entry points

 
Host entry points that run one System.CommandLine pipeline: serve live with no verb, build the static site with `build`, or run a read-only inspection with `diag <sub>`. Build and diag run one-shot against a started in-memory host that is disposed afterward; serve hands off to `RunAsync`.

 
 - [RunOrBuildAsync](https://usepennington.net/reference/api/pennington-extensions.md) — the core dispatcher; call it directly on a bare `AddPennington` host.
 - [RunDocSiteAsync](https://usepennington.net/reference/api/doc-site-service-extensions.md) — DocSite wrapper over `RunOrBuildAsync`.
 - [RunBlogSiteAsync](https://usepennington.net/reference/api/blog-site-service-extensions.md) — BlogSite wrapper over `RunOrBuildAsync`.
 
 
## Example

 
A complete DocSite host wiring all three layers — `AddDocSite`, `UseDocSite`, `RunDocSiteAsync` — in call order.

 
```csharp:symbol
using Pennington.DocSite;
  
var builder = WebApplication.CreateBuilder(args);
  
// Swap the bare `AddPennington` host for the DocSite template. `AddDocSite`
// wires the full documentation experience on top of Pennington core — a
// Blazor-rendered layout with sidebar navigation, header, search surface,
// outline nav, dark-mode toggle — driven entirely from `DocSiteOptions`.
builder.Services.AddDocSite(() => new DocSiteOptions
{
    SiteTitle = "Scaffold Docs",
    SiteDescription = "A minimal DocSite scaffold built on AddDocSite.",
    GitHubUrl = "https://github.com/usepennington/pennington",
    HeaderContent = """<a href="/">Scaffold Docs</a>""",
    FooterContent = """<footer class="mt-16 py-8 text-center text-sm text-base-500">Built with Pennington DocSite.</footer>""",
});
  
var app = builder.Build();
  
// `UseDocSite` mounts locale routing, antiforgery, static files, Razor
// component routing (`Pages.razor` owns `/{*fileName:nonfile}`), MonorailCSS,
// SPA navigation, and the core Pennington middleware in the right order.
app.UseDocSite();
  
// `RunDocSiteAsync` delegates to `RunOrBuildAsync`, so `dotnet run` serves live
// and `dotnet run -- build <baseUrl> <outputDir>` generates static HTML. Both
// positional args are optional (defaults: `/` and `output`).
await app.RunDocSiteAsync(args);
```

 
## See also

 
 - Reference: [CLI and build arguments](https://usepennington.net/reference/host/cli.md)
 - Reference: [PenningtonOptions](https://usepennington.net/reference/api/pennington-options.md)
 - Reference: [DocSiteOptions](https://usepennington.net/reference/api/doc-site-options.md)
 - Background: [Dev mode and build mode share one code path](https://usepennington.net/explanation/core/dev-vs-build.md)
 
 
[Previous
                
                SPA engine attributes and events](https://usepennington.net/reference/spa/attributes.md)[Next
                    
                CLI and build arguments](https://usepennington.net/reference/host/cli.md)