diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 098d7ef25..e6f6ce731 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -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
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 75c6e8db9..99b2b5f33 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -22,6 +22,7 @@
+
diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/ConfigureSchemaGeneratorOptions.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/ConfigureSchemaGeneratorOptions.cs
index 565811584..723e1e12a 100644
--- a/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/ConfigureSchemaGeneratorOptions.cs
+++ b/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/ConfigureSchemaGeneratorOptions.cs
@@ -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(filterDescriptor)));
+ filterDescriptor => options.SchemaFilters.Add(GetOrCreateFilter(filterDescriptor)));
}
private void DeepCopy(SchemaGeneratorOptions source, SchemaGeneratorOptions target)
@@ -44,10 +44,10 @@ private void DeepCopy(SchemaGeneratorOptions source, SchemaGeneratorOptions targ
target.SchemaFilters = new List(source.SchemaFilters);
}
- private TFilter CreateFilter(FilterDescriptor filterDescriptor)
+ private TFilter GetOrCreateFilter(FilterDescriptor filterDescriptor)
{
- return (TFilter)ActivatorUtilities
- .CreateInstance(_serviceProvider, filterDescriptor.Type, filterDescriptor.Arguments);
+ return (TFilter)(filterDescriptor.FilterInstance
+ ?? ActivatorUtilities.CreateInstance(_serviceProvider, filterDescriptor.Type, filterDescriptor.Arguments));
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/ConfigureSwaggerGeneratorOptions.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/ConfigureSwaggerGeneratorOptions.cs
index 72744ed5c..fce2c752b 100644
--- a/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/ConfigureSwaggerGeneratorOptions.cs
+++ b/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/ConfigureSwaggerGeneratorOptions.cs
@@ -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(filterDescriptor)));
+ filterDescriptor => options.ParameterFilters.Add(GetOrCreateFilter(filterDescriptor)));
_swaggerGenOptions.RequestBodyFilterDescriptors.ForEach(
- filterDescriptor => options.RequestBodyFilters.Add(CreateFilter(filterDescriptor)));
+ filterDescriptor => options.RequestBodyFilters.Add(GetOrCreateFilter(filterDescriptor)));
_swaggerGenOptions.OperationFilterDescriptors.ForEach(
- filterDescriptor => options.OperationFilters.Add(CreateFilter(filterDescriptor)));
+ filterDescriptor => options.OperationFilters.Add(GetOrCreateFilter(filterDescriptor)));
_swaggerGenOptions.DocumentFilterDescriptors.ForEach(
- filterDescriptor => options.DocumentFilters.Add(CreateFilter(filterDescriptor)));
+ filterDescriptor => options.DocumentFilters.Add(GetOrCreateFilter(filterDescriptor)));
if (!options.SwaggerDocs.Any())
{
@@ -74,10 +74,10 @@ public void DeepCopy(SwaggerGeneratorOptions source, SwaggerGeneratorOptions tar
target.SecuritySchemesSelector = source.SecuritySchemesSelector;
}
- private TFilter CreateFilter(FilterDescriptor filterDescriptor)
+ private TFilter GetOrCreateFilter(FilterDescriptor filterDescriptor)
{
- return (TFilter)ActivatorUtilities
- .CreateInstance(_serviceProvider, filterDescriptor.Type, filterDescriptor.Arguments);
+ return (TFilter)(filterDescriptor.FilterInstance
+ ?? ActivatorUtilities.CreateInstance(_serviceProvider, filterDescriptor.Type, filterDescriptor.Arguments));
}
}
}
diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/SwaggerGenOptions.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/SwaggerGenOptions.cs
index af02a9201..edf5e9b32 100644
--- a/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/SwaggerGenOptions.cs
+++ b/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/SwaggerGenOptions.cs
@@ -30,5 +30,7 @@ public class FilterDescriptor
public Type Type { get; set; }
public object[] Arguments { get; set; }
+
+ public object FilterInstance { get; set; }
}
}
diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/SwaggerGenOptionsExtensions.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/SwaggerGenOptionsExtensions.cs
index e03819bea..92aa46629 100644
--- a/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/SwaggerGenOptionsExtensions.cs
+++ b/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/SwaggerGenOptionsExtensions.cs
@@ -328,7 +328,7 @@ public static void SupportNonNullableReferenceTypes(this SwaggerGenOptions swagg
///
/// Extend the Swagger Generator with "filters" that can modify Schemas after they're initially generated
///
- /// A type that derives from ISchemaFilter
+ /// A type that derives from
///
/// Optionally inject parameters through filter constructors
public static void SchemaFilter(
@@ -336,6 +336,7 @@ public static void SupportNonNullableReferenceTypes(this SwaggerGenOptions swagg
params object[] arguments)
where TFilter : ISchemaFilter
{
+ if (swaggerGenOptions == null) throw new ArgumentNullException(nameof(swaggerGenOptions));
swaggerGenOptions.SchemaFilterDescriptors.Add(new FilterDescriptor
{
Type = typeof(TFilter),
@@ -343,10 +344,29 @@ public static void SupportNonNullableReferenceTypes(this SwaggerGenOptions swagg
});
}
+ ///
+ /// Extend the Swagger Generator with "filters" that can modify Schemas after they're initially generated
+ ///
+ /// A type that derives from
+ ///
+ /// The filter instance to use.
+ public static void AddSchemaFilterInstance(
+ 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
+ });
+ }
+
///
/// Extend the Swagger Generator with "filters" that can modify Parameters after they're initially generated
///
- /// A type that derives from IParameterFilter
+ /// A type that derives from
///
/// Optionally inject parameters through filter constructors
public static void ParameterFilter(
@@ -354,6 +374,7 @@ public static void SupportNonNullableReferenceTypes(this SwaggerGenOptions swagg
params object[] arguments)
where TFilter : IParameterFilter
{
+ if (swaggerGenOptions == null) throw new ArgumentNullException(nameof(swaggerGenOptions));
swaggerGenOptions.ParameterFilterDescriptors.Add(new FilterDescriptor
{
Type = typeof(TFilter),
@@ -361,10 +382,29 @@ public static void SupportNonNullableReferenceTypes(this SwaggerGenOptions swagg
});
}
+ ///
+ /// Extend the Swagger Generator with "filters" that can modify Parameters after they're initially generated
+ ///
+ /// A type that derives from
+ ///
+ /// The filter instance to use.
+ public static void AddParameterFilterInstance(
+ 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
+ });
+ }
+
///
/// Extend the Swagger Generator with "filters" that can modify RequestBodys after they're initially generated
///
- /// A type that derives from IRequestBodyFilter
+ /// A type that derives from
///
/// Optionally inject parameters through filter constructors
public static void RequestBodyFilter(
@@ -372,6 +412,7 @@ public static void SupportNonNullableReferenceTypes(this SwaggerGenOptions swagg
params object[] arguments)
where TFilter : IRequestBodyFilter
{
+ if (swaggerGenOptions == null) throw new ArgumentNullException(nameof(swaggerGenOptions));
swaggerGenOptions.RequestBodyFilterDescriptors.Add(new FilterDescriptor
{
Type = typeof(TFilter),
@@ -379,10 +420,29 @@ public static void SupportNonNullableReferenceTypes(this SwaggerGenOptions swagg
});
}
+ ///
+ /// Extend the Swagger Generator with "filters" that can modify RequestBodys after they're initially generated
+ ///
+ /// A type that derives from
+ ///
+ /// The filter instance to use.
+ public static void AddRequestBodyFilterInstance(
+ 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
+ });
+ }
+
///
/// Extend the Swagger Generator with "filters" that can modify Operations after they're initially generated
///
- /// A type that derives from IOperationFilter
+ /// A type that derives from
///
/// Optionally inject parameters through filter constructors
public static void OperationFilter(
@@ -390,6 +450,7 @@ public static void SupportNonNullableReferenceTypes(this SwaggerGenOptions swagg
params object[] arguments)
where TFilter : IOperationFilter
{
+ if (swaggerGenOptions == null) throw new ArgumentNullException(nameof(swaggerGenOptions));
swaggerGenOptions.OperationFilterDescriptors.Add(new FilterDescriptor
{
Type = typeof(TFilter),
@@ -397,10 +458,29 @@ public static void SupportNonNullableReferenceTypes(this SwaggerGenOptions swagg
});
}
+ ///
+ /// Extend the Swagger Generator with "filters" that can modify Operations after they're initially generated
+ ///
+ /// A type that derives from
+ ///
+ /// The filter instance to use.
+ public static void AddOperationFilterInstance(
+ this SwaggerGenOptions swaggerGenOptions,
+ TFilter filterInstance)
+ 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
+ });
+ }
+
///
/// Extend the Swagger Generator with "filters" that can modify SwaggerDocuments after they're initially generated
///
- /// A type that derives from IDocumentFilter
+ /// A type that derives from
///
/// Optionally inject parameters through filter constructors
public static void DocumentFilter(
@@ -408,6 +488,7 @@ public static void SupportNonNullableReferenceTypes(this SwaggerGenOptions swagg
params object[] arguments)
where TFilter : IDocumentFilter
{
+ if (swaggerGenOptions == null) throw new ArgumentNullException(nameof(swaggerGenOptions));
swaggerGenOptions.DocumentFilterDescriptors.Add(new FilterDescriptor
{
Type = typeof(TFilter),
@@ -415,6 +496,25 @@ public static void SupportNonNullableReferenceTypes(this SwaggerGenOptions swagg
});
}
+ ///
+ /// Extend the Swagger Generator with "filters" that can modify SwaggerDocuments after they're initially generated
+ ///
+ /// A type that derives from
+ ///
+ /// The filter instance to use.
+ public static void AddDocumentFilterInstance(
+ 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
+ {
+ FilterInstance = filterInstance
+ });
+ }
+
///
/// Inject human-friendly descriptions for Operations, Parameters and Schemas based on XML Comment files
///
diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/Properties/AssemblyInfo.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/Properties/AssemblyInfo.cs
deleted file mode 100644
index 3469cd4c8..000000000
--- a/src/Swashbuckle.AspNetCore.SwaggerGen/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,3 +0,0 @@
-using System.Runtime.CompilerServices;
-
-[assembly: InternalsVisibleTo("Swashbuckle.AspNetCore.IntegrationTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100795482b2b019ad690196ad34ca1d13abb1c3ed0e24fdaea1ca82ca11462a2d883e149864773aada8b40f41c1b1ea7824f23fb569cfc20e9fd03763896a2905fa23e1a62a940d40d14e3107e8cf90f6d705848e39fe25121a7f8c1cd5dcd6701aea982d13c4a42b3a0766dfc27fc02fa40194ed0a7841a8768d33f7aaabde87a7")]
diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/Swashbuckle.AspNetCore.SwaggerGen.csproj b/src/Swashbuckle.AspNetCore.SwaggerGen/Swashbuckle.AspNetCore.SwaggerGen.csproj
index 6ca886944..b1c83aec8 100644
--- a/src/Swashbuckle.AspNetCore.SwaggerGen/Swashbuckle.AspNetCore.SwaggerGen.csproj
+++ b/src/Swashbuckle.AspNetCore.SwaggerGen/Swashbuckle.AspNetCore.SwaggerGen.csproj
@@ -10,12 +10,17 @@
netstandard2.0;netcoreapp3.0;net5.0;net6.0;net7.0
+
+
+
+
+
-
+
diff --git a/test/Swashbuckle.AspNetCore.ApiTesting.Test/Swashbuckle.AspNetCore.ApiTesting.Test.csproj b/test/Swashbuckle.AspNetCore.ApiTesting.Test/Swashbuckle.AspNetCore.ApiTesting.Test.csproj
index 8bd159a0b..8d7539a5a 100644
--- a/test/Swashbuckle.AspNetCore.ApiTesting.Test/Swashbuckle.AspNetCore.ApiTesting.Test.csproj
+++ b/test/Swashbuckle.AspNetCore.ApiTesting.Test/Swashbuckle.AspNetCore.ApiTesting.Test.csproj
@@ -5,7 +5,7 @@
-
+
diff --git a/test/Swashbuckle.AspNetCore.IntegrationTests/Swashbuckle.AspNetCore.IntegrationTests.csproj b/test/Swashbuckle.AspNetCore.IntegrationTests/Swashbuckle.AspNetCore.IntegrationTests.csproj
index 14cfb486f..e2012d92a 100644
--- a/test/Swashbuckle.AspNetCore.IntegrationTests/Swashbuckle.AspNetCore.IntegrationTests.csproj
+++ b/test/Swashbuckle.AspNetCore.IntegrationTests/Swashbuckle.AspNetCore.IntegrationTests.csproj
@@ -1,7 +1,7 @@
- Swashbuckle.AspNetCore.IntegrationTests.snk
+ $(MSBuildThisFileDirectory)..\..\src\Swashbuckle.AspNetCore.Swagger\Swashbuckle.AspNetCore.Swagger.snk
$(NoWarn);8002
true
net6.0
diff --git a/test/Swashbuckle.AspNetCore.IntegrationTests/Swashbuckle.AspNetCore.IntegrationTests.snk b/test/Swashbuckle.AspNetCore.IntegrationTests/Swashbuckle.AspNetCore.IntegrationTests.snk
deleted file mode 100644
index bef10bbfc..000000000
Binary files a/test/Swashbuckle.AspNetCore.IntegrationTests/Swashbuckle.AspNetCore.IntegrationTests.snk and /dev/null differ
diff --git a/test/Swashbuckle.AspNetCore.Newtonsoft.Test/SchemaGenerator/NewtonsoftSchemaGeneratorTests.cs b/test/Swashbuckle.AspNetCore.Newtonsoft.Test/SchemaGenerator/NewtonsoftSchemaGeneratorTests.cs
index fa4e9f79f..d2d7ad984 100644
--- a/test/Swashbuckle.AspNetCore.Newtonsoft.Test/SchemaGenerator/NewtonsoftSchemaGeneratorTests.cs
+++ b/test/Swashbuckle.AspNetCore.Newtonsoft.Test/SchemaGenerator/NewtonsoftSchemaGeneratorTests.cs
@@ -619,9 +619,9 @@ public void GenerateSchema_Errors_IfTypesHaveConflictingSchemaIds()
[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(
diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/ConfigureSchemaGeneratorOptionsTests.cs b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/ConfigureSchemaGeneratorOptionsTests.cs
index b430a2164..3a4471c44 100644
--- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/ConfigureSchemaGeneratorOptionsTests.cs
+++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/ConfigureSchemaGeneratorOptionsTests.cs
@@ -1,4 +1,9 @@
-using System.Reflection;
+using System.Linq;
+using System.Reflection;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+using NSubstitute;
using Xunit;
namespace Swashbuckle.AspNetCore.SwaggerGen.Test;
@@ -15,4 +20,45 @@ public static void DeepCopy_Copies_All_Properties()
// to SwaggerGeneratorOptions and ConfigureSchemaGeneratorOptions.DeepCopy() needs to be updated
Assert.Equal(12, publicProperties.Length);
}
+
+ [Fact]
+ public static void AddingSchemaFilterInstances_WhenConfiguringOptions_SameInstanceIsAdded()
+ {
+ var webhostingEnvironment = Substitute.For();
+ webhostingEnvironment.ApplicationName.Returns("Swashbuckle.AspNetCore.SwaggerGen.Test");
+
+ var testSchemaFilter = new TestSchemaFilter();
+
+ var options = new SwaggerGenOptions();
+ options.AddSchemaFilterInstance(testSchemaFilter);
+ options.AddSchemaFilterInstance(testSchemaFilter);
+
+ var configureSchemaGeneratorOptions = new ConfigureSchemaGeneratorOptions(Options.Create(options), null);
+ var schemaGeneratorOptions = new SchemaGeneratorOptions();
+
+ configureSchemaGeneratorOptions.Configure(schemaGeneratorOptions);
+
+ Assert.Equal(2, schemaGeneratorOptions.SchemaFilters.Count);
+ Assert.Same(testSchemaFilter, schemaGeneratorOptions.SchemaFilters.First());
+ Assert.Same(testSchemaFilter, schemaGeneratorOptions.SchemaFilters.Last());
+ }
+
+ [Fact]
+ public static void AddingSchemaFilterTypes_WhenConfiguringOptions_DifferentInstancesAreAdded()
+ {
+ var webhostingEnvironment = Substitute.For();
+ webhostingEnvironment.ApplicationName.Returns("Swashbuckle.AspNetCore.SwaggerGen.Test");
+
+ var options = new SwaggerGenOptions();
+ options.SchemaFilter();
+ options.SchemaFilter();
+
+ var configureSchemaGeneratorOptions = new ConfigureSchemaGeneratorOptions(Options.Create(options), null);
+ var schemaGeneratorOptions = new SchemaGeneratorOptions();
+
+ configureSchemaGeneratorOptions.Configure(schemaGeneratorOptions);
+
+ Assert.Equal(2, schemaGeneratorOptions.SchemaFilters.Count);
+ Assert.NotSame(schemaGeneratorOptions.SchemaFilters.First(), schemaGeneratorOptions.SchemaFilters.Last());
+ }
}
diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/ConfigureSwaggerGeneratorOptionsTests.cs b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/ConfigureSwaggerGeneratorOptionsTests.cs
index 39d3f4085..ca6a1c809 100644
--- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/ConfigureSwaggerGeneratorOptionsTests.cs
+++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/ConfigureSwaggerGeneratorOptionsTests.cs
@@ -1,4 +1,9 @@
-using System.Reflection;
+using System.Linq;
+using System.Reflection;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+using NSubstitute;
using Xunit;
namespace Swashbuckle.AspNetCore.SwaggerGen.Test;
@@ -15,4 +20,192 @@ public static void DeepCopy_Copies_All_Properties()
// to SwaggerGeneratorOptions and ConfigureSwaggerGeneratorOptions.DeepCopy() needs to be updated
Assert.Equal(18, publicProperties.Length);
}
+
+ [Fact]
+ public static void AddingParameterFilterInstances_WhenConfiguringOptions_SameInstanceIsAdded()
+ {
+ var webhostingEnvironment = Substitute.For();
+ webhostingEnvironment.ApplicationName.Returns("Swashbuckle.AspNetCore.SwaggerGen.Test");
+
+ var testParameterFilter = new TestParameterFilter();
+
+ var options = new SwaggerGenOptions();
+ options.AddParameterFilterInstance(testParameterFilter);
+ options.AddParameterFilterInstance(testParameterFilter);
+
+ var configureSwaggerGeneratorOptions = new ConfigureSwaggerGeneratorOptions(
+ Options.Create(options),
+ null,
+ webhostingEnvironment);
+ var swaggerGeneratorOptions = new SwaggerGeneratorOptions();
+
+ configureSwaggerGeneratorOptions.Configure(swaggerGeneratorOptions);
+
+ Assert.Equal(2, swaggerGeneratorOptions.ParameterFilters.Count);
+ Assert.Same(testParameterFilter, swaggerGeneratorOptions.ParameterFilters.First());
+ Assert.Same(testParameterFilter, swaggerGeneratorOptions.ParameterFilters.Last());
+ }
+
+ [Fact]
+ public static void AddingParameterFilterTypes_WhenConfiguringOptions_DifferentInstancesAreAdded()
+ {
+ var webhostingEnvironment = Substitute.For();
+ webhostingEnvironment.ApplicationName.Returns("Swashbuckle.AspNetCore.SwaggerGen.Test");
+
+ var options = new SwaggerGenOptions();
+ options.ParameterFilter();
+ options.ParameterFilter();
+
+ var configureSwaggerGeneratorOptions = new ConfigureSwaggerGeneratorOptions(
+ Options.Create(options),
+ null,
+ webhostingEnvironment);
+ var swaggerGeneratorOptions = new SwaggerGeneratorOptions();
+
+ configureSwaggerGeneratorOptions.Configure(swaggerGeneratorOptions);
+
+ Assert.Equal(2, swaggerGeneratorOptions.ParameterFilters.Count);
+ Assert.NotSame(swaggerGeneratorOptions.ParameterFilters.First(), swaggerGeneratorOptions.ParameterFilters.Last());
+ }
+
+ [Fact]
+ public static void AddingRequestBodyFilterInstances_WhenConfiguringOptions_SameInstanceIsAdded()
+ {
+ var webhostingEnvironment = Substitute.For();
+ webhostingEnvironment.ApplicationName.Returns("Swashbuckle.AspNetCore.SwaggerGen.Test");
+
+ var testRequestBodyFilter = new TestRequestBodyFilter();
+
+ var options = new SwaggerGenOptions();
+ options.AddRequestBodyFilterInstance(testRequestBodyFilter);
+ options.AddRequestBodyFilterInstance(testRequestBodyFilter);
+
+ var configureSwaggerGeneratorOptions = new ConfigureSwaggerGeneratorOptions(
+ Options.Create(options),
+ null,
+ webhostingEnvironment);
+ var swaggerGeneratorOptions = new SwaggerGeneratorOptions();
+
+ configureSwaggerGeneratorOptions.Configure(swaggerGeneratorOptions);
+
+ Assert.Equal(2, swaggerGeneratorOptions.RequestBodyFilters.Count);
+ Assert.Same(testRequestBodyFilter, swaggerGeneratorOptions.RequestBodyFilters.First());
+ Assert.Same(testRequestBodyFilter, swaggerGeneratorOptions.RequestBodyFilters.Last());
+ }
+
+ [Fact]
+ public static void AddingRequestBodyFilterTypes_WhenConfiguringOptions_DifferentInstancesAreAdded()
+ {
+ var webhostingEnvironment = Substitute.For();
+ webhostingEnvironment.ApplicationName.Returns("Swashbuckle.AspNetCore.SwaggerGen.Test");
+
+ var options = new SwaggerGenOptions();
+ options.RequestBodyFilter();
+ options.RequestBodyFilter();
+
+ var configureSwaggerGeneratorOptions = new ConfigureSwaggerGeneratorOptions(
+ Options.Create(options),
+ null,
+ webhostingEnvironment);
+ var swaggerGeneratorOptions = new SwaggerGeneratorOptions();
+
+ configureSwaggerGeneratorOptions.Configure(swaggerGeneratorOptions);
+
+ Assert.Equal(2, swaggerGeneratorOptions.RequestBodyFilters.Count);
+ Assert.NotSame(swaggerGeneratorOptions.RequestBodyFilters.First(), swaggerGeneratorOptions.RequestBodyFilters.Last());
+ }
+
+ [Fact]
+ public static void AddingOperationFilterInstances_WhenConfiguringOptions_SameInstanceIsAdded()
+ {
+ var webhostingEnvironment = Substitute.For();
+ webhostingEnvironment.ApplicationName.Returns("Swashbuckle.AspNetCore.SwaggerGen.Test");
+
+ var testOperationFilter = new TestOperationFilter();
+
+ var options = new SwaggerGenOptions();
+ options.AddOperationFilterInstance(testOperationFilter);
+ options.AddOperationFilterInstance(testOperationFilter);
+
+ var configureSwaggerGeneratorOptions = new ConfigureSwaggerGeneratorOptions(
+ Options.Create(options),
+ null,
+ webhostingEnvironment);
+ var swaggerGeneratorOptions = new SwaggerGeneratorOptions();
+
+ configureSwaggerGeneratorOptions.Configure(swaggerGeneratorOptions);
+
+ Assert.Equal(2, swaggerGeneratorOptions.OperationFilters.Count);
+ Assert.Same(testOperationFilter, swaggerGeneratorOptions.OperationFilters.First());
+ Assert.Same(testOperationFilter, swaggerGeneratorOptions.OperationFilters.Last());
+ }
+
+ [Fact]
+ public static void AddingOperationFilterTypes_WhenConfiguringOptions_DifferentInstancesAreAdded()
+ {
+ var webhostingEnvironment = Substitute.For();
+ webhostingEnvironment.ApplicationName.Returns("Swashbuckle.AspNetCore.SwaggerGen.Test");
+
+ var options = new SwaggerGenOptions();
+ options.OperationFilter();
+ options.OperationFilter();
+
+ var configureSwaggerGeneratorOptions = new ConfigureSwaggerGeneratorOptions(
+ Options.Create(options),
+ null,
+ webhostingEnvironment);
+ var swaggerGeneratorOptions = new SwaggerGeneratorOptions();
+
+ configureSwaggerGeneratorOptions.Configure(swaggerGeneratorOptions);
+
+ Assert.Equal(2, swaggerGeneratorOptions.OperationFilters.Count);
+ Assert.NotSame(swaggerGeneratorOptions.OperationFilters.First(), swaggerGeneratorOptions.OperationFilters.Last());
+ }
+
+ [Fact]
+ public static void AddingDocumentFilterInstances_WhenConfiguringOptions_SameInstanceIsAdded()
+ {
+ var webhostingEnvironment = Substitute.For();
+ webhostingEnvironment.ApplicationName.Returns("Swashbuckle.AspNetCore.SwaggerGen.Test");
+
+ var testDocumentFilter = new TestDocumentFilter();
+
+ var options = new SwaggerGenOptions();
+ options.AddDocumentFilterInstance(testDocumentFilter);
+ options.AddDocumentFilterInstance(testDocumentFilter);
+
+ var configureSwaggerGeneratorOptions = new ConfigureSwaggerGeneratorOptions(
+ Options.Create(options),
+ null,
+ webhostingEnvironment);
+ var swaggerGeneratorOptions = new SwaggerGeneratorOptions();
+
+ configureSwaggerGeneratorOptions.Configure(swaggerGeneratorOptions);
+
+ Assert.Equal(2, swaggerGeneratorOptions.DocumentFilters.Count);
+ Assert.Same(testDocumentFilter, swaggerGeneratorOptions.DocumentFilters.First());
+ Assert.Same(testDocumentFilter, swaggerGeneratorOptions.DocumentFilters.Last());
+ }
+
+ [Fact]
+ public static void AddingDocumentFilterTypes_WhenConfiguringOptions_DifferentInstancesAreAdded()
+ {
+ var webhostingEnvironment = Substitute.For();
+ webhostingEnvironment.ApplicationName.Returns("Swashbuckle.AspNetCore.SwaggerGen.Test");
+
+ var options = new SwaggerGenOptions();
+ options.DocumentFilter();
+ options.DocumentFilter();
+
+ var configureSwaggerGeneratorOptions = new ConfigureSwaggerGeneratorOptions(
+ Options.Create(options),
+ null,
+ webhostingEnvironment);
+ var swaggerGeneratorOptions = new SwaggerGeneratorOptions();
+
+ configureSwaggerGeneratorOptions.Configure(swaggerGeneratorOptions);
+
+ Assert.Equal(2, swaggerGeneratorOptions.DocumentFilters.Count);
+ Assert.NotSame(swaggerGeneratorOptions.DocumentFilters.First(), swaggerGeneratorOptions.DocumentFilters.Last());
+ }
}
diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/Swashbuckle.AspNetCore.SwaggerGen.Test.csproj b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/Swashbuckle.AspNetCore.SwaggerGen.Test.csproj
index 0cb9c4236..6380c5ae5 100644
--- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/Swashbuckle.AspNetCore.SwaggerGen.Test.csproj
+++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/Swashbuckle.AspNetCore.SwaggerGen.Test.csproj
@@ -4,6 +4,8 @@
true
1701;1702;1591
net6.0;net7.0
+ True
+ $(MSBuildThisFileDirectory)..\..\src\Swashbuckle.AspNetCore.Swagger\Swashbuckle.AspNetCore.Swagger.snk
@@ -14,6 +16,7 @@
+
diff --git a/test/Swashbuckle.AspNetCore.TestSupport/Swashbuckle.AspNetCore.TestSupport.csproj b/test/Swashbuckle.AspNetCore.TestSupport/Swashbuckle.AspNetCore.TestSupport.csproj
index befe7167b..f29366bf0 100644
--- a/test/Swashbuckle.AspNetCore.TestSupport/Swashbuckle.AspNetCore.TestSupport.csproj
+++ b/test/Swashbuckle.AspNetCore.TestSupport/Swashbuckle.AspNetCore.TestSupport.csproj
@@ -6,6 +6,8 @@
false
1.0.0
+ True
+ $(MSBuildThisFileDirectory)..\..\src\Swashbuckle.AspNetCore.Swagger\Swashbuckle.AspNetCore.Swagger.snk