Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Configuring ApiVersionDescriptions in .NetCore 3.0 without using build service provider in startup

I have the following code in my Startup.cs file to grab and process each of my API version descriptions and add them to my 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(), 
                    });
            }

My understanding is that I should dependency inject the implementation of the IApiVersionDescriptionProvider instead of using the BuildServiceProvider inside the ConfigureServices method of my startup class as this would prevent and additional copy of a singleton being created.

How would I go about this in this specific example as this is the method in which services are configured so I do not have an instance built by this point that the service can use wthout using the build service provider.

I read somewhere else on StackOverflow about using options but I could not see how that example would apply in this scenario. Any help would be greatly appreciated as this Swagger configuration was based off of a Pluralsight video posted late 2019 that I would have expected to have been correct.

Thanks in advance.

like image 962
jezzipin Avatar asked Jan 15 '20 17:01

jezzipin


People also ask

How do I add dependency injection to startup CS?

The implementation class of above interface having dummy data. Then we have to create a Controller(API) for calling this repo, and inject this interface into this. In the last, we have to register it in Startup class. Also mention which type of instance want to inject - (the lifetime) of our instance.

What is the options pattern in Asp net Core?

So, in short, the options pattern helps us to: bind the configuration data to strongly typed objects. group the configuration data in logical sections. reload the configuration while the application is running. validate the configuration.


1 Answers

You can use implement the IConfigureOptions Interface. There is an example of doing exactly what you're trying to do in the repository:

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 = "[email protected]" },
                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;
        }
    }
}

It is added in Startup.cs as:

services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();

References: Options pattern in ASP.NET Core / ASP.NET API Versioning

like image 157
crgolden Avatar answered Sep 28 '22 18:09

crgolden