Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#2765 Allow Filter instance reuse #2839

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ jobs:
- name: Checkout code
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4

- name: Setup .NET SDKs
uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 # v4.0.0
with:
dotnet-version: |
6.0.x
7.0.x
- name: Setup .NET SDK
uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 # v4.0.0
id: setup-dotnet
Expand Down
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<PackageVersion Include="Microsoft.OpenApi.Readers" Version="1.6.14" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="NSubstitute" Version="5.1.0" />
<PackageVersion Include="Nswag.MSbuild" Version="13.17.0" />
<PackageVersion Include="ReportGenerator" Version="5.2.2" />
<PackageVersion Include="System.Text.Json" Version="4.6.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public void Configure(SchemaGeneratorOptions options)

// Create and add any filters that were specified through the FilterDescriptor lists
_swaggerGenOptions.SchemaFilterDescriptors.ForEach(
filterDescriptor => options.SchemaFilters.Add(CreateFilter<ISchemaFilter>(filterDescriptor)));
filterDescriptor => options.SchemaFilters.Add(GetOrCreateFilter<ISchemaFilter>(filterDescriptor)));
}

private void DeepCopy(SchemaGeneratorOptions source, SchemaGeneratorOptions target)
Expand All @@ -44,10 +44,10 @@ private void DeepCopy(SchemaGeneratorOptions source, SchemaGeneratorOptions targ
target.SchemaFilters = new List<ISchemaFilter>(source.SchemaFilters);
}

private TFilter CreateFilter<TFilter>(FilterDescriptor filterDescriptor)
private TFilter GetOrCreateFilter<TFilter>(FilterDescriptor filterDescriptor)
{
return (TFilter)ActivatorUtilities
.CreateInstance(_serviceProvider, filterDescriptor.Type, filterDescriptor.Arguments);
return (TFilter)(filterDescriptor.FilterInstance
?? ActivatorUtilities.CreateInstance(_serviceProvider, filterDescriptor.Type, filterDescriptor.Arguments));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,16 @@ public void Configure(SwaggerGeneratorOptions options)
// Create and add any filters that were specified through the FilterDescriptor lists ...

_swaggerGenOptions.ParameterFilterDescriptors.ForEach(
filterDescriptor => options.ParameterFilters.Add(CreateFilter<IParameterFilter>(filterDescriptor)));
filterDescriptor => options.ParameterFilters.Add(GetOrCreateFilter<IParameterFilter>(filterDescriptor)));

_swaggerGenOptions.RequestBodyFilterDescriptors.ForEach(
filterDescriptor => options.RequestBodyFilters.Add(CreateFilter<IRequestBodyFilter>(filterDescriptor)));
filterDescriptor => options.RequestBodyFilters.Add(GetOrCreateFilter<IRequestBodyFilter>(filterDescriptor)));

_swaggerGenOptions.OperationFilterDescriptors.ForEach(
filterDescriptor => options.OperationFilters.Add(CreateFilter<IOperationFilter>(filterDescriptor)));
filterDescriptor => options.OperationFilters.Add(GetOrCreateFilter<IOperationFilter>(filterDescriptor)));

_swaggerGenOptions.DocumentFilterDescriptors.ForEach(
filterDescriptor => options.DocumentFilters.Add(CreateFilter<IDocumentFilter>(filterDescriptor)));
filterDescriptor => options.DocumentFilters.Add(GetOrCreateFilter<IDocumentFilter>(filterDescriptor)));

if (!options.SwaggerDocs.Any())
{
Expand Down Expand Up @@ -74,10 +74,10 @@ public void DeepCopy(SwaggerGeneratorOptions source, SwaggerGeneratorOptions tar
target.SecuritySchemesSelector = source.SecuritySchemesSelector;
}

private TFilter CreateFilter<TFilter>(FilterDescriptor filterDescriptor)
private TFilter GetOrCreateFilter<TFilter>(FilterDescriptor filterDescriptor)
{
return (TFilter)ActivatorUtilities
.CreateInstance(_serviceProvider, filterDescriptor.Type, filterDescriptor.Arguments);
return (TFilter)(filterDescriptor.FilterInstance
?? ActivatorUtilities.CreateInstance(_serviceProvider, filterDescriptor.Type, filterDescriptor.Arguments));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,7 @@ public class FilterDescriptor
public Type Type { get; set; }

public object[] Arguments { get; set; }

public object FilterInstance { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -328,93 +328,193 @@ public static void InferSecuritySchemes(
/// <summary>
/// Extend the Swagger Generator with "filters" that can modify Schemas after they're initially generated
/// </summary>
/// <typeparam name="TFilter">A type that derives from ISchemaFilter</typeparam>
/// <typeparam name="TFilter">A type that derives from <see cref="ISchemaFilter"/></typeparam>
/// <param name="swaggerGenOptions"></param>
/// <param name="arguments">Optionally inject parameters through filter constructors</param>
public static void SchemaFilter<TFilter>(
this SwaggerGenOptions swaggerGenOptions,
params object[] arguments)
where TFilter : ISchemaFilter
{
if (swaggerGenOptions == null) throw new ArgumentNullException(nameof(swaggerGenOptions));
swaggerGenOptions.SchemaFilterDescriptors.Add(new FilterDescriptor
{
Type = typeof(TFilter),
Arguments = arguments
});
}

/// <summary>
/// Extend the Swagger Generator with "filters" that can modify Schemas after they're initially generated
/// </summary>
/// <typeparam name="TFilter">A type that derives from <see cref="ISchemaFilter"/></typeparam>
/// <param name="swaggerGenOptions"></param>
/// <param name="filterInstance">The filter instance to use.</param>
public static void AddSchemaFilterInstance<TFilter>(
this SwaggerGenOptions swaggerGenOptions,
TFilter filterInstance)
where TFilter : ISchemaFilter
{
if (swaggerGenOptions == null) throw new ArgumentNullException(nameof(swaggerGenOptions));
if (filterInstance == null) throw new ArgumentNullException(nameof(filterInstance));
swaggerGenOptions.SchemaFilterDescriptors.Add(new FilterDescriptor
{
FilterInstance = filterInstance
});
}

/// <summary>
/// Extend the Swagger Generator with "filters" that can modify Parameters after they're initially generated
/// </summary>
/// <typeparam name="TFilter">A type that derives from IParameterFilter</typeparam>
/// <typeparam name="TFilter">A type that derives from <see cref="IParameterFilter"/></typeparam>
/// <param name="swaggerGenOptions"></param>
/// <param name="arguments">Optionally inject parameters through filter constructors</param>
public static void ParameterFilter<TFilter>(
this SwaggerGenOptions swaggerGenOptions,
params object[] arguments)
where TFilter : IParameterFilter
{
if (swaggerGenOptions == null) throw new ArgumentNullException(nameof(swaggerGenOptions));
swaggerGenOptions.ParameterFilterDescriptors.Add(new FilterDescriptor
{
Type = typeof(TFilter),
Arguments = arguments
});
}

/// <summary>
/// Extend the Swagger Generator with "filters" that can modify Parameters after they're initially generated
/// </summary>
/// <typeparam name="TFilter">A type that derives from <see cref="IParameterFilter"/></typeparam>
/// <param name="swaggerGenOptions"></param>
/// <param name="filterInstance">The filter instance to use.</param>
public static void AddParameterFilterInstance<TFilter>(
this SwaggerGenOptions swaggerGenOptions,
TFilter filterInstance)
where TFilter : IParameterFilter
{
if (swaggerGenOptions == null) throw new ArgumentNullException(nameof(swaggerGenOptions));
if (filterInstance == null) throw new ArgumentNullException(nameof(filterInstance));
swaggerGenOptions.ParameterFilterDescriptors.Add(new FilterDescriptor
{
FilterInstance = filterInstance
});
}

/// <summary>
/// Extend the Swagger Generator with "filters" that can modify RequestBodys after they're initially generated
/// </summary>
/// <typeparam name="TFilter">A type that derives from IRequestBodyFilter</typeparam>
/// <typeparam name="TFilter">A type that derives from <see cref="IRequestBodyFilter"/></typeparam>
/// <param name="swaggerGenOptions"></param>
/// <param name="arguments">Optionally inject parameters through filter constructors</param>
public static void RequestBodyFilter<TFilter>(
this SwaggerGenOptions swaggerGenOptions,
params object[] arguments)
where TFilter : IRequestBodyFilter
{
if (swaggerGenOptions == null) throw new ArgumentNullException(nameof(swaggerGenOptions));
swaggerGenOptions.RequestBodyFilterDescriptors.Add(new FilterDescriptor
{
Type = typeof(TFilter),
Arguments = arguments
});
}

/// <summary>
/// Extend the Swagger Generator with "filters" that can modify RequestBodys after they're initially generated
/// </summary>
/// <typeparam name="TFilter">A type that derives from <see cref="IRequestBodyFilter"/></typeparam>
/// <param name="swaggerGenOptions"></param>
/// <param name="filterInstance">The filter instance to use.</param>
public static void AddRequestBodyFilterInstance<TFilter>(
this SwaggerGenOptions swaggerGenOptions,
TFilter filterInstance)
where TFilter : IRequestBodyFilter
{
if (swaggerGenOptions == null) throw new ArgumentNullException(nameof(swaggerGenOptions));
if (filterInstance == null) throw new ArgumentNullException(nameof(filterInstance));
swaggerGenOptions.RequestBodyFilterDescriptors.Add(new FilterDescriptor
{
FilterInstance = filterInstance
});
}

/// <summary>
/// Extend the Swagger Generator with "filters" that can modify Operations after they're initially generated
/// </summary>
/// <typeparam name="TFilter">A type that derives from IOperationFilter</typeparam>
/// <typeparam name="TFilter">A type that derives from <see cref="IOperationFilter"/></typeparam>
/// <param name="swaggerGenOptions"></param>
/// <param name="arguments">Optionally inject parameters through filter constructors</param>
public static void OperationFilter<TFilter>(
this SwaggerGenOptions swaggerGenOptions,
params object[] arguments)
where TFilter : IOperationFilter
{
if (swaggerGenOptions == null) throw new ArgumentNullException(nameof(swaggerGenOptions));
swaggerGenOptions.OperationFilterDescriptors.Add(new FilterDescriptor
{
Type = typeof(TFilter),
Arguments = arguments
});
}

/// <summary>
/// Extend the Swagger Generator with "filters" that can modify Operations after they're initially generated
/// </summary>
/// <typeparam name="TFilter">A type that derives from <see cref="IOperationFilter"/></typeparam>
/// <param name="swaggerGenOptions"></param>
/// <param name="filterInstance">The filter instance to use.</param>
public static void AddOperationFilterInstance<TFilter>(
this SwaggerGenOptions swaggerGenOptions,
TFilter filterInstance)
martincostello marked this conversation as resolved.
Show resolved Hide resolved
where TFilter : IOperationFilter
{
if (swaggerGenOptions == null) throw new ArgumentNullException(nameof(swaggerGenOptions));
if (filterInstance == null) throw new ArgumentNullException(nameof(filterInstance));
swaggerGenOptions.OperationFilterDescriptors.Add(new FilterDescriptor
{
FilterInstance = filterInstance
});
}

/// <summary>
/// Extend the Swagger Generator with "filters" that can modify SwaggerDocuments after they're initially generated
/// </summary>
/// <typeparam name="TFilter">A type that derives from IDocumentFilter</typeparam>
/// <typeparam name="TFilter">A type that derives from <see cref="IDocumentFilter"/></typeparam>
/// <param name="swaggerGenOptions"></param>
/// <param name="arguments">Optionally inject parameters through filter constructors</param>
public static void DocumentFilter<TFilter>(
this SwaggerGenOptions swaggerGenOptions,
params object[] arguments)
where TFilter : IDocumentFilter
{
if (swaggerGenOptions == null) throw new ArgumentNullException(nameof(swaggerGenOptions));
swaggerGenOptions.DocumentFilterDescriptors.Add(new FilterDescriptor
{
Type = typeof(TFilter),
Arguments = arguments
});
}

/// <summary>
/// Extend the Swagger Generator with "filters" that can modify SwaggerDocuments after they're initially generated
/// </summary>
/// <typeparam name="TFilter">A type that derives from <see cref="IDocumentFilter"/></typeparam>
/// <param name="swaggerGenOptions"></param>
/// <param name="filterInstance">The filter instance to use.</param>
public static void AddDocumentFilterInstance<TFilter>(
this SwaggerGenOptions swaggerGenOptions,
TFilter filterInstance)
where TFilter : IDocumentFilter
{
if (swaggerGenOptions == null) throw new ArgumentNullException(nameof(swaggerGenOptions));
if (filterInstance == null) throw new ArgumentNullException(nameof(filterInstance));
swaggerGenOptions.DocumentFilterDescriptors.Add(new FilterDescriptor
martincostello marked this conversation as resolved.
Show resolved Hide resolved
{
FilterInstance = filterInstance
});
}

/// <summary>
/// Inject human-friendly descriptions for Operations, Parameters and Schemas based on XML Comment files
/// </summary>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,17 @@
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<InternalsVisibleTo Include="Swashbuckle.AspNetCore.IntegrationTests" Key="00240000048000009400000006020000002400005253413100040000010001000b80d002f0437a94c4f6d77dfc29ce54df1040f66374cb7122ec5ddab3907a6dfe609a07ffd49b9aa6731fe3f8de4da7979ddea73e949c86effc4bec3f469cc36e788cf58c42c4be755efd1afd996ccab9f0db3455b834219f6614d00fe0410cc307c4eced320fd65fcc501f135dc537d7d09dcc1d2a572d24f8459a86469ec5" />
<InternalsVisibleTo Include="Swashbuckle.AspNetCore.SwaggerGen.Test" Key="00240000048000009400000006020000002400005253413100040000010001000b80d002f0437a94c4f6d77dfc29ce54df1040f66374cb7122ec5ddab3907a6dfe609a07ffd49b9aa6731fe3f8de4da7979ddea73e949c86effc4bec3f469cc36e788cf58c42c4be755efd1afd996ccab9f0db3455b834219f6614d00fe0410cc307c4eced320fd65fcc501f135dc537d7d09dcc1d2a572d24f8459a86469ec5" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Swashbuckle.AspNetCore.Swagger\Swashbuckle.AspNetCore.Swagger.csproj" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="Microsoft.AspNetCore.Mvc.ApiExplorer"/>
<PackageReference Include="Microsoft.AspNetCore.Mvc.ApiExplorer" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.DataAnnotations" />
<PackageReference Include="System.Text.Json" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Swashbuckle.AspNetCore.ApiTesting\Swashbuckle.AspNetCore.ApiTesting.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)..\..\src\Swashbuckle.AspNetCore.ApiTesting\Swashbuckle.AspNetCore.ApiTesting.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<AssemblyOriginatorKeyFile>Swashbuckle.AspNetCore.IntegrationTests.snk</AssemblyOriginatorKeyFile>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)..\..\src\Swashbuckle.AspNetCore.Swagger\Swashbuckle.AspNetCore.Swagger.snk</AssemblyOriginatorKeyFile>
<NoWarn>$(NoWarn);8002</NoWarn>
<SignAssembly>true</SignAssembly>
<TargetFramework>net6.0</TargetFramework>
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -619,9 +619,9 @@ public void GenerateSchema_HonorsSerializerSetting_StringEnumConverter(
[InlineData(TypeNameHandling.Arrays, TypeNameAssemblyFormatHandling.Full, false,
null)]
[InlineData(TypeNameHandling.Objects, TypeNameAssemblyFormatHandling.Full, true,
"Swashbuckle.AspNetCore.TestSupport.{0}, Swashbuckle.AspNetCore.TestSupport, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")]
"Swashbuckle.AspNetCore.TestSupport.{0}, Swashbuckle.AspNetCore.TestSupport, Version=1.0.0.0, Culture=neutral, PublicKeyToken=62657d7474907593")]
[InlineData(TypeNameHandling.All, TypeNameAssemblyFormatHandling.Full, true,
"Swashbuckle.AspNetCore.TestSupport.{0}, Swashbuckle.AspNetCore.TestSupport, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")]
"Swashbuckle.AspNetCore.TestSupport.{0}, Swashbuckle.AspNetCore.TestSupport, Version=1.0.0.0, Culture=neutral, PublicKeyToken=62657d7474907593")]
[InlineData(TypeNameHandling.Auto, TypeNameAssemblyFormatHandling.Simple, true,
"Swashbuckle.AspNetCore.TestSupport.{0}, Swashbuckle.AspNetCore.TestSupport")]
public void GenerateSchema_HonorsSerializerSetting_TypeNameHandling(
Expand Down
Loading