Open maurei opened 3 years ago
You can tell the CLI tool to use an identical host setup as your application with the following approach:
Thanks for the quick response.
I tried that and ensured the SwaggerHostFactory
is actually called by the CLI, but Startup.Configure(IApplicationBuilder )
still isn't called. I've updated the repo to demonstrate this.
My bad - you're absolutely correct. With it's current implementation, the CLI tool builds an IHost
or IWebHost
and corresponding service container, and then uses that to retrieve an instance of ISwaggerProvider
, but falls short of actually spinning up the application behind the scenes, and as a result (and something I'm only learning now) does not invoke the startup Configure
method. I need to dig deeper to find an alternative approach that works - I'd prefer not have to actually spin up the app behind the scenes but it's starting to look like that may be neccessary in some shape or form.
Thanks for the elaboration. I'm looking into a workaround along the direction of executing the bit of code earlier that normally runs in Startup.Configure
. Ideally I'd do this only when the code is being called by Swashbuckle CLI. Is there some environment variable being set that allows me to detect this?
Is there any traction on this? I have other customizations that I need to include in the CLI-generated document.
Basically, this needs to be invoked:
app.UseSwagger(x =>
{
x.PreSerializeFilters.Add(SwaggerDocCustomizer.ModifySwaggerDoc);
});
UPDATE: I had a misconfiguration - using minimal hosting mode works (at least for my case). It does seem to require starting the app however...
Original: Program.cs
..
var app = builder.Build();
app
...
.UseEndpoints(b => {
b.MapVersionedODataRoute("odata", "api/odata", modelBuilder).Select().Count();
//every /odata/ route and schema is excluded from the generated swagger.json although these lines are run
});
@domaindrivendev Just tuning in on this discussion to ensure that we understand the implications of any changes that may or may not be underway.
We are actually really happy that the CLI does not invoke the startup Configure
method. In our setup, we have an appsettings.json
file that does not in itself allow for the CLI to build the service collection due to missing configuration. We thus use appsettings.Development.json
to run the Swashbuckle CLI, by setting ASPNETCORE_ENVIRONMENT=Development
. However, this mode also causes our startup Configure
method to seed our databases with development related data, for ease of use. We wouldn't want that to happen when building the swagger.json
.
In this case, I guess we would need to maintain two sets of app settings files, such as appsettings.Development.json
and appsettings.Swagger.json
, or would it be possible to use a cleverer approach (similarly to what @maurei is asking for)?
Entity Framework faced the same problem for running migrations. How they solved that is to start your app, but first subscribe to runtime-level events. The event handler terminates the app after services have been registered and the needed info has become available. It's all described at https://andrewlock.net/exploring-dotnet-6-part-5-supporting-ef-core-tools-with-webapplicationbuilder/.
I'm a maintainer of the JsonApiDotNetCore library (JADNC) and working on an OpenAPI Specification integration using Swashbuckle.
In JADNC we configure the routing through the use of an IApplicationModelConvention. We register our routing convention not in the
ConfigureServices(IServiceCollection)
method but in theConfigure(IApplicationBuilder)
method of the Startup. Here is the gist of that:This works fine when accessing the OAS document on the
docs/{documentName}/openapi.json
endpoint. However, when generating the OAS document usingdotnet swagger tofile
I noticed theConfigure(IApplicationBuilder)
isn't being called, and as a result the desired routes don't make it to the document.Eg the following difference will arise (snippet):
From CLI:
I've added a minimal repro case
For JADNC it's undesired to move the registration of the routing convention to
ConfigureServices(IServiceCollection)
because it depends on services that are registered in the DI container. See JsonApiRoutingConvention.