Search code examples
c#.netasp.net-coredependency-injection.net-8.0

How to implement Keyed Transient Dependency Injection in C# using IServiceProvider


I have 3 SFTP providers for my application. I am trying to use newly introduced .net 8 Keyed DI feature to register these SFTP providers:

var hostname1 = "hostname";
var portNo1 = 22;
var username1 = "username";
var password1 = "password";

services.AddKeyedTransient<SftpClient>("SFTP1", new SftpClient(hostname1, portNo1, username1, password1));

Later retreive it like:

public IActionResult Get([FromKeyedServices("SFTP1")] SftpClient client)
 {
    do something with the SFTPclient...
 }

The issue is that the code is not compiling:

The error is:

Severity Code Description Project File Line Suppression State Error CS1503 Argument 3: cannot convert from 'Renci.SshNet.SftpClient' to 'System.Func<System.IServiceProvider, object?, Renci.SshNet.SftpClient>' TestSFTP C:\Users\Windows 10 VM\source\repos\TestSFTP\TestSFTP\Program.cs 18 Active

error screenshot

I do not know how to use IServiceProvider to register keyed SftpClient. Please help me.


Solution

  • A transient service means "new instance every time it's required".

    Therefore, it doesn't make sense to pass an instance to AddKeyedTransient, you need to pass a factory function instead:

    services.AddKeyedTransient<SftpClient>(
        "SFTP1",
        delegate { return new SftpClient(hostname1, portNo1, username1, password1); });
    

    Every time that service is requested from the provider, the factory function is invoked, and you get a new instance.


    If you do want to register a single instance, then use AddKeyedSingleton for that:

    services.AddKeyedSingleton<SftpClient>(
        "SFTP1",
        new SftpClient(hostname1, portNo1, username1, password1));