-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API Proposal]: the keyed service registration serviceKey non-nullable #90322
Comments
Tagging subscribers to this area: @dotnet/area-extensions-dependencyinjection Issue DetailsBackground and motivationCurrently, the For example: var serviceCollection = new ServiceCollection();
// reg1
serviceCollection.AddKeyedSingleton<IIdGenerator, GuidIdGenerator>(null);
// reg2
serviceCollection.AddSingleton<IIdGenerator, GuidIdGenerator>(); these two service registrations would be the same, they would add the same {
"ServiceType": "typeof(IIdGenerator)",
"ImplementType": "typeof(GuidIdGenerator)",
"ServiceKey": null,
"Lifetime": "Singleton"
// ...
} API ProposalFor namespace namespace Microsoft.Extensions.DependencyInjection;
public static class ServiceCollectionServiceExtensions {
- public static IServiceCollection AddKeyedScoped(this IServiceCollection services, Type serviceType, object? serviceKey);
+ public static IServiceCollection AddKeyedScoped(this IServiceCollection services, Type serviceType, object serviceKey);
- public static IServiceCollection AddKeyedScoped(this IServiceCollection services, Type serviceType, object? serviceKey, Func<IServiceProvider, object, object> implementationFactory);
+ public static IServiceCollection AddKeyedScoped(this IServiceCollection services, Type serviceType, object serviceKey, Func<IServiceProvider, object, object> implementationFactory);
- public static IServiceCollection AddKeyedScoped(this IServiceCollection services, Type serviceType, object? serviceKey, Type implementationType);
+ public static IServiceCollection AddKeyedScoped(this IServiceCollection services, Type serviceType, object serviceKey, Type implementationType);
- public static IServiceCollection AddKeyedScoped<TService, TImplementation>(this IServiceCollection services, object? serviceKey) where TService : class where TImplementation : class, TService;
+ public static IServiceCollection AddKeyedScoped<TService, TImplementation>(this IServiceCollection services, object serviceKey) where TService : class where TImplementation : class, TService;
- public static IServiceCollection AddKeyedScoped<TService, TImplementation>(this IServiceCollection services, object? serviceKey, Func<IServiceProvider, object, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService;
+ public static IServiceCollection AddKeyedScoped<TService, TImplementation>(this IServiceCollection services, object serviceKey, Func<IServiceProvider, object, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService;
- public static IServiceCollection AddKeyedScoped<TService>(this IServiceCollection services, object? serviceKey) where TService : class;
+ public static IServiceCollection AddKeyedScoped<TService>(this IServiceCollection services, object serviceKey) where TService : class;
- public static IServiceCollection AddKeyedScoped<TService>(this IServiceCollection services, object? serviceKey, Func<IServiceProvider, object, TService> implementationFactory) where TService : class;
+ public static IServiceCollection AddKeyedScoped<TService>(this IServiceCollection services, object serviceKey, Func<IServiceProvider, object, TService> implementationFactory) where TService : class;
- public static IServiceCollection AddKeyedSingleton(this IServiceCollection services, Type serviceType, object? serviceKey);
+ public static IServiceCollection AddKeyedSingleton(this IServiceCollection services, Type serviceType, object serviceKey);
- public static IServiceCollection AddKeyedSingleton(this IServiceCollection services, Type serviceType, object? serviceKey, Func<IServiceProvider, object, object> implementationFactory);
+ public static IServiceCollection AddKeyedSingleton(this IServiceCollection services, Type serviceType, object serviceKey, Func<IServiceProvider, object, object> implementationFactory);
- public static IServiceCollection AddKeyedSingleton(this IServiceCollection services, Type serviceType, object? serviceKey, Type implementationType);
+ public static IServiceCollection AddKeyedSingleton(this IServiceCollection services, Type serviceType, object serviceKey, Type implementationType);
- public static IServiceCollection AddKeyedSingleton<TService, TImplementation>(this IServiceCollection services, object? serviceKey) where TService : class where TImplementation : class, TService;
+ public static IServiceCollection AddKeyedSingleton<TService, TImplementation>(this IServiceCollection services, object serviceKey) where TService : class where TImplementation : class, TService;
- public static IServiceCollection AddKeyedSingleton<TService, TImplementation>(this IServiceCollection services, object? serviceKey, Func<IServiceProvider, object, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService;
+ public static IServiceCollection AddKeyedSingleton<TService, TImplementation>(this IServiceCollection services, object serviceKey, Func<IServiceProvider, object, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService;
- public static IServiceCollection AddKeyedSingleton<TService>(this IServiceCollection services, object? serviceKey) where TService : class;
+ public static IServiceCollection AddKeyedSingleton<TService>(this IServiceCollection services, object serviceKey) where TService : class;
- public static IServiceCollection AddKeyedSingleton<TService>(this IServiceCollection services, object? serviceKey, Func<IServiceProvider, object, TService> implementationFactory) where TService : class;
+ public static IServiceCollection AddKeyedSingleton<TService>(this IServiceCollection services, object serviceKey, Func<IServiceProvider, object, TService> implementationFactory) where TService : class;
- public static IServiceCollection AddKeyedTransient(this IServiceCollection services, Type serviceType, object? serviceKey);
+ public static IServiceCollection AddKeyedTransient(this IServiceCollection services, Type serviceType, object serviceKey);
- public static IServiceCollection AddKeyedTransient(this IServiceCollection services, Type serviceType, object? serviceKey, Func<IServiceProvider, object, object> implementationFactory);
+ public static IServiceCollection AddKeyedTransient(this IServiceCollection services, Type serviceType, object serviceKey, Func<IServiceProvider, object, object> implementationFactory);
- public static IServiceCollection AddKeyedTransient(this IServiceCollection services, Type serviceType, object? serviceKey, Type implementationType);
+ public static IServiceCollection AddKeyedTransient(this IServiceCollection services, Type serviceType, object serviceKey, Type implementationType);
- public static IServiceCollection AddKeyedTransient<TService, TImplementation>(this IServiceCollection services, object? serviceKey) where TService : class where TImplementation : class, TService;
+ public static IServiceCollection AddKeyedTransient<TService, TImplementation>(this IServiceCollection services, object serviceKey) where TService : class where TImplementation : class, TService;
- public static IServiceCollection AddKeyedTransient<TService, TImplementation>(this IServiceCollection services, object? serviceKey, Func<IServiceProvider, object, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService;
+ public static IServiceCollection AddKeyedTransient<TService, TImplementation>(this IServiceCollection services, object serviceKey, Func<IServiceProvider, object, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService;
- public static IServiceCollection AddKeyedTransient<TService>(this IServiceCollection services, object? serviceKey) where TService : class;
+ public static IServiceCollection AddKeyedTransient<TService>(this IServiceCollection services, object serviceKey) where TService : class;
- public static IServiceCollection AddKeyedTransient<TService>(this IServiceCollection services, object? serviceKey, Func<IServiceProvider, object, TService> implementationFactory) where TService : class;
+ public static IServiceCollection AddKeyedTransient<TService>(this IServiceCollection services, object serviceKey, Func<IServiceProvider, object, TService> implementationFactory) where TService : class;
} For namespace namespace Microsoft.Extensions.DependencyInjection.Extensions {
public static class ServiceCollectionDescriptorExtensions {
- public static IServiceCollection RemoveAllKeyed(this IServiceCollection collection, Type serviceType, object? serviceKey);
+ public static IServiceCollection RemoveAllKeyed(this IServiceCollection collection, Type serviceType, object serviceKey);
- public static IServiceCollection RemoveAllKeyed<T>(this IServiceCollection collection, object? serviceKey);
+ public static IServiceCollection RemoveAllKeyed<T>(this IServiceCollection collection, object serviceKey);
- public static void TryAddKeyedScoped(this IServiceCollection collection, Type service, object? serviceKey);
+ public static void TryAddKeyedScoped(this IServiceCollection collection, Type service, object serviceKey);
- public static void TryAddKeyedScoped(this IServiceCollection collection, Type service, object? serviceKey, Func<IServiceProvider, object, object> implementationFactory);
+ public static void TryAddKeyedScoped(this IServiceCollection collection, Type service, object serviceKey, Func<IServiceProvider, object, object> implementationFactory);
- public static void TryAddKeyedScoped(this IServiceCollection collection, Type service, object? serviceKey, Type implementationType);
+ public static void TryAddKeyedScoped(this IServiceCollection collection, Type service, object serviceKey, Type implementationType);
- public static void TryAddKeyedScoped<TService, TImplementation>(this IServiceCollection collection, object? serviceKey) where TService : class where TImplementation : class, TService;
+ public static void TryAddKeyedScoped<TService, TImplementation>(this IServiceCollection collection, object serviceKey) where TService : class where TImplementation : class, TService;
- public static void TryAddKeyedScoped<TService>(this IServiceCollection collection, object? serviceKey) where TService : class;
+ public static void TryAddKeyedScoped<TService>(this IServiceCollection collection, object serviceKey) where TService : class;
- public static void TryAddKeyedScoped<TService>(this IServiceCollection services, object? serviceKey, Func<IServiceProvider, object, TService> implementationFactory) where TService : class;
+ public static void TryAddKeyedScoped<TService>(this IServiceCollection services, object serviceKey, Func<IServiceProvider, object, TService> implementationFactory) where TService : class;
- public static void TryAddKeyedSingleton(this IServiceCollection collection, Type service, object? serviceKey);
+ public static void TryAddKeyedSingleton(this IServiceCollection collection, Type service, object serviceKey);
- public static void TryAddKeyedSingleton(this IServiceCollection collection, Type service, object? serviceKey, Func<IServiceProvider, object, object> implementationFactory);
+ public static void TryAddKeyedSingleton(this IServiceCollection collection, Type service, object serviceKey, Func<IServiceProvider, object, object> implementationFactory);
- public static void TryAddKeyedSingleton(this IServiceCollection collection, Type service, object? serviceKey, Type implementationType);
+ public static void TryAddKeyedSingleton(this IServiceCollection collection, Type service, object serviceKey, Type implementationType);
- public static void TryAddKeyedSingleton<TService, TImplementation>(this IServiceCollection collection, object? serviceKey) where TService : class where TImplementation : class, TService;
+ public static void TryAddKeyedSingleton<TService, TImplementation>(this IServiceCollection collection, object serviceKey) where TService : class where TImplementation : class, TService;
- public static void TryAddKeyedSingleton<TService>(this IServiceCollection collection, object? serviceKey) where TService : class;
+ public static void TryAddKeyedSingleton<TService>(this IServiceCollection collection, object serviceKey) where TService : class;
- public static void TryAddKeyedSingleton<TService>(this IServiceCollection services, object? serviceKey, Func<IServiceProvider, object, TService> implementationFactory) where TService : class;
+ public static void TryAddKeyedSingleton<TService>(this IServiceCollection services, object serviceKey, Func<IServiceProvider, object, TService> implementationFactory) where TService : class;
- public static void TryAddKeyedTransient(this IServiceCollection collection, Type service, object? serviceKey);
+ public static void TryAddKeyedTransient(this IServiceCollection collection, Type service, object serviceKey);
- public static void TryAddKeyedTransient(this IServiceCollection collection, Type service, object? serviceKey, Func<IServiceProvider, object, object> implementationFactory);
+ public static void TryAddKeyedTransient(this IServiceCollection collection, Type service, object serviceKey, Func<IServiceProvider, object, object> implementationFactory);
- public static void TryAddKeyedTransient(this IServiceCollection collection, Type service, object? serviceKey, Type implementationType);
+ public static void TryAddKeyedTransient(this IServiceCollection collection, Type service, object serviceKey, Type implementationType);
- public static void TryAddKeyedTransient<TService, TImplementation>(this IServiceCollection collection, object? serviceKey) where TService : class where TImplementation : class, TService;
+ public static void TryAddKeyedTransient<TService, TImplementation>(this IServiceCollection collection, object serviceKey) where TService : class where TImplementation : class, TService;
- public static void TryAddKeyedTransient<TService>(this IServiceCollection collection, object? serviceKey) where TService : class;
+ public static void TryAddKeyedTransient<TService>(this IServiceCollection collection, object serviceKey) where TService : class;
- public static void TryAddKeyedTransient<TService>(this IServiceCollection services, object? serviceKey, Func<IServiceProvider, object, TService> implementationFactory) where TService : class;
+ public static void TryAddKeyedTransient<TService>(this IServiceCollection services, object serviceKey, Func<IServiceProvider, object, TService> implementationFactory) where TService : class;
}
} API Usagevar serviceCollection = new ServiceCollection();
// throw `ArgumentNullException` since the `serviceKey` could not be null
serviceCollection.AddKeyedSingleton<IIdGenerator, GuidIdGenerator>(null); Alternative DesignsNo response RisksNo response
|
I believe the rationale here was that this API can be used for both keyed- and nonkeyed-services. |
Since we already have API for non-keyed service, think maybe we could disable |
Supporting |
But from the API approved here, seemed to be non-nullable |
Correct that was the original proposal, but the API was changed (with internal email approval) during implementation. |
Background and motivation
Currently, the
serviceKey
in the keyed service registration extensions could benull
, while when theserviceKey
isnull
it would not be a keyed service. It feels strange that the behavior is not as its naming.For example:
these two service registrations would be the same, they would add the same
ServiceDescriptor
like belowAnd the api approved
serviceKey
seemed to be non-nullable#64427 (comment)
API Proposal
For namespace
Microsoft.Extensions.DependencyInjection
:For namespace
Microsoft.Extensions.DependencyInjection.Extensions
:API Usage
Alternative Designs
Treat as
KeyedService.AnyKey
when theserviceKey
isnull
?Risks
No response
The text was updated successfully, but these errors were encountered: