-
Notifications
You must be signed in to change notification settings - Fork 10k
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
Keyed services fail to dependency inject into middleware #54500
Comments
I am also experiencing the issue with .NET 8.0.2. I did a workaround with injecting the IServiceProvider to the middleware and acquiring the keyed service implementation with serviceProvider.GetKeyedService<>. It works but it doesn't look so nice. Do you have any updates regarding this issue? |
Microsoft.Extensions.DependencyInjection.ActivatorUtilities supports FromKeyedServicesAttribute but Microsoft.Extensions.Internal.ActivatorUtilities doesn't. Why does ASP.NET Core even have its own fork of this class…? |
I have the same problem. |
I'm experiencing the same issue. Specifically, it resolves to an unexpected instance when another instance is already registered using the Consider the following example: public class HelloWorldMiddleware(RequestDelegate next)
{
public async Task InvokeAsync(HttpContext context, [FromKeyedServices("HelloWorld:1")] IHelloWorld helloWorld)
{
await next(context);
}
} Scenario 1 returns an incorrect instance: builder.Services.AddSingleton<IHelloWorld>(new HelloWorld()); // This instance is incorrectly resolved in the middleware, which shouldn't happen.
builder.Services.AddKeyedSingleton<IHelloWorld>("HelloWorld:1", new HelloWorld()); Scenario 2, which results in the error mentioned in the original post: builder.Services.AddKeyedSingleton<IHelloWorld>("HelloWorld:1", new HelloWorld()); |
…ction to Microsoft.AspNetCore.Http.Abstractions and utilized the ActivatorUtilities it provides to obtain a middleware instance. Also changed the ReflectionMiddlewareBinder to be able to handle keyed injection.
…new lines) based on pull-request feedback.
… parameter within the ReflectionFallback.
…ach parameter within the ReflectionFallback, removed the parameterType and declaringType from the precomputed cache.
…d added the NotNullWhen(true) attribute. Also changed the Inherit param from true to false when obtaining the custom attribute FromKeyedServicesAttribute.
…test. Added Benchmark(s) for the ReflectionFallback method.
The workaround mentioned by @laliconfigcat (injecting via |
Another workaround is to implement public class MiddlewareUsingKeyedSomeClassConstructor(R[FromKeyedServices("test")] SomeClass someClass) : IMiddleware
{
public async Task InvokeAsync(HttpContext context. RequestDelegate next)
{
await next(context);
}
}
builder.Services.AddTransient<MiddlewareUsingKeyedSomeClassConstructor>();
app.UseMiddleware<MiddlewareUsingKeyedSomeClassConstructor>(); |
…pport unit-tests.
…on check in test method..
…on check in test method.
Is there an existing issue for this?
Describe the bug
It does not seem possible to get keyed services injected into middleware classes . Neither using constructor or Invoke/InvokeAsync argument injection. Attempting to do so results in a startup or invoke time exception respectively.
Expected Behavior
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-8.0#service-lifetimes documents constructor as well as InvokeAsync using DI as well as constructor injection using keyed services for classes in DI.
As such the expectation is for DI on middleware to also work with keyed services.
Steps To Reproduce
Execute the following code using
dotnet run
Exceptions (if any)
app.UseMiddleware<MiddlewareUsingKeyedSomeClassConstructor>(); // Throws on startup
app.UseMiddleware<MiddlewareUsingKeyedSomeClassInvoke>(); // Throws on invoke
.NET Version
8.0.200
Anything else?
No response
The text was updated successfully, but these errors were encountered: