Skip to content

[Task] Extend Plugin Configuration with Host Builder and Context #8

Description

@rian-be

Summary

Extend the AuthKit.Plugins.Abstractions plugin contract with host aware configuration support through an IHostApplicationBuilder overload and strongly typed AuthKitPluginContext.

The goal is to allow plugins to access host level configuration and contextual information during service registration without breaking existing plugin implementations.

Goal

Provide backward compatible configuration contract that allows plugins to receive:

  • the host application builder,
  • configuration,
  • and an explicit AuthKitPluginContext.

The new APIs must coexist with the existing plugin configuration methods and must not require existing plugins to change their implementation.

Background

The current plugin contract provides service configuration through the existing overload:

void ConfigureServices(
    IServiceCollection services,
    IConfiguration configuration);

This is sufficient for basic dependency registration but does not expose the broader host application builder.

Some plugins may need access to host-level capabilities during registration, such as:

  • host environment information,
  • application configuration,
  • service registration facilities,
  • plugin specific contextual information,
  • or other host provided metadata.

Passing individual dependencies through additional parameters would make the contract increasingly difficult to evolve.

This task introduces:

  1. an IHostApplicationBuilder based configuration overload;
  2. an AuthKitPluginContext abstraction that provides plugin context without coupling plugin implementations to the host's internal runtime.

Scope

B1. IHostApplicationBuilder Configuration Overload

Add host builder-aware configuration method to IAuthKitPlugin.

Preferred signature:

void ConfigureServices(
    IHostApplicationBuilder builder,
    IConfiguration configuration);

The new overload must coexist with the existing:

void ConfigureServices(
    IServiceCollection services,
    IConfiguration configuration);

Existing plugins must continue to compile and operate without modification.

B2. AuthKitPluginContext

Introduce new:

AuthKitPluginContext.cs

in AuthKit.Plugins.Abstractions.

The context provides strongly typed information about the plugin and its host configuration environment.

The context must be passed to the plugin configuration API:

void ConfigureServices(
    IServiceCollection services,
    AuthKitPluginContext context);

The exact properties should remain minimal and focused on stable plugin contract concerns.

Proposed Contract

The resulting interface should support the existing and new configuration paths without breaking existing implementations.

Conceptually:

public interface IAuthKitPlugin
{
    void ConfigureServices(
        IServiceCollection services,
        IConfiguration configuration);

    void ConfigureServices(
        IHostApplicationBuilder builder,
        IConfiguration configuration);

    void ConfigureServices(
        IServiceCollection services,
        AuthKitPluginContext context);
}

The exact compatibility mechanism may use default interface implementations where supported by the target framework.

The implementation must avoid forcing existing plugins to implement all overloads.

AuthKitPluginContext

Introduce:

public sealed record AuthKitPluginContext
{
    // Stable plugin/host contextual information.
}

The context should expose only information that is appropriate for the public plugin contract.
The initial context should remain intentionally small.

Potential contextual information may include:

Plugin name
Plugin configuration
Host environment
Application services
Host metadata

Only properties that are already required by the AuthKit architecture should be added.
Do not expose internal host implementation details merely for convenience.

Requirements

B1. Host Builder

The new IHostApplicationBuilder overload must allow a plugin to participate in host-level service configuration.

The plugin must be able to use:

builder.Services

for service registration.

The builder provided to the plugin must represent the same host builder used by AuthKit.
The host must not create an unrelated or isolated builder instance.

Existing Overload

The existing:

ConfigureServices(
    IServiceCollection services,
    IConfiguration configuration)

must remain valid.

Its semantics must not change.
Existing plugins implementing only the old overload must continue to work.
The host must define deterministic behavior when plugin implements both the old and new overloads.
The implementation must not accidentally execute the same registration logic twice.

B2. Plugin Context

AuthKitPluginContext must provide stable abstraction for plugin specific contextual information.

The context should not expose mutable host internals unless explicitly required by the contract.

Properties should be read only where possible.

For example:

public sealed record AuthKitPluginContext(
    string PluginName,
    IConfiguration Configuration);

is preferable to exposing mutable service container or internal plugin loader state.
The exact shape should follow the existing AuthKit abstraction style.

Context Identity

The context must represent the plugin currently being configured.

If multiple plugins are loaded:

Plugin A → AuthKitPluginContext for Plugin A
Plugin B → AuthKitPluginContext for Plugin B

The host must not accidentally reuse the context of one plugin for another.

Configuration Isolation

Plugin configuration must remain scoped to the plugin's configuration namespace where applicable.

For example:

Plugins:
  DevTokens:
    ...

must not cause the context for another plugin to expose the wrong configuration section.
The context must not provide unrestricted access to mutable plugin loader state.

Backward Compatibility

This task is explicitly additive.

The following must remain unchanged:

  • existing IAuthKitPlugin members,
  • existing plugin implementations,
  • existing plugin configuration behavior,
  • existing plugin loading behavior.

Existing plugins, including DevTokens, must compile without modification.

A plugin implementing only:

void ConfigureServices(
    IServiceCollection services,
    IConfiguration configuration);

must continue to work.

A plugin must not be required to implement:

void ConfigureServices(
    IHostApplicationBuilder builder,
    IConfiguration configuration);

or:

void ConfigureServices(
    IServiceCollection services,
    AuthKitPluginContext context);

unless it explicitly wants to use the new APIs.

Default Interface Behavior

If default interface implementations are used, the new overloads must have safe defaults.

For example, the host builder overload may delegate to the existing service collection overload:

void ConfigureServices(
    IHostApplicationBuilder builder,
    IConfiguration configuration)
{
    ConfigureServices(builder.Services, configuration);
}

This provides compatibility bridge for existing plugins.

The opposite direction must not be used if it would require constructing an artificial IHostApplicationBuilder.

The context overload must similarly have explicitly defined default behavior if implemented as default interface member.

Invocation Rules

The host must define deterministic invocation strategy.

For legacy plugin:

Existing ConfigureServices(IServiceCollection, IConfiguration)
        ↓
called once

For plugin implementing the new host builder overload:

ConfigureServices(IHostApplicationBuilder, IConfiguration)
        ↓
called once

For plugin using AuthKitPluginContext:

ConfigureServices(IServiceCollection, AuthKitPluginContext)
        ↓
called once

The host must avoid accidental duplicate invocation when multiple compatibility overloads are available.
The selected strategy must be documented and covered by tests.

Error Handling

Invalid plugin configuration must result in an explicit configuration or contract error.

The implementation must not:

  • silently ignore plugin's configuration method,
  • silently construct an invalid context,
  • silently use another plugin's context,
  • or silently discard host builder configuration.

If required context property cannot be constructed, plugin loading/configuration must fail explicitly.

Dependency Injection

The new context must not introduce new dependency injection system.
It should use the existing AuthKit host DI infrastructure.
The context must not own the application's service provider unless this is explicitly required by the final contract.

Do not introduce service locator behavior through AuthKitPluginContext merely to make dependencies easier to access.

XML Documentation

All newly introduced public types and members must contain complete XML documentation.

At minimum:

  • AuthKitPluginContext
  • all public properties of AuthKitPluginContext
  • the new IAuthKitPlugin overloads

must be documented.

Documentation must clearly describe:

  • when the API is called,
  • what the supplied values represent,
  • and whether the API is optional for existing plugins.

Non Goals

This task does not include:

  • plugin endpoint mapping,
  • middleware configuration,
  • pipeline ordering,
  • lifecycle events,
  • hosted services,
  • OpenAPI configuration,
  • Marten configuration,
  • authentication configuration,
  • authorization configuration,
  • new DI infrastructure,
  • or plugin runtime lifecycle management.

Those concerns are handled by later Section B issues.

Validation

B1. Host Builder

  • IHostApplicationBuilder overload exists.
  • The overload receives the actual AuthKit host builder.
  • builder.Services can be used for plugin registrations.
  • Existing IServiceCollection overload remains unchanged.
  • Legacy plugins continue to work.
  • Plugin implementing only the new overload works.
  • Host does not invoke equivalent configuration logic twice.

B2. Context

  • AuthKitPluginContext exists in AuthKit.Plugins.Abstractions.
  • Context is strongly typed.
  • Context exposes only stable plugin-contract information.
  • Context is correctly associated with the plugin being configured.
  • Multiple plugins receive independent/correct contexts.
  • Plugin configuration is correctly associated with the relevant plugin configuration.
  • Context does not introduce a new DI system.

Compatibility

  • Existing plugins compile without modification.
  • Existing plugins retain their current configuration behavior.
  • DevTokens compiles without modification.
  • DevTokens loads successfully.
  • PluginContractValidator passes.

Documentation

  • All new public types have XML documentation.
  • All new public members have XML documentation.
  • Backward compatible behavior is documented.

Build and Tests

  • dotnet build AuthKit.Plugins.Abstractions succeeds.
  • Build completes with zero warnings.
  • Relevant unit tests pass.
  • Integration tests pass.
  • Plugin configuration invocation tests pass.
  • Context isolation tests pass.

Acceptance Criteria

  • IAuthKitPlugin supports host builde aware configuration.
  • The existing configuration overload remains fully compatible.
  • AuthKitPluginContext provides strongly typed plugin configuration context.
  • Existing plugins require no source changes.
  • The host invokes the appropriate configuration path exactly once.
  • Each plugin receives the correct context.
  • No new DI or configuration engine is introduced.
  • All new public API is fully XML documented.
  • PluginContractValidator passes.
  • DevTokens continues to compile and load successfully.

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