Skip to content

Commit

Permalink
Merge pull request #1556 from domaindrivendev/convention-based-hook-f…
Browse files Browse the repository at this point in the history
…or-cli-webhost

Use convention over type-system for CLI WebHost factory hook
  • Loading branch information
domaindrivendev authored Mar 6, 2020
2 parents 9b8fbc0 + b0a1312 commit 0a7420c
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 59 deletions.
23 changes: 0 additions & 23 deletions src/Swashbuckle.AspNetCore.Cli/DefaultSwaggerWebHostFactory.cs

This file was deleted.

12 changes: 0 additions & 12 deletions src/Swashbuckle.AspNetCore.Cli/ISwaggerWebHostFactory.cs

This file was deleted.

41 changes: 30 additions & 11 deletions src/Swashbuckle.AspNetCore.Cli/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Writers;
using Swashbuckle.AspNetCore.Swagger;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore;

namespace Swashbuckle.AspNetCore.Cli
{
Expand Down Expand Up @@ -66,17 +68,17 @@ static int Main(string[] args)
var startupAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(
Path.Combine(Directory.GetCurrentDirectory(), namedArgs["startupassembly"]));

var hostFactory = CreateSwaggerWebHostFactory(startupAssembly);
var host = hostFactory.BuildWebHost();
// 2) Build a web host to serve the request
var host = BuildWebHost(startupAssembly);

// 2) Retrieve Swagger via configured provider
// 3) Retrieve Swagger via configured provider
var swaggerProvider = host.Services.GetRequiredService<ISwaggerProvider>();
var swagger = swaggerProvider.GetSwagger(
namedArgs["swaggerdoc"],
namedArgs.ContainsKey("--host") ? namedArgs["--host"] : null,
namedArgs.ContainsKey("--basepath") ? namedArgs["--basepath"] : null);

// 3) Serialize to specified output location or stdout
// 4) Serialize to specified output location or stdout
var outputPath = namedArgs.ContainsKey("--output")
? Path.Combine(Directory.GetCurrentDirectory(), namedArgs["--output"])
: null;
Expand Down Expand Up @@ -112,15 +114,32 @@ private static string EscapePath(string path)
: path;
}

private static ISwaggerWebHostFactory CreateSwaggerWebHostFactory(Assembly startupAssembly)
private static IWebHost BuildWebHost(Assembly startupAssembly)
{
// Scan the startup assembly for custom implementations
var customFactoryType = startupAssembly.DefinedTypes
.SingleOrDefault(t => t.ImplementedInterfaces.Contains(typeof(ISwaggerWebHostFactory)));
// Scan the startup assembly for any types that match the naming convention
var factoryTypes = startupAssembly.DefinedTypes
.Where(t => t.Name == "SwaggerWebHostFactory");

return (customFactoryType != null)
? startupAssembly.CreateInstance(customFactoryType.FullName) as ISwaggerWebHostFactory
: new DefaultSwaggerWebHostFactory(startupAssembly);
if (!factoryTypes.Any())
{
return WebHost.CreateDefaultBuilder()
.UseStartup(startupAssembly.FullName)
.Build();
}

if (factoryTypes.Count() > 1)
throw new InvalidOperationException("Multiple SwaggerWebHostFactory classes detected");

var factoryMethod = factoryTypes
.Single()
.GetMethod("CreateWebHost", BindingFlags.Public | BindingFlags.Static);

if (factoryMethod == null || factoryMethod.ReturnType != typeof(IWebHost))
throw new InvalidOperationException(
"SwaggerWebHostFactory class detected but does not contain a public static method " +
"called CreateWebHost with return type IWebHost");

return (IWebHost)factoryMethod.Invoke(null, null);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,17 @@
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Readers;
using Microsoft.VisualStudio.TestPlatform.Utilities;
using Xunit;
using Xunit.Abstractions;
using ReDocApp = ReDoc;

namespace Swashbuckle.AspNetCore.IntegrationTests
{
public class SwaggerGenIntegrationTests
{
private readonly ITestOutputHelper _output;

public SwaggerGenIntegrationTests(ITestOutputHelper output)
{
_output = output;
}

[Theory]
[InlineData(typeof(Basic.Startup), "/swagger/v1/swagger.json")]
[InlineData(typeof(CliExample.Startup), "/api-docs/v1/swagger.json")]
Expand Down
5 changes: 2 additions & 3 deletions test/WebSites/CliExampleWithFactory/SwaggerWebHostFactory.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
using Microsoft.AspNetCore.Hosting;
using Swashbuckle.AspNetCore.Cli;

namespace CliExampleWithFactory
{
public class MySwaggerWebHostFactory : ISwaggerWebHostFactory
public class SwaggerWebHostFactory
{
public IWebHost BuildWebHost()
public static IWebHost CreateWebHost()
{
return Program.BuildWebHost(new string[0]);
}
Expand Down

0 comments on commit 0a7420c

Please sign in to comment.