DbConnectionStringBuilder annotations force invalid suppressions on library authors
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- PR merge metrics
- PR metrics pending
Description
DbConnectionStringBuilder has `DynamicallyAccessedMembers` on the type:
https://github.com/dotnet/runtime/blob/ea694d84df646ef212a74e83c8bfafa053d46606/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs#L18-L24
which says that it's trim-compatible to reflect over the specified members of `DbConnectionStringBuilder` or derived types. But at the same item, several members are marked as `RequiresUnreferencedCode`:
https://github.com/dotnet/runtime/blob/ea694d84df646ef212a74e83c8bfafa053d46606/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs#L400-L404
The suppression on `GetProperties` is invalid because it allows:
```csharp
new DbConnectionStringBuilder().GetType().GetMethods(...)
```
which is reflecting over RUC methods but doesn't produce trim warnings. The annotations also lead to unactionable trim warnings:
```csharp
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System.Collections;
using System.ComponentModel.DataAnnotations;
using System.Data.Common;
using System.Diagnostics.CodeAnalysis;
var db = new MyStringBuilder();
new ServiceCollection()
.Configure(settings =>
{
settings.Option = true;
})
.AddSingleton, MyValidator>()
.AddSingleton()
.BuildServiceProvider();
public class MySettings
{
[Required]
public bool Option { get; set; }
}
class SettingsHelper
{
private readonly IOptions _options;
public SettingsHelper(IOptions options)
{
_options = options;
}
}
[OptionsValidator]
public partial class MyValidator : IValidateOptions
{
}
class MyStringBuilder : DbConnectionStringBuilder
{
[RequiresUnreferencedCode("GetProperties")]
protected override void GetProperties(Hashtable propertyDescriptors)
{
base.GetProperties(propertyDescriptors);
}
}
```
This produces a trim warning from `MyStringBuilder.GetProperties`, but only when both `MyStringBuilder` and the options validation logic are referenced from the app (because the options validation logic internally uses `ICustomTypeDescriptor.GetProperties`):
```
warning IL2112: 'DynamicallyAccessedMembersAttribute' on 'MyStringBuilder' or one of its base types references 'MyStringBuilder.GetProperties(Hashtable)' which requires unreferenced code. GetProperties.
```
I'm opening this issue because I have seen this cause confusion in various places, and I think it's worth writing down our recommendations. Given the way we have annotated `DbConnectiontStringBuilder`, I think the current recommendation is for all derived types to suppress the warnings from the derived members (so add `UnconditionalSuppressMessage("IL2112", ...)` to the `GetProperties` override in this example). This is not ideal because it forces the library author to add an invalid suppression.
Contributor guide
Assessment
This issue has not been assessed yet.