在 .NetCore 3.0 中配置 ApiVersionDescriptions 而不在启动时使用构建服务提供程序

jez*_*pin 9 configuration swagger asp.net-core

我的 Startup.cs 文件中有以下代码来获取和处理我的每个 API 版本描述并将它们添加到我的 Swagger。

var apiVersionDescriptionProvider = services.BuildServiceProvider().GetService<IApiVersionDescriptionProvider>();

        // Register the Swagger generator, defining 1 or more Swagger documents
        services.AddSwaggerGen(setup =>
        {
            foreach (var description in apiVersionDescriptionProvider.ApiVersionDescriptions)
            {
                setup.SwaggerDoc(
                    $"MyAPISpecification{description.GroupName}",
                    new OpenApiInfo() 
                    { 
                        Title = "My API Specification",
                        Version = description.ApiVersion.ToString(), 
                    });
            }
Run Code Online (Sandbox Code Playgroud)

我的理解是,我应该依赖注入 IApiVersionDescriptionProvider 的实现,而不是在我的启动类的 ConfigureServices 方法中使用 BuildServiceProvider ,因为这会阻止创建单例的额外副本。

在此特定示例中,我将如何处理此问题,因为这是配置服务的方法,因此此时我没有构建实例,服务可以在不使用构建服务提供程序的情况下使用该实例。

我在 StackOverflow 上的其他地方阅读了有关使用选项的内容,但我看不出该示例如何适用于这种情况。任何帮助都将不胜感激,因为此 Swagger 配置基于 2019 年末发布的 Pluralsight 视频,我认为这是正确的。

提前致谢。

crg*_*den 17

您可以使用实现IConfigureOptions 接口。有一个示例可以准确地执行您在存储库中尝试执行的操作:

namespace Microsoft.Examples
{
    using Microsoft.AspNetCore.Mvc.ApiExplorer;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Options;
    using Microsoft.OpenApi.Models;
    using Swashbuckle.AspNetCore.SwaggerGen;
    using System;

    /// <summary>
    /// Configures the Swagger generation options.
    /// </summary>
    /// <remarks>This allows API versioning to define a Swagger document per API version after the
    /// <see cref="IApiVersionDescriptionProvider"/> service has been resolved from the service container.</remarks>
    public class ConfigureSwaggerOptions : IConfigureOptions<SwaggerGenOptions>
    {
        readonly IApiVersionDescriptionProvider provider;

        /// <summary>
        /// Initializes a new instance of the <see cref="ConfigureSwaggerOptions"/> class.
        /// </summary>
        /// <param name="provider">The <see cref="IApiVersionDescriptionProvider">provider</see> used to generate Swagger documents.</param>
        public ConfigureSwaggerOptions( IApiVersionDescriptionProvider provider ) => this.provider = provider;

        /// <inheritdoc />
        public void Configure( SwaggerGenOptions options )
        {
            // add a swagger document for each discovered API version
            // note: you might choose to skip or document deprecated API versions differently
            foreach ( var description in provider.ApiVersionDescriptions )
            {
                options.SwaggerDoc( description.GroupName, CreateInfoForApiVersion( description ) );
            }
        }

        static OpenApiInfo CreateInfoForApiVersion( ApiVersionDescription description )
        {
            var info = new OpenApiInfo()
            {
                Title = "Sample API",
                Version = description.ApiVersion.ToString(),
                Description = "A sample application with Swagger, Swashbuckle, and API versioning.",
                Contact = new OpenApiContact() { Name = "Bill Mei", Email = "bill.mei@somewhere.com" },
                License = new OpenApiLicense() { Name = "MIT", Url = new Uri( "https://opensource.org/licenses/MIT" ) }
            };

            if ( description.IsDeprecated )
            {
                info.Description += " This API version has been deprecated.";
            }

            return info;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它被添加Startup.cs为:

services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();
Run Code Online (Sandbox Code Playgroud)

参考:ASP.NET Core / ASP.NET API 版本控制中的选项模式

  • @crgolden,我了解设置“IConfigureOptions&lt;SwaggerGenOptions&gt;”的注册,但我不确定如何/在哪里自动注入“ConfigureSwaggerOptions”的实例。如何/在哪里引用“IConfigureOptions&lt;SwaggerGenOptions&gt;”作为构造函数参数,以便使用“IApiVersionDescriptionProvider”实例自动创建“ConfigureSwaggerOptions”实例? (3认同)