AddApiVersioning with a custom IProblemDetailsWriter breaks both the custom and decorated IProblemDetailsWriter
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 290
Description
### Is there an existing issue for this?
- [x] I have searched the existing issues
### Describe the bug
Calling `AddApiVersioning()` causes a custom IProblemDetailsWriter to be removed, and a decorated DefaultProblemDetailsWriter to be added to the ServiceProvider **while leaving the original in place.**
The function from "Asp.Versioning.Http" `IServiceCollectionExtensions.TryAddProblemDetailsRfc7231Compliance(...)` correctly looks for and finds the descriptor associated with "DefaultProblemDetailsWriter". However, that function then calls `services.Replace(...)` *which [always replaces](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.extensions.servicecollectiondescriptorextensions.replace) the **first** enumerable matching the ServiceType*. This replaces the custom writer with a decorated version of the default, while still leaving the default writer.
ProblemDetailsService iterates through an "IEnumerable" until it finds the first writer where `CanWrite(...)` is true, then stops. This is done in the order the services are registered. To ensure the default writer is not called accidentally, I must register my custom provider before calling `AddProblemDetails()`. This triggers the bug.
### Expected Behavior
My custom `IProblemDetailsWriter` continues to work as expected. If it cannot write, then the DefaultProblemDetailsWriter is augmented by `AddApiVersioning()`.
### Steps To Reproduce
```
var builder = WebApplication.CreateBuilder();
builder.Services.AddSingleton();
builder.Services.AddProblemDetails();
builder.Services.AddApiVersioning();
```
Inspect builder.Services and CustomProblemDetailsWriter will have been removed.
### Exceptions (if any)
None
### .NET Version
9.0.203
### Anything else?
* IDE: Microsoft Visual Studio Professional 2022 (64-bit) - Current Version 17.13.6
* TargetFramework: net8.0
* dotnet --info
```
.NET SDK:
Version: 9.0.203
Commit: dc7acfa194
Workload version: 9.0.200-manifests.12d79ccf
MSBuild version: 17.13.20+a4ef1e90f
Runtime Environment:
OS Name: Windows
OS Version: 10.0.19044
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\9.0.203\
.NET workloads installed:
[aspire]
Installation Source: VS 17.13.35931.197
Manifest Version: 8.2.2/8.0.100
Manifest Path: C:\PROGRAM FILES\DOTNET\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.2.2\WorkloadManifest.json
Install Type: Msi
Configured to use loose manifests when installing new manifests.
Host:
Version: 9.0.4
Architecture: x64
Commit: f57e6dc747
.NET SDKs installed:
8.0.408 [C:\Program Files\dotnet\sdk]
9.0.203 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 8.0.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 9.0.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 8.0.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 9.0.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 8.0.15 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 9.0.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Other architectures found:
x86 [C:\Program Files (x86)\dotnet]
registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]
Environment variables:
Not set
global.json file:
Not found
Learn more:
https://aka.ms/dotnet/info
Download .NET:
https://aka.ms/dotnet/download
```
Contributor guide
Assessment
This issue has not been assessed yet.