monstertjie_za
monstertjie_za

Reputation: 7803

Unable to resolve service for type 'Swashbuckle.AspNetCore.Swagger.ISwaggerProvider'

I am starting a new Core Web API, and would like to add Swagger to my application.

My current environment:

Here is my Startup.cs class and configuration:

public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();

        //AK: Enable CORS
        //CORS should be configured on host server.
        services.AddCors(setupAction =>
        {
            setupAction.AddPolicy(DevCorsPolicyName,
                builder =>
                {
                    builder.WithOrigins("*").AllowAnyHeader().AllowAnyMethod();
                });
        });

        #region Configuration

        //Configuration File
        services.Configure<AppSettingConfiguration>(Configuration.GetSection("AppSettings"));
        //AutoMapper
        services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

        //Configure Swagger
        services.ConfigureSwaggerGen(c =>
        {
            c.SwaggerDoc("v3", new OpenApiInfo
            {
                Title = "GTrackAPI",
                Version = "v3"
            });
        });

        #endregion

        #region Dependency Injection

        //Database context and repository
        services.AddDbContext<IGTrackContext, GTrackContext>(builder =>
        {
            builder.UseSqlServer(connectionString: Configuration.GetConnectionString("gtrackConnection"), sqlServerOptionsAction: null);
        });
        services.AddScoped<IGTrackRepository, GTrackRepository>();

        //facade layers
        services.AddScoped<IPersonFacade, PersonFacade>();

        //Service layers
        services.AddScoped<IPersonService, PersonService>();

        #endregion
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        //Enable development environment only settings
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        //AK: Only allow all origins for development environmnet
        app.UseCors(DevCorsPolicyName);

        // Enable middleware to serve generated Swagger as a JSON endpoint.
        app.UseSwagger();

        // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
        // specifying the Swagger JSON endpoint.
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "GTrackAPI");
            c.RoutePrefix = string.Empty; //Configures swagger to load at application root
        });

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }

When I run my application, I get the following error:

InvalidOperationException: Unable to resolve service for type 'Swashbuckle.AspNetCore.Swagger.ISwaggerProvider' while attempting to Invoke middleware 'Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware'.

Here is the Stacktrace:

System.InvalidOperationException: Unable to resolve service for type 'Swashbuckle.AspNetCore.Swagger.ISwaggerProvider' while attempting to Invoke middleware 'Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware'. at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.GetService(IServiceProvider sp, Type type, Type middleware) at lambda_method(Closure , Object , HttpContext , IServiceProvider ) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass4_1.b__2(HttpContext context) at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.Invoke(HttpContext context, ICorsPolicyProvider corsPolicyProvider) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass4_1.b__2(HttpContext context) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

It is pretty clear that I am missing something here, not sure exactly what. Any help would be appreciated.

Upvotes: 42

Views: 80451

Answers (3)

Dariusz Woźniak
Dariusz Woźniak

Reputation: 10350

Answer for Minimal API and .NET ≥ 6

  1. Install Swashbuckle.AspNetCore NuGet package
  2. Add AddEndpointsApiExplorer before AddSwaggerGen

Working example:

var builder = WebApplication.CreateBuilder(args);

var services = builder.Services;
services.AddEndpointsApiExplorer();
services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}

app.UseSwagger();

app.MapGet("/", () => "Hello World!");

app.UseSwaggerUI();
app.Run();

Upvotes: 24

Rakesh Suryawanshi
Rakesh Suryawanshi

Reputation: 520

If you have created a Web API with dotnet CLI and if you are getting this error

error NU1100: Unable to resolve 'Swashbuckle.AspNetCore (>= 5.6.3)' for 'net5.0'

It means dotnet CLI is unable to find the swagger dependency

To resolve this you can run following dotnet CLI command

dotnet add package Swashbuckle.AspNetCore.Swagger --version 5.6.3

Upvotes: 2

Nkosi
Nkosi

Reputation: 246998

A call to

services.AddSwaggerGen();

appears to be missing in the ConfigureServices.

public static IServiceCollection AddSwaggerGen(
    this IServiceCollection services,
    Action<SwaggerGenOptions> setupAction = null)
{
    // Add Mvc convention to ensure ApiExplorer is enabled for all actions
    services.Configure<MvcOptions>(c =>
        c.Conventions.Add(new SwaggerApplicationConvention()));

    // Register generator and it's dependencies
    services.AddTransient<ISwaggerProvider, SwaggerGenerator>();
    services.AddTransient<ISchemaGenerator, SchemaGenerator>();
    services.AddTransient<IApiModelResolver, JsonApiModelResolver>();

    // Register custom configurators that assign values from SwaggerGenOptions (i.e. high level config)
    // to the service-specific options (i.e. lower-level config)
    services.AddTransient<IConfigureOptions<SwaggerGeneratorOptions>, ConfigureSwaggerGeneratorOptions>();
    services.AddTransient<IConfigureOptions<SchemaGeneratorOptions>, ConfigureSchemaGeneratorOptions>();

    // Used by the <c>dotnet-getdocument</c> tool from the Microsoft.Extensions.ApiDescription.Server package.
    services.TryAddSingleton<IDocumentProvider, DocumentProvider>();

    if (setupAction != null) services.ConfigureSwaggerGen(setupAction);

    return services;
}

which is what adds the ISwaggerProvider to the service collection

You can refactor your current code to

//...

//Configure Swagger
services.AddSwaggerGen(c => { //<-- NOTE 'Add' instead of 'Configure'
    c.SwaggerDoc("v3", new OpenApiInfo {
        Title = "GTrackAPI",
        Version = "v3"
    });
});

//...

which as seen by the source code will eventually call ConfigureSwaggerGen with the setup action.

Upvotes: 61

Related Questions