dotnet / dotnet/aspnetcore

Add Key Property to ServiceFilterAttribute

Open
#58,017 0 comments 1 reaction 0 assignees View on GitHub
api-suggestion area-mvc
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 5h
Merged PRs (30d)
276

Description

## Background and Motivation
Since .NET 8, the service provider supports keyed service registrations. However, the ServiceFilterAttribute, which uses dependency injection from a type, does not allow specifying an optional key for the registration. It should have an optional Key property.
Internally, the only change would be to check if the Key property is not null or whitespace, and then call GetRequiredKeyedService instead of GetRequiredService.

## Proposed API

```csharp
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
[DebuggerDisplay("Type = {ServiceType}, Key = {Key}, Order = {Order}")]
public class ServiceFilterAttribute : Attribute, IFilterFactory, IOrderedFilter
{
public ServiceFilterAttribute(Type type) {}
public object? Key { get; set; }

public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
ArgumentNullException.ThrowIfNull(serviceProvider);

IFilterMetadata filter;

if (Key is null || (Key is string keyStr && string.IsNullOrWhiteSpace(keyStr)))
{
filter = (IFilterMetadata)serviceProvider.GetRequiredService(ServiceType);
}
else
{
filter = (IFilterMetadata)serviceProvider.GetRequiredKeyedService(ServiceType, Key);
}
if (filter is IFilterFactory filterFactory)
{
// Unwrap filter factories
filter = filterFactory.CreateInstance(serviceProvider);
}

return filter;
}
}
```

## Usage Examples

```csharp
[ServiceFilter(type(MyActionFilter), Key = "My")]
public IActionResult Action() { ... }
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.