Class BowireServiceCollectionExtensions
- Namespace
- Kuestenlogik.Bowire
- Assembly
- Kuestenlogik.Bowire.dll
DI-container extensions that wire Bowire and its installed protocol plugins into an ASP.NET application.
public static class BowireServiceCollectionExtensions
- Inheritance
-
BowireServiceCollectionExtensions
- Inherited Members
Remarks
Paired with
MapBowire(IEndpointRouteBuilder, string, Action<BowireOptions>?):
call AddBowire() in Program.cs before builder.Build(),
then MapBowire() on the resulting app.
Methods
AddBowire(IServiceCollection)
Registers Bowire and auto-configures the DI prerequisites for every installed protocol plugin.
public static IServiceCollection AddBowire(this IServiceCollection services)
Parameters
servicesIServiceCollectionThe application's service collection.
Returns
- IServiceCollection
The same
servicesinstance, so calls can be chained (for example with.AddBowire().AddAuthentication(…)).
Examples
Without AddBowire, protocols must be configured by hand:
builder.Services.AddGrpc();
builder.Services.AddGrpcReflection();
// ... and every other protocol's own setup ...
var app = builder.Build();
app.MapGrpcReflectionService();
app.MapBowire();
With AddBowire, a single line covers every referenced plugin:
builder.Services.AddBowire();
var app = builder.Build();
app.MapBowire();
Remarks
Scans every loaded assembly whose name starts with Kuestenlogik.Bowire
for types that implement IBowireProtocolServices and
invokes ConfigureServices(IServiceCollection) on
each. Only protocols whose NuGet package is actually referenced by
the host project are activated — no gRPC reference means no gRPC
Server Reflection is registered, no SignalR reference means no hub
enumeration, and so on.
A preliminary pass force-loads every Kuestenlogik.Bowire*.dll from the
application's output directory so that plugins shipped as runtime
dependencies (but not touched by the CLR yet) are discovered too.
Assemblies that fail to enumerate types are silently skipped to keep
startup resilient in misconfigured deployments.
- See Also
AddBowire(IServiceCollection, Action<BowireOptions>?)
Overload that exposes a configuration callback for the subset of
BowireOptions that needs to be settled at
AddServices time rather than at
MapBowire(IEndpointRouteBuilder, string, Action<BowireOptions>?)
time. Today the only such option is
SchemaHintsPath — the user-local
schema-hints file path that the
LayeredAnnotationStore singleton needs at
construction. Everything else still flows through the regular
MapBowire callback.
public static IServiceCollection AddBowire(this IServiceCollection services, Action<BowireOptions>? configure)
Parameters
servicesIServiceCollectionconfigureAction<BowireOptions>
Returns
AddBowireEnvironment(IServiceCollection, string, Action<BowireProvisionedEnvironment>)
Declare an environment from the host's own configuration (#49).
public static IServiceCollection AddBowireEnvironment(this IServiceCollection services, string name, Action<BowireProvisionedEnvironment> configure)
Parameters
servicesIServiceCollectionThe host's container.
namestringWhat it is called in the workbench's switcher.
configureAction<BowireProvisionedEnvironment>Fills in the variables.
Returns
Examples
services.AddBowire();
services.AddBowireEnvironment("Staging", env => env
.Set("baseUrl", configuration["Api:BaseUrl"])
.Set("tenant", options.Value.TenantId));
Remarks
An embedded host already knows its base URLs and tenant ids; without
this the only way to use them in the workbench was to read them out of
appsettings.json and type them in again, leaving two copies of
which one goes quietly wrong the moment the other changes.
Declared environments are contributed on every start and never written
to environments.json. Change the host's configuration, restart,
and the environment changes with it — nothing stale left behind, and
nothing for the workbench to save back and end up holding twice.
Call it once per environment. A second call with the same name replaces the first, so a host composing configuration in layers gets the last word rather than two entries sharing a name.
AddBowireModule<TModule>(IServiceCollection)
Counterpart to AddBowireRail<TRail>(IServiceCollection) for cross-cutting modules (AI, Assistant, var-resolver, …).
public static IServiceCollection AddBowireModule<TModule>(this IServiceCollection services) where TModule : class, IBowireModuleContribution, new()
Parameters
servicesIServiceCollection
Returns
Type Parameters
TModule
AddBowirePlugins(IServiceCollection, IConfiguration)
Overload that reads the plugin directory from a bound
IConfiguration. Looks at Bowire:PluginDir;
returns unchanged when the key is unset so callers can wire this
into their startup pipeline unconditionally.
public static IServiceCollection AddBowirePlugins(this IServiceCollection services, IConfiguration configuration)
Parameters
servicesIServiceCollectionconfigurationIConfiguration
Returns
Remarks
This is the preferred wiring for embedded hosts that already
build an IConfiguration from appsettings.json
or similar:
builder.Services
.AddBowirePlugins(builder.Configuration)
.AddBowire();
Plugins themselves read their own config section via the standard .NET options pattern:
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions<MyPluginOptions>()
.BindConfiguration("Bowire:Plugins:MyPlugin");
}
AddBowirePlugins(IServiceCollection, string)
Load every .dll under pluginDir into the
default AssemblyLoadContext so
the subsequent AddBowire(IServiceCollection) reflection pass picks the
plugins up. Intended for embedded hosts that want to extend the
workbench with out-of-tree protocol plugins without depending on
the bowire CLI tool.
public static IServiceCollection AddBowirePlugins(this IServiceCollection services, string pluginDir)
Parameters
servicesIServiceCollectionThe application's service collection (returned unchanged, for chaining).
pluginDirstringDirectory to scan. Per-package subdirectories (
pluginDir/<package>/*.dll) are the primary layout — matches whatbowire plugin installproduces — but loose DLLs at the top level are picked up too.
Returns
Remarks
Non-existent paths are treated as empty (no throw) so callers can
blindly pass a configured directory even when no plugins have been
installed yet. DLLs that fail to load are silently skipped — the
equivalent behaviour to the bowire CLI's plugin loader.
Call this before AddBowire(IServiceCollection).
AddBowireRail<TRail>(IServiceCollection)
Register a specific rail contribution explicitly (in addition to the auto-discovery pass driven by AddBowire(IServiceCollection)). Useful when (a) the host wants to override a built-in rail's metadata without forking the contributing package, or (b) the rail descriptor lives in an assembly that isn't loaded by the auto-scan reach.
public static IServiceCollection AddBowireRail<TRail>(this IServiceCollection services) where TRail : class, IBowireRailContribution, new()
Parameters
servicesIServiceCollection
Returns
Type Parameters
TRailRail contribution type. Must implement IBowireRailContribution and expose a parameterless constructor — the registry instantiates the descriptor without passing dependencies (it's a metadata object).