Is your feature request related to a specific problem? Or an existing feature?
If you extend existing solutions that come with a preconfigured Swashbuckle (for example Umbraco), you may want to add your own documents for your own API's, but not wish to inherit the existing configuration (eg. UseOneOfForPolymorphism or existing Filters).
Describe the solution you'd like
Currently, there can only ever be one SwaggerGenOptions, and it's split into a SwaggerGeneratorOptions and SchemaGeneratorOptions during startup using ConfigureSwaggerGeneratorOptions and ConfigureSchemaGeneratorOptions.
As such, the SwaggerGenerator and SchemaGenerator will use the same configuration for all documents. While you can make Filters opt-in by checking the documentName before proceeding with the logic, it's pretty much impossible to do something as simple as enabling/disabling UseOneOfForPolymorphism for one specific document without reinventing the wheel quite a bit.
My proposed solution is making the default ISwaggerProvider/IAsyncSwaggerProvider "document-aware". If the DI has a specific configuration for the string documentName, that one is used instead of the "global" one.
I made a proof of concept for this by creating a custom DocumentAwareSwaggerGenerator with this particular logic:
private SwaggerGenerator GetSwaggerGenerator(string documentName)
{
var swaggerGenOptions = _serviceProvider
.GetKeyedService<SwaggerGenOptions>(documentName);
SwaggerGeneratorOptions swaggerGeneratorOptions;
SchemaGeneratorOptions schemaGeneratorOptions;
if (swaggerGenOptions == null)
{
swaggerGeneratorOptions = _swaggerGeneratorOptions;
schemaGeneratorOptions = _schemaGeneratorOptions;
}
else
{
swaggerGeneratorOptions = swaggerGenOptions.SwaggerGeneratorOptions;
schemaGeneratorOptions = swaggerGenOptions.SchemaGeneratorOptions;
}
var schemaGenerator = new SchemaGenerator(schemaGeneratorOptions, _serializerDataContractResolver);
return new SwaggerGenerator(swaggerGeneratorOptions, _apiDescriptionsProvider, schemaGenerator);
}
I then added an Extension method:
public static IServiceCollection ConfigureSwaggerGen<T>(
this IServiceCollection services,
string name,
OpenApiInfo info
)
where T : class, IConfigureOptions<SwaggerGenOptions>
{
services.Configure<SwaggerGenOptions>(options =>
{
options.SwaggerDoc(name, info);
});
//NOTE: Transient so the constructor can inject all types of scope
services.AddKeyedTransient<IConfigureOptions<SwaggerGenOptions>, T>(name);
//NOTE: Singleton so the factory is only run once
services.AddKeyedSingleton(name, (provider, _) =>
{
var swaggerGenOptions = new SwaggerGenOptions();
swaggerGenOptions.SwaggerGeneratorOptions.SwaggerDocs.Add(
name,
info
);
provider
.GetRequiredKeyedService<IConfigureOptions<SwaggerGenOptions>>(name)
.Configure(swaggerGenOptions);
//Snip: ConfigureSwaggerGeneratorOptions CreateFilter logic
//Snip: ConfigureSchemaGeneratorOptions CreateFilter logic
return swaggerGenOptions;
});
return services;
}
All-in-all, this works! But I feel something like this should be included as part of Swashbuckle by default.
Is your feature request related to a specific problem? Or an existing feature?
If you extend existing solutions that come with a preconfigured Swashbuckle (for example Umbraco), you may want to add your own documents for your own API's, but not wish to inherit the existing configuration (eg.
UseOneOfForPolymorphism
or existing Filters).Describe the solution you'd like
Currently, there can only ever be one
SwaggerGenOptions
, and it's split into aSwaggerGeneratorOptions
andSchemaGeneratorOptions
during startup usingConfigureSwaggerGeneratorOptions
andConfigureSchemaGeneratorOptions
.As such, the
SwaggerGenerator
andSchemaGenerator
will use the same configuration for all documents. While you can make Filters opt-in by checking the documentName before proceeding with the logic, it's pretty much impossible to do something as simple as enabling/disablingUseOneOfForPolymorphism
for one specific document without reinventing the wheel quite a bit.My proposed solution is making the default
ISwaggerProvider
/IAsyncSwaggerProvider
"document-aware". If the DI has a specific configuration for thestring documentName
, that one is used instead of the "global" one.I made a proof of concept for this by creating a custom
DocumentAwareSwaggerGenerator
with this particular logic:I then added an Extension method:
All-in-all, this works! But I feel something like this should be included as part of Swashbuckle by default.
Additional context
No response