镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

[FromKeyedServices("keyName")] Keyed services support in Microsoft.Extensions.DependencyInjection is not resolving dependency in constructor  #92076

Closed

Description

@nitish-kaushik

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

I am trying the new Support for keyed services in minimal APIs, MVC, and SignalR feature in Asp.Net Core Web API Controller. The dependency works fine when I resolve them directly in the action method of the controller but throws an exception if resolve it in the controller constructor.

Here is my code:

public interface IEmployee
{
    string GetMessage();
}
public class Employee : IEmployee
{
    public string GetMessage()
    {
       return "Hello from Employee";
    }
}
public class TempEmployee : IEmployee
{
    public string GetMessage()
    {
        return "Hello from Temp Employee";
    }
}

And this is how I have registered them in the program.cs class.

builder.Services.AddKeyedSingleton<IEmployee, Employee>("employee");
builder.Services.AddKeyedSingleton<IEmployee, TempEmployee>("tempEmployee");

Here is the code from the Controller:

This works fine if resolving the dependency directly in the method

[HttpGet("temp")]
public ActionResult GetTempEmployee([FromKeyedServices("tempEmployee")] IEmployee tempEmployee)
{
    return Ok(tempEmployee.GetMessage());
}

But If I try to inject this dependency in the constructor then get the error:

[ApiController]
[Route("[controller]")]
public class EmployeeController : ControllerBase
{
    private readonly IEmployee tempEmployee;

    public EmployeeController([FromKeyedServices("tempEmployee")] IEmployee _tempEmployee)
    {
        tempEmployee = _tempEmployee;
    }

    [HttpGet("temp")]
    public ActionResult GetTempEmployee()
    {
        return Ok(tempEmployee.GetMessage());
    }
}

Error:

System.InvalidOperationException: Unable to resolve service for type 'WebApplication5.IEmployee' while attempting to activate 'WebApplication5.Controllers.EmployeeController'.
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ThrowHelperUnableToResolveService(Type type, Type requiredBy)
   at lambda_method3(Closure, IServiceProvider, Object[])
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass6_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

HEADERS
=======
Accept: */*
Host: localhost:7212
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,hi;q=0.8
Referer: https://localhost:7212/swagger/index.html
sec-ch-ua: "Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
sec-fetch-site: same-origin
sec-fetch-mode: cors
sec-fetch-dest: empty

My System Setup

Microsoft Visual Studio Enterprise 2022 (64-bit)
Preview Version 17.8.0 Preview 1.0

Windows:
Edition Windows 11 Home Single Language
Version 22H2
OS build 22621.2134
Experience Windows Feature Experience Pack 1000.22659.1000.0

Output form dotnet --info command

C:\Users\Nitish>dotnet --info
.NET SDK:
Version: 8.0.100-rc.1.23455.8
Commit: e14caf947f

Runtime Environment:
OS Name: Windows
OS Version: 10.0.22621
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\8.0.100-rc.1.23455.8\

.NET workloads installed:
There are no installed workloads to display.

Host:
Version: 8.0.0-rc.1.23419.4
Architecture: x64
Commit: 9295993
RID: win-x64

.NET SDKs installed:
6.0.101 [C:\Program Files\dotnet\sdk]
7.0.102 [C:\Program Files\dotnet\sdk]
8.0.100-preview.7.23376.3 [C:\Program Files\dotnet\sdk]
8.0.100-rc.1.23455.8 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.20 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.0-preview.7.23375.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.0-rc.1.23421.29 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.0-preview.7.23375.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.0-rc.1.23419.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 6.0.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 7.0.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 7.0.9 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.0-preview.7.23376.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.0-rc.1.23420.5 [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

Expected Behavior

The Keyed services support should work in the constructor too.

Steps To Reproduce

No response

Exceptions (if any)

No response

.NET Version

8.0.100-rc.1.23455.8

Anything else?

dotnet --info

.NET SDK:
Version: 8.0.100-rc.1.23455.8
Commit: e14caf947f

Runtime Environment:
OS Name: Windows
OS Version: 10.0.22621
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\8.0.100-rc.1.23455.8\

.NET workloads installed:
There are no installed workloads to display.

Host:
Version: 8.0.0-rc.1.23419.4
Architecture: x64
Commit: 9295993
RID: win-x64

.NET SDKs installed:
6.0.101 [C:\Program Files\dotnet\sdk]
7.0.102 [C:\Program Files\dotnet\sdk]
8.0.100-preview.7.23376.3 [C:\Program Files\dotnet\sdk]
8.0.100-rc.1.23455.8 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.20 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.0-preview.7.23375.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.0-rc.1.23421.29 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.0-preview.7.23375.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.0-rc.1.23419.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 6.0.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 7.0.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 7.0.9 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.0-preview.7.23376.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.0-rc.1.23420.5 [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

Activity

  1. BrennanConroy commented on Sep 13, 2023

    @BrennanConroy
    Member

    It looks like ActivatorUtilities.CreateFactory doesn't have support for FromKeyedServices. This will affect both MVC and SignalR for the constructors of Controller and Hub respectively (when using FromKeyedServices).

    I'm checking with folks to see if we just missed support for that.

  2. nitish-kaushik commented on Sep 13, 2023

    @nitish-kaushik
    Author

    @BrennanConroy Please check for IKeyedServiceProvider too. This is also throwing the same exception in the constructor.

    Here is the code

    public class ValuesController : ControllerBase
    {
        public readonly IKeyedServiceProvider keyedServiceProvider;
    
        public ValuesController(IKeyedServiceProvider _keyedServiceProvider)
        {
            keyedServiceProvider = _keyedServiceProvider;
        }
       
        [HttpGet("permanent")]
        public ActionResult GetEmployee()
        {
            var ss = keyedServiceProvider.GetRequiredKeyedService<IEmployee>("tempEmployee");
            return Ok(ss.GetMessage());
        }
    }
    

    Exception:

    Unable to resolve service for type 'Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider' while attempting to activate 'WebApplication5.Controllers.ValuesController'.

  3. benjaminpetit commented on Sep 14, 2023

    @benjaminpetit
    Contributor

    IKeyedServiceProvider is not resolvable with DI, you have to use SIServiceProvider directly

  4. nitish-kaushik commented on Sep 14, 2023

    @nitish-kaushik
    Author
  5. ghost added
    needs-area-labelAn area label is needed to ensure this gets routed to the appropriate area owners
    on Sep 14, 2023
  6. ghost added
    untriagedNew issue has not been triaged by the area owner
    on Sep 14, 2023
  7. removed
    needs-area-labelAn area label is needed to ensure this gets routed to the appropriate area owners
    on Sep 14, 2023
  8. benjaminpetit commented on Sep 14, 2023

    @benjaminpetit
    Contributor

    Transfering the issue in runtime.

    The issue is that ActivatorUtilities.CreateFactory doesn't support the [FromKeyedService] attribute.

  9. added this to the 8.0.0 milestone on Sep 14, 2023
  10. ghost added
    in-prThere is an active PR which will close this issue when it is merged
    on Sep 15, 2023
  11. ghost removed
    in-prThere is an active PR which will close this issue when it is merged
    on Sep 16, 2023
  12. ericstj commented on Sep 18, 2023

    @ericstj
    Member

    Can this be closed now?

  13. ghost locked as resolved and limited conversation to collaborators on Oct 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions