Skip to content

Commit 42c2c7d

Browse files
committed
Fail at startup when ASP.NET OpenAPI is registered
1 parent ffd1003 commit 42c2c7d

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

Diff for: src/JsonApiDotNetCore/Configuration/ApplicationBuilderExtensions.cs

+31
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using JsonApiDotNetCore.Middleware;
22
using Microsoft.AspNetCore.Builder;
33
using Microsoft.Extensions.DependencyInjection;
4+
using Microsoft.Extensions.Options;
45

56
namespace JsonApiDotNetCore.Configuration;
67

@@ -23,6 +24,7 @@ public static class ApplicationBuilderExtensions
2324
public static void UseJsonApi(this IApplicationBuilder builder)
2425
{
2526
ArgumentNullException.ThrowIfNull(builder);
27+
AssertAspNetCoreOpenApiIsNotRegistered(builder.ApplicationServices);
2628

2729
using (IServiceScope scope = builder.ApplicationServices.CreateScope())
2830
{
@@ -46,4 +48,33 @@ public static void UseJsonApi(this IApplicationBuilder builder)
4648

4749
builder.UseMiddleware<JsonApiMiddleware>();
4850
}
51+
52+
private static void AssertAspNetCoreOpenApiIsNotRegistered(IServiceProvider serviceProvider)
53+
{
54+
Type? optionsType = TryLoadOptionsType();
55+
56+
if (optionsType != null)
57+
{
58+
Type configureType = typeof(IConfigureOptions<>).MakeGenericType(optionsType);
59+
object? configureInstance = serviceProvider.GetService(configureType);
60+
61+
if (configureInstance != null)
62+
{
63+
throw new InvalidOperationException("JsonApiDotNetCore is incompatible with ASP.NET OpenAPI. " +
64+
"Replace 'services.AddOpenApi()' with 'services.AddOpenApiForJsonApi()' from the JsonApiDotNetCore.OpenApi.Swashbuckle NuGet package.");
65+
}
66+
}
67+
}
68+
69+
private static Type? TryLoadOptionsType()
70+
{
71+
try
72+
{
73+
return Type.GetType("Microsoft.AspNetCore.OpenApi.OpenApiOptions, Microsoft.AspNetCore.OpenApi");
74+
}
75+
catch (FileLoadException)
76+
{
77+
return null;
78+
}
79+
}
4980
}

Diff for: test/DiscoveryTests/AspNetOpenApiTests.cs

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#if !NET8_0
2+
using FluentAssertions;
3+
using JsonApiDotNetCore.Configuration;
4+
using Microsoft.AspNetCore.Builder;
5+
using Microsoft.AspNetCore.TestHost;
6+
using Microsoft.Extensions.DependencyInjection;
7+
using Xunit;
8+
9+
namespace DiscoveryTests;
10+
11+
public sealed class AspNetOpenApiTests
12+
{
13+
[Fact]
14+
public async Task Throws_when_AspNet_OpenApi_is_registered()
15+
{
16+
// Arrange
17+
WebApplicationBuilder builder = WebApplication.CreateEmptyBuilder(new WebApplicationOptions());
18+
builder.WebHost.UseTestServer();
19+
builder.Services.AddJsonApi();
20+
builder.Services.AddOpenApi();
21+
await using WebApplication app = builder.Build();
22+
23+
// Act
24+
Action action = app.UseJsonApi;
25+
26+
// Assert
27+
action.Should().ThrowExactly<InvalidOperationException>().WithMessage("JsonApiDotNetCore is incompatible with ASP.NET OpenAPI. " +
28+
"Replace 'services.AddOpenApi()' with 'services.AddOpenApiForJsonApi()' from the JsonApiDotNetCore.OpenApi.Swashbuckle NuGet package.");
29+
}
30+
}
31+
#endif

Diff for: test/DiscoveryTests/DiscoveryTests.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@
1414
<PackageReference Include="coverlet.collector" Version="$(CoverletVersion)" PrivateAssets="All" />
1515
<PackageReference Include="GitHubActionsTestLogger" Version="$(GitHubActionsTestLoggerVersion)" PrivateAssets="All" />
1616
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(TestSdkVersion)" />
17+
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Condition="'$(TargetFramework)' != 'net8.0'" Version="$(AspNetCoreVersion)" />
1718
</ItemGroup>
1819
</Project>

0 commit comments

Comments
 (0)