Skip to content

[Task] Add Plugin Endpoints and Application Pipeline Hooks #9

Description

@rian-be

Summary

Extend the AuthKit.Plugins.Abstractions plugin contract with explicit application integration hooks for endpoint registration, application configuration, and deterministic middleware pipeline placement.

The goal is to allow plugins to integrate with the ASP.NET Core request pipeline without requiring plugins to modify host startup code directly or rely on implicit middleware ordering.

Goal

Provide first class plugin APIs for:

  • registering plugin endpoints,
  • configuring application level middleware,
  • and explicitly controlling middleware placement in the host pipeline.

The implementation must remain additive and preserve compatibility with existing plugin implementations.

Background

Plugins currently have limited control over the ASP.NET Core application pipeline.

This makes it difficult for plugin to expose:

Plugin endpoints
Plugin middleware
Request processing behavior

without coupling the plugin to the host's startup implementation.

In particular, middleware ordering is significant in ASP.NET Core.

For example:

Authentication
    ↓
Authorization
    ↓
Plugin Middleware
    ↓
Endpoint Execution

must not be left to plugin discovery order or an undefined registration sequence.

This task introduces explicit hooks for endpoint mapping and application configuration, together with deterministic middleware positioning mechanism.

Scope

B3. MapEndpoints

Add an explicit endpoint registration hook:

void MapEndpoints(IEndpointRouteBuilder endpoints);

The host must invoke this method during endpoint configuration.

Plugin endpoints registered through this method must become part of the application's normal ASP.NET Core endpoint routing system.

B4. ConfigureApplication

Add an application configuration hook:

void ConfigureApplication(IApplicationBuilder application);

The hook allows plugin to register application level middleware or other supported application pipeline configuration.

It must coexist with existing MiddlewareType behavior.

B5. ConfigurePipeline with Explicit Position

Add pipeline configuration mechanism that allows plugins to specify where their middleware should be inserted.

The ordering must be deterministic and must not depend on:

  • plugin discovery order,
  • filesystem order,
  • assembly load order,
  • or dictionary enumeration order.

The exact position representation should follow the existing AuthKit architecture and should be strongly typed rather than relying on arbitrary strings where practical.

Proposed Contract

The contract should conceptually support:

void MapEndpoints(
    IEndpointRouteBuilder endpoints);

void ConfigureApplication(
    IApplicationBuilder application);

void ConfigurePipeline(
    IApplicationBuilder application,
    PluginPipelinePosition position);

The exact ConfigurePipeline signature and position type may be adjusted to match the final AuthKit host pipeline design.

If dedicated position type is introduced, it should be part of AuthKit.Plugins.Abstractions.

B3. Endpoint Mapping

Plugins may register endpoints using the supplied IEndpointRouteBuilder.

Example:

public void MapEndpoints(IEndpointRouteBuilder endpoints)
{
    endpoints.MapGet(
        "/plugin/example",
        () => Results.Ok());
}

The plugin must not need direct access to the host's endpoint configuration implementation.

Endpoint Registration Timing

The host must invoke MapEndpoints at the appropriate endpoint routing configuration stage.
Endpoint mapping must occur after the required service configuration has completed.
The host must not attempt to execute plugin endpoint handlers during application construction.

Endpoint Isolation

A plugin must only register its own endpoints through its own invocation.
The host must not accidentally pass one plugin's endpoint configuration state to another plugin.

Endpoint Failures

If endpoint mapping fails, the host must surface the failure explicitly.
The host must not silently skip failed plugin endpoint registration.

B4. Application Configuration

ConfigureApplication provides plugin level application configuration hook.
Example:

public void ConfigureApplication(IApplicationBuilder application)
{
    application.UseMiddleware<MyPluginMiddleware>();
}

The hook must operate on the actual application's IApplicationBuilder.

The host must not create an isolated application pipeline that is disconnected from the main application.

Existing MiddlewareType

The new API must coexist with existing MiddlewareType based plugin behavior.
Existing plugins relying on MiddlewareType must continue to work without modification.

The host must define deterministic behavior when plugin uses both:

MiddlewareType

and:

ConfigureApplication

The implementation must not silently register the same middleware twice.

Application Configuration Timing

ConfigureApplication must execute during application pipeline construction.

It must not be invoked after the application has already started serving requests.
The host must ensure that application configuration occurs before the final request pipeline is built.

B5. Middleware Pipeline Position

Middleware order is part of the plugin contract.

The host must provide an explicit mechanism for determining where plugin middleware is inserted.
The position must be deterministic.

A plugin must not have to rely on:

Plugin A loaded before Plugin B

to determine request processing order.

Position Model

A position model should provide finite set of well defined pipeline stages.

For example:

BeforeRouting
Routing
BeforeAuthentication
Authentication
BeforeAuthorization
Authorization
BeforeEndpoints
AfterEndpoints

The exact stages should be defined by the host architecture.

The implementation should avoid exposing every internal middleware as a public ordering dependency.

Ordering Within Position

If multiple plugins select the same pipeline position, the host must define deterministic ordering.

Possible strategies include:

  • explicit numeric order,
  • plugin defined order,
  • stable plugin name ordering,
  • or another documented mechanism.

The chosen mechanism must be deterministic and testable.
Plugin discovery order must not be the implicit ordering mechanism.

Invalid Positions

If plugin specifies an unsupported or invalid pipeline position, the host must fail explicitly.

It must not silently place the middleware at:

End

or another default position unless that behavior is explicitly defined by the contract.

Authentication and Authorization Ordering

The pipeline mechanism must allow plugins to correctly position middleware relative to authentication and authorization.

For example:

Routing
    ↓
Authentication
    ↓
Authorization
    ↓
Plugin Middleware
    ↓
Endpoints

must remain possible where required by the plugin.

The host must not allow plugin to accidentally execute authorization dependent middleware before authentication without an explicit configuration choice.

Authentication and authorization configuration itself belongs to B11–B12.

Endpoint Routing Compatibility

Plugin endpoint registration must remain compatible with ASP.NET Core endpoint routing.
The implementation must not introduce parallel routing mechanism.

Plugin endpoints should participate in:

  • endpoint metadata,
  • authorization metadata,
  • authentication behavior,
  • OpenAPI discovery,
  • and normal ASP.NET Core endpoint selection

where applicable.

Backward Compatibility

The change must be additive.
Existing plugins must continue to work without modification.

In particular:

  • plugins without MapEndpoints remain valid,
  • plugins without ConfigureApplication remain valid,
  • plugins using only MiddlewareType remain valid,
  • existing middleware behavior remains unchanged.

New hooks should use default interface implementations where appropriate.
The host must not invoke optional hooks unnecessarily.

Duplicate Registration

The host must avoid accidentally registering the same plugin middleware or endpoint multiple times.

Repeated lifecycle/configuration execution must not result from:

  • plugin discovery being repeated,
  • host builder configuration being invoked more than once,
  • or compatibility overloads being processed incorrectly.

Where duplicate registration cannot be prevented by the host, the behavior must be explicitly documented and tested.

Error Handling

Plugin configuration failures must be explicit.

The host must not silently ignore exceptions thrown by:

MapEndpoints
ConfigureApplication
ConfigurePipeline

A plugin that cannot configure its required application integration must cause an explicit host configuration failure.

Invalid pipeline positions must also produce an explicit error.

Thread Safety

Endpoint and application pipeline configuration occurs during application construction.

The implementation must not introduce shared mutable state that can result in:

  • duplicate endpoint registration,
  • inconsistent middleware ordering,
  • or cross plugin configuration leakage.

The resulting pipeline must be deterministic for the same plugin configuration.

Testing Strategy

Tests should use minimal sample plugin and a test host.

The test plugin should expose:

Endpoint
Middleware
Pipeline position

The tests should verify the actual resulting ASP.NET Core pipeline rather than only checking that methods were invoked.

Where practical, middleware should append identifiable markers to a request context so that ordering can be asserted.

Example:

PluginA
PluginB
Endpoint

should produce exactly the expected execution sequence.

Validation

B3. Endpoints

  • MapEndpoints(IEndpointRouteBuilder) exists.
  • Plugin endpoints are visible through the application's endpoint routing.
  • Plugin endpoint mapping executes during application configuration.
  • Endpoint mapping uses the actual application route builder.
  • Endpoint registration failures are explicit.
  • Existing plugins without endpoint hooks remain compatible.

B4. Application Configuration

  • ConfigureApplication(IApplicationBuilder) exists.
  • The hook receives the actual application builder.
  • Plugin middleware can be registered.
  • MiddlewareType behavior remains compatible.
  • Middleware is not accidentally registered twice.
  • Application configuration occurs before request processing starts.

B5. Pipeline Position

  • ConfigurePipeline supports explicit middleware positioning.
  • Pipeline positions are strongly typed or otherwise explicitly defined.
  • Ordering does not depend on plugin discovery order.
  • Multiple plugins at the same position have deterministic ordering.
  • Invalid positions are rejected explicitly.
  • Middleware can be placed relative to routing/authentication/authorization where supported.
  • Resulting middleware order is covered by integration tests.

Compatibility

  • Existing plugins compile without modification.
  • Existing MiddlewareType plugins continue to operate.
  • DevTokens continues to compile and load successfully.
  • PluginContractValidator passes.

Documentation

  • All new public APIs have complete XML documentation.
  • Pipeline position semantics are documented.
  • MiddlewareType compatibility behavior is documented.
  • Endpoint registration timing is documented.

Build and Tests

  • dotnet build AuthKit.Plugins.Abstractions succeeds.
  • Build completes with zero warnings.
  • Relevant unit tests pass.
  • Endpoint integration tests pass.
  • Middleware ordering integration tests pass.
  • Duplicate registration tests pass.
  • Invalid pipeline position tests pass.

Acceptance Criteria

  • Plugins can register endpoints through MapEndpoints.
  • Plugins can configure application middleware through ConfigureApplication.
  • Plugins can explicitly control middleware placement through ConfigurePipeline.
  • Middleware ordering is deterministic and independent of plugin discovery order.
  • Pipeline positions are explicitly defined and validated.
  • Plugin middleware can be positioned correctly relative to routing, authentication, authorization, and endpoints where supported.
  • Existing MiddlewareType behavior remains compatible.
  • Existing plugins require no source changes.
  • Endpoint and pipeline configuration failures are surfaced explicitly.
  • No plugin endpoint or middleware is silently ignored or moved to an unrelated fallback position.
  • PluginContractValidator passes.
  • DevTokens continues to compile and load successfully.

Non Goals

This task does not include:

  • lifecycle events such as OnStarting, OnStarted, or OnStopping,
  • plugin hosted services,
  • configuration binding,
  • OpenAPI configuration,
  • Marten integration,
  • authentication configurat ion,
  • authorization policy configuration,
  • or redesigning IAuthKitPlugin.

These concerns are handled by the other Section B sub issues.

Parent

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

P1Core operationadditiveAdditive, non-breaking changearea/abstractionsAuthKit.Plugins.Abstractions contractcontractChanges the plugin contractsub-taskChild task of an epic

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions