add support for including all assemblies xml docs in swagger ...
This commit is contained in:
+171
-86
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -12,8 +13,10 @@ using xCommons.Configurations;
|
||||
using xCommons.Constants;
|
||||
using xCommons.Filters;
|
||||
|
||||
namespace xCommons.Extensions {
|
||||
public static partial class DIExtensions {
|
||||
namespace xCommons.Extensions
|
||||
{
|
||||
public static partial class DIExtensions
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Inject Specific Registered Service from IServiceCollection
|
||||
@@ -21,10 +24,11 @@ namespace xCommons.Extensions {
|
||||
/// <param name="source"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static T GetRegisteredService<T> (this IServiceCollection source) {
|
||||
public static T GetRegisteredService<T>(this IServiceCollection source)
|
||||
{
|
||||
//
|
||||
var serviceProvider = source.BuildServiceProvider ();
|
||||
return serviceProvider.GetService<T> ();
|
||||
var serviceProvider = source.BuildServiceProvider();
|
||||
return serviceProvider.GetService<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -32,10 +36,55 @@ namespace xCommons.Extensions {
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="configuration"></param>
|
||||
public static void AddXAppConfiguration (this IServiceCollection services, IConfiguration configuration) {
|
||||
public static void AddXAppConfiguration(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
//
|
||||
var appConfiguration = configuration.GetXAppConfiguration ();
|
||||
services.AddSingleton<XAppConfiguration> (appConfiguration);
|
||||
var appConfiguration = configuration.GetXAppConfiguration();
|
||||
services.AddSingleton<XAppConfiguration>(appConfiguration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Search Assemblies, Extract XML Comments and
|
||||
/// Integrate them inside swagger gen documents ...
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
public static void IncludeAssembliesXMLComments(this SwaggerGenOptions source)
|
||||
{
|
||||
//
|
||||
// Extract all Exists .xml files ...
|
||||
var basePath = AppContext.BaseDirectory;
|
||||
var xmlFiles = Directory.GetFiles(basePath, "*.xml", SearchOption.TopDirectoryOnly);
|
||||
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||
|
||||
//
|
||||
// Loop through Detected XML Files ...
|
||||
foreach (var xmlFile in xmlFiles)
|
||||
{
|
||||
//
|
||||
try
|
||||
{
|
||||
//
|
||||
// Retrieve file name for Assembly Checking ...
|
||||
var assemblyName = Path.GetFileNameWithoutExtension(xmlFile);
|
||||
|
||||
//
|
||||
// Try to retrieve Assembly ...
|
||||
var assembly = assemblies
|
||||
.FirstOrDefault(a => a.GetName().Name == assemblyName);
|
||||
if (!assembly.IsNullOrDefault() ||
|
||||
File.Exists(Path.Combine(basePath, $"{assemblyName}.dll"))
|
||||
)
|
||||
{
|
||||
//
|
||||
// Includes Selected XML Comments ...
|
||||
source.IncludeXmlComments(xmlFile);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Warning: Could not include XML comments from {xmlFile}. Error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -46,51 +95,62 @@ namespace xCommons.Extensions {
|
||||
/// <param name="addRequiredXPoweredFilter"></param>
|
||||
/// <param name="addXTokenAuthorization"></param>
|
||||
/// <param name="addDefaultValueFilter"></param>
|
||||
public static void AddXSwaggerGenOptions (
|
||||
public static void AddXSwaggerGenOptions(
|
||||
this SwaggerGenOptions source,
|
||||
string xmlFilePath = null,
|
||||
bool addRequiredXPoweredFilter = true,
|
||||
bool addXTokenAuthorization = true,
|
||||
bool addDefaultValueFilter = true
|
||||
) {
|
||||
)
|
||||
{
|
||||
//
|
||||
if (source.IsNull ()) {
|
||||
source = new SwaggerGenOptions ();
|
||||
if (source.IsNull())
|
||||
{
|
||||
source = new SwaggerGenOptions();
|
||||
}
|
||||
|
||||
//
|
||||
// Add Xml File Path ...
|
||||
if (!xmlFilePath.IsNullOrEmpty ()) {
|
||||
source.IncludeXmlComments (xmlFilePath);
|
||||
if (!xmlFilePath.IsNullOrEmpty())
|
||||
{
|
||||
source.IncludeXmlComments(xmlFilePath);
|
||||
}
|
||||
|
||||
//
|
||||
// Include all XML Documents ...
|
||||
source.IncludeAssembliesXMLComments();
|
||||
|
||||
//
|
||||
// Handle RequireXPowered Filter ...
|
||||
if (addRequiredXPoweredFilter) {
|
||||
source.OperationFilter<RequireXPoweredOperationFilter> ();
|
||||
if (addRequiredXPoweredFilter)
|
||||
{
|
||||
source.OperationFilter<RequireXPoweredOperationFilter>();
|
||||
}
|
||||
|
||||
//
|
||||
// Add Default Values Filter ...
|
||||
if (addDefaultValueFilter) {
|
||||
source.OperationFilter<SwaggerDefaultValuesOperationFilter> ();
|
||||
if (addDefaultValueFilter)
|
||||
{
|
||||
source.OperationFilter<SwaggerDefaultValuesOperationFilter>();
|
||||
}
|
||||
|
||||
//
|
||||
// Handle XToken Authorizations ...
|
||||
if (addXTokenAuthorization) {
|
||||
if (addXTokenAuthorization)
|
||||
{
|
||||
//
|
||||
#region Bearer AccessToken ...
|
||||
//
|
||||
source.AddSecurityDefinition (nameof (XAuthorization.AccessToken), new OpenApiSecurityScheme {
|
||||
source.AddSecurityDefinition(nameof(XAuthorization.AccessToken), new OpenApiSecurityScheme
|
||||
{
|
||||
In = ParameterLocation.Header,
|
||||
Description = "Bearer token",
|
||||
Type = SecuritySchemeType.ApiKey,
|
||||
Name = XAuthorization.Header
|
||||
Description = "Bearer token",
|
||||
Type = SecuritySchemeType.ApiKey,
|
||||
Name = XAuthorization.Header
|
||||
});
|
||||
|
||||
//
|
||||
source.AddSecurityRequirement (new OpenApiSecurityRequirement {
|
||||
source.AddSecurityRequirement(new OpenApiSecurityRequirement {
|
||||
{
|
||||
new OpenApiSecurityScheme {
|
||||
Reference = new OpenApiReference {
|
||||
@@ -105,15 +165,16 @@ namespace xCommons.Extensions {
|
||||
//
|
||||
#region RefreshToken ...
|
||||
//
|
||||
source.AddSecurityDefinition (nameof (XAuthorization.RefreshToken), new OpenApiSecurityScheme {
|
||||
source.AddSecurityDefinition(nameof(XAuthorization.RefreshToken), new OpenApiSecurityScheme
|
||||
{
|
||||
In = ParameterLocation.Header,
|
||||
Description = "refresh token",
|
||||
Type = SecuritySchemeType.ApiKey,
|
||||
Name = nameof (XAuthorization.RefreshToken)
|
||||
Description = "refresh token",
|
||||
Type = SecuritySchemeType.ApiKey,
|
||||
Name = nameof(XAuthorization.RefreshToken)
|
||||
});
|
||||
|
||||
//
|
||||
source.AddSecurityRequirement (new OpenApiSecurityRequirement {
|
||||
source.AddSecurityRequirement(new OpenApiSecurityRequirement {
|
||||
{
|
||||
new OpenApiSecurityScheme {
|
||||
Reference = new OpenApiReference {
|
||||
@@ -128,15 +189,16 @@ namespace xCommons.Extensions {
|
||||
//
|
||||
#region ExpiresAt ...
|
||||
//
|
||||
source.AddSecurityDefinition (nameof (XAuthorization.ExpiresAt), new OpenApiSecurityScheme {
|
||||
source.AddSecurityDefinition(nameof(XAuthorization.ExpiresAt), new OpenApiSecurityScheme
|
||||
{
|
||||
In = ParameterLocation.Header,
|
||||
Description = "expires at",
|
||||
Type = SecuritySchemeType.ApiKey,
|
||||
Name = nameof (XAuthorization.ExpiresAt)
|
||||
Description = "expires at",
|
||||
Type = SecuritySchemeType.ApiKey,
|
||||
Name = nameof(XAuthorization.ExpiresAt)
|
||||
});
|
||||
|
||||
//
|
||||
source.AddSecurityRequirement (new OpenApiSecurityRequirement {
|
||||
source.AddSecurityRequirement(new OpenApiSecurityRequirement {
|
||||
{
|
||||
new OpenApiSecurityScheme {
|
||||
Reference = new OpenApiReference {
|
||||
@@ -160,7 +222,7 @@ namespace xCommons.Extensions {
|
||||
/// <param name="addRequiredXPoweredFilter"></param>
|
||||
/// <param name="addXTokenAuthorization"></param>
|
||||
/// <param name="addDefaultValueFilter"></param>
|
||||
public static void AddXSwagger (
|
||||
public static void AddXSwagger(
|
||||
this IServiceCollection source,
|
||||
IConfiguration configuration,
|
||||
SwaggerGenOptions settings = null,
|
||||
@@ -168,11 +230,13 @@ namespace xCommons.Extensions {
|
||||
bool addRequiredXPoweredFilter = true,
|
||||
bool addXTokenAuthorization = true,
|
||||
bool addDefaultValueFilter = true
|
||||
) {
|
||||
)
|
||||
{
|
||||
//
|
||||
var xSwaggerConfig = configuration.GetXSwaggerConfiguration ();
|
||||
if (xSwaggerConfig.IsNull ()) {
|
||||
xSwaggerConfig = new XSwaggerConfiguration ();
|
||||
var xSwaggerConfig = configuration.GetXSwaggerConfiguration();
|
||||
if (xSwaggerConfig.IsNull())
|
||||
{
|
||||
xSwaggerConfig = new XSwaggerConfiguration();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -180,10 +244,11 @@ namespace xCommons.Extensions {
|
||||
|
||||
//
|
||||
#region Prepare SwaggerGenOptions ...
|
||||
if (settings.IsNull ()) {
|
||||
settings = new SwaggerGenOptions ();
|
||||
if (settings.IsNull())
|
||||
{
|
||||
settings = new SwaggerGenOptions();
|
||||
}
|
||||
settings.AddXSwaggerGenOptions (
|
||||
settings.AddXSwaggerGenOptions(
|
||||
xmlFilePath: xmlFilePath,
|
||||
addDefaultValueFilter: addDefaultValueFilter,
|
||||
addXTokenAuthorization: addXTokenAuthorization,
|
||||
@@ -195,7 +260,8 @@ namespace xCommons.Extensions {
|
||||
#region Prepare Swagger Doc ...
|
||||
//
|
||||
// Api Document Section ...
|
||||
var apiDoc = new OpenApiInfo {
|
||||
var apiDoc = new OpenApiInfo
|
||||
{
|
||||
Title = xSwaggerConfig.Title,
|
||||
Version = xSwaggerConfig.Version,
|
||||
Description = xSwaggerConfig.Description,
|
||||
@@ -203,23 +269,27 @@ namespace xCommons.Extensions {
|
||||
|
||||
//
|
||||
// Api Document TermsOfUse URL ...
|
||||
if (!xSwaggerConfig.TermsOfServiceUrl.IsNullOrEmpty ()) {
|
||||
apiDoc.TermsOfService = new Uri (xSwaggerConfig.TermsOfServiceUrl);
|
||||
if (!xSwaggerConfig.TermsOfServiceUrl.IsNullOrEmpty())
|
||||
{
|
||||
apiDoc.TermsOfService = new Uri(xSwaggerConfig.TermsOfServiceUrl);
|
||||
}
|
||||
|
||||
//
|
||||
// Contact Section ...
|
||||
if (!xSwaggerConfig.Contact.IsNull ()) {
|
||||
if (!xSwaggerConfig.Contact.IsNull())
|
||||
{
|
||||
//
|
||||
var apiContact = new OpenApiContact {
|
||||
var apiContact = new OpenApiContact
|
||||
{
|
||||
Name = xSwaggerConfig.Contact.Name,
|
||||
Email = xSwaggerConfig.Contact.Email
|
||||
};
|
||||
|
||||
//
|
||||
// Contact URL ...
|
||||
if (!xSwaggerConfig.Contact.Url.IsNullOrEmpty ()) {
|
||||
apiContact.Url = new Uri (xSwaggerConfig.Contact.Url);
|
||||
if (!xSwaggerConfig.Contact.Url.IsNullOrEmpty())
|
||||
{
|
||||
apiContact.Url = new Uri(xSwaggerConfig.Contact.Url);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -228,16 +298,19 @@ namespace xCommons.Extensions {
|
||||
|
||||
//
|
||||
// License Section ...
|
||||
if (!xSwaggerConfig.License.IsNull ()) {
|
||||
if (!xSwaggerConfig.License.IsNull())
|
||||
{
|
||||
//
|
||||
var apiLicense = new OpenApiLicense {
|
||||
var apiLicense = new OpenApiLicense
|
||||
{
|
||||
Name = xSwaggerConfig.License.Name,
|
||||
};
|
||||
|
||||
//
|
||||
// License URL ...
|
||||
if (!xSwaggerConfig.License.Url.IsNullOrEmpty ()) {
|
||||
apiLicense.Url = new Uri (xSwaggerConfig.License.Url);
|
||||
if (!xSwaggerConfig.License.Url.IsNullOrEmpty())
|
||||
{
|
||||
apiLicense.Url = new Uri(xSwaggerConfig.License.Url);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -247,13 +320,14 @@ namespace xCommons.Extensions {
|
||||
|
||||
//
|
||||
// Register Swagger ...
|
||||
source.AddSwaggerGen (
|
||||
opt => {
|
||||
source.AddSwaggerGen(
|
||||
opt =>
|
||||
{
|
||||
//
|
||||
opt.UpdateData (settings);
|
||||
opt.UpdateData(settings);
|
||||
|
||||
//
|
||||
opt.SwaggerDoc ("v1", apiDoc);
|
||||
opt.SwaggerDoc("v1", apiDoc);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -266,18 +340,22 @@ namespace xCommons.Extensions {
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="options"></param>
|
||||
public static void UseXSwagger (
|
||||
public static void UseXSwagger(
|
||||
this IApplicationBuilder source,
|
||||
SwaggerUIOptions options = null
|
||||
) {
|
||||
)
|
||||
{
|
||||
//
|
||||
source.UseSwagger ();
|
||||
source.UseSwagger();
|
||||
|
||||
//
|
||||
if (options.IsNull ()) {
|
||||
source.UseSwaggerUI ();
|
||||
} else {
|
||||
source.UseSwaggerUI (options: options);
|
||||
if (options.IsNull())
|
||||
{
|
||||
source.UseSwaggerUI();
|
||||
}
|
||||
else
|
||||
{
|
||||
source.UseSwaggerUI(options: options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,24 +364,28 @@ namespace xCommons.Extensions {
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="allowedOrigins"></param>
|
||||
public static void AddXCors (
|
||||
public static void AddXCors(
|
||||
this IServiceCollection source,
|
||||
IEnumerable<string> allowedOrigins
|
||||
) {
|
||||
)
|
||||
{
|
||||
//
|
||||
if (!allowedOrigins.HasChild ()) {
|
||||
if (!allowedOrigins.HasChild())
|
||||
{
|
||||
//
|
||||
Console.WriteLine ($"XCommons: there is no provided allowedOrigins, start app without any specific cors, this may be unsecure ...");
|
||||
Console.WriteLine($"XCommons: there is no provided allowedOrigins, start app without any specific cors, this may be unsecure ...");
|
||||
|
||||
//
|
||||
source.AddCors (options => {
|
||||
options.AddPolicy (XPolicy.AllowedOrigins,
|
||||
builder => {
|
||||
source.AddCors(options =>
|
||||
{
|
||||
options.AddPolicy(XPolicy.AllowedOrigins,
|
||||
builder =>
|
||||
{
|
||||
builder
|
||||
.AllowAnyOrigin ()
|
||||
.AllowAnyHeader ()
|
||||
.AllowAnyMethod ()
|
||||
.WithExposedHeaders ("*");
|
||||
.AllowAnyOrigin()
|
||||
.AllowAnyHeader()
|
||||
.AllowAnyMethod()
|
||||
.WithExposedHeaders("*");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -312,15 +394,17 @@ namespace xCommons.Extensions {
|
||||
}
|
||||
|
||||
//
|
||||
source.AddCors (options => {
|
||||
options.AddPolicy (XPolicy.AllowedOrigins,
|
||||
builder => {
|
||||
source.AddCors(options =>
|
||||
{
|
||||
options.AddPolicy(XPolicy.AllowedOrigins,
|
||||
builder =>
|
||||
{
|
||||
builder
|
||||
.WithOrigins (allowedOrigins.ToArray ())
|
||||
.AllowAnyHeader ()
|
||||
.AllowAnyMethod ()
|
||||
.AllowCredentials ()
|
||||
.WithExposedHeaders ("*");
|
||||
.WithOrigins(allowedOrigins.ToArray())
|
||||
.AllowAnyHeader()
|
||||
.AllowAnyMethod()
|
||||
.AllowCredentials()
|
||||
.WithExposedHeaders("*");
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -329,9 +413,10 @@ namespace xCommons.Extensions {
|
||||
/// Use X Registered Cross Origin Resource Sharings
|
||||
/// </summary>
|
||||
/// <param name="sources"></param>
|
||||
public static void UseXCors (this IApplicationBuilder sources) {
|
||||
public static void UseXCors(this IApplicationBuilder sources)
|
||||
{
|
||||
//
|
||||
sources.UseCors (XPolicy.AllowedOrigins);
|
||||
sources.UseCors(XPolicy.AllowedOrigins);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -355,7 +440,7 @@ namespace xCommons.Extensions {
|
||||
//
|
||||
// Report All Available Api Versions on Response ...
|
||||
opt.ReportApiVersions = true;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -65,9 +65,9 @@
|
||||
|
||||
<!-- For XML Documentation Support -->
|
||||
<PropertyGroup>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<NoWarn>$(NoWarn);1591</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user