Adding Swagger to a .Net core application

If you have used Swagger with a website to document your API, then you know it has some nice features for testing your API as well as viewing the structure and documentation.

This is brief walkthrough of setting up Swagger.

First install the Swashbuckle nuget package.

In the startup.cs file of your .Net core web app, change ConfigureServices to have the following.

public IServiceProvider ConfigureServices(IServiceCollection services)

        {

            // Add framework services.

            services.AddMvc()

                .AddControllersAsServices();

            services.AddSwaggerGen(c =>

            {

                c.SwaggerDoc(“v1”, new Info { Title = “MyAPI”, Version = “v1” });

            });

            services.ConfigureSwaggerGen(c =>

            {

                c.IncludeXmlComments(GetXmlCommentsPath(PlatformServices.Default.Application));

            });

           

            return ConfigureIoC(services);

        }


And add this:

private string GetXmlCommentsPath(ApplicationEnvironment appEnvironment)



        {



            return Path.Combine(appEnvironment.ApplicationBasePath, "SolutionName.Project.ProjectAPI.xml");

//The above is coming from the .Net core project properties, build tab. // You need to check the box to create the XML documentation and use the file name from there. 

        }

ProjectProperties

StructureMap in .Net core website

I have been working on creating a .Net core application, which will have a standard Enterprise architecture with several subprojects.  Getting StructureMap to work has been a bit of struggle so let me document here what needed to be done.

First, the information here (https://andrewlock.net/getting-started-with-structuremap-in-asp-net-core/) was a good start, but that was for a project where everything was in a single project. My solution is more complex with interfaces and classes that exist in separate projects.

I installed the StructureMap nuget package in all of the projects that had components created by DI (Services, ServiceInterfaces, Repository, RepositoryInterfaces, and the Web project). My other projects that have entites or DTO’s that are not created via DI do not need to have the StructureMap nuget packages installed.

In my Startup.cs file in the .Net Core web project, I had to change the ConfigureServices function as follows.

public IServiceProvider ConfigureServices(IServiceCollection services)

{

// Add framework services.

services.AddMvc()

.AddControllersAsServices();

services.AddSwaggerGen(c =>

{

c.SwaggerDoc("v1", new Info { Title = "MyProjectTitleAPI", Version = "v1" });

});

services.ConfigureSwaggerGen(c =>

{

c.IncludeXmlComments(GetXmlCommentsPath(PlatformServices.Default.Application));

});

return ConfigureIoC(services);

}

Then I added this function, per the linked article, but notice that I do have to add the services manually. StructureMap should not be requiring that I do that, so while this works and would be standard OP for a tool like Ninject, I hoped I wouldn’t need these steps. (*Would love feedback if someone can tell me how to get around this issue.)

public IServiceProvider ConfigureIoC(IServiceCollection services)

        {

            var container = new Container();

             

            container.Configure(config =>

            {

                // Register stuff in container, using the StructureMap APIs...

                config.Scan(_ =>

                {

                    _.AssemblyContainingType(typeof(Startup));

                    //Todo:Research: This may not be needed, but I couldn't get it to work without it

                    _.Assembly("MarcTalcott.Reporting.Services"); //Services and IServices

                    _.Assembly("MarcTalcott.Reporting.Repositories");  //Repositories

                    _.Assembly("MarcTalcott.Reporting.Entities");  //IRepositories

                    _.WithDefaultConventions();

                    _.LookForRegistries();

                   

                });

                //Todo:Research: These direct Adds may not be needed, but I couldn't get it to work without them

                //Todo:Research: Also each of the projects that are involved DI, have a InfrastructureRegistry class I added, but have commented out. Seems that isn't needed.

                //  It might be that InfrastructureRegistry in each project can be setup properly (?) to avoid the need for these specific adds here.

                //  The advantage of StructureMap is that you shouldn't have to do this as log as the conventions are right, but it doesn't seem to work auto-magically for me.

                //  Could be that the Interfaces and Implementations must be in the same project but that defeats a lot of the purpose of programming to interfaces, which is a priority.

                //Add specific services (see note above)

                services.AddTransient();

                services.AddTransient();

                //Populate the container using the service collection

                config.Populate(services);

            });

            return container.GetInstance();

        }

That is it. The lines above where I’m explicitly setting

services.AddTransient();

are lines I don’t think should be needed since I expect StructureMap to find the class and associate it to the interface by convention. Perhaps it is a bug in this early .Net Core version of StructureMap. Perhaps not.