如何使用 IServiceProvider 在 C# 中实现键控瞬态依赖注入

问题描述 投票:0回答:2

我的应用程序有 3 个 SFTP 提供商。我正在尝试使用新引入的 .net 8 Keyed DI 功能来注册这些 SFTP 提供商:

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

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

稍后检索它,如下所示:

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

问题是代码无法编译:

错误是:

严重性代码描述项目文件行抑制状态 错误 CS1503 参数 3:无法从“Renci.SshNet.SftpClient”转换为“System.Func”TestSFTP C:\Users\Windows 10 VM\source epos\TestSFTP\TestSFTP\Program.cs 18 活动

我不知道如何使用 IServiceProvider 注册键控 SftpClient。 请帮助我。

c# .net asp.net-core dependency-injection .net-8.0
2个回答
3
投票

瞬态服务意味着“每次需要时都会创建新实例”。

因此,将实例传递给

AddKeyedTransient
是没有意义的,你需要传递一个工厂方法:

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

每次向提供者请求该服务时,都会调用工厂方法,并且您会获得一个新实例。


如果您确实想注册单个实例,请使用

AddKeyedSingleton
来实现:

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

1
投票

在这种情况下你需要提供实现工厂:

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

Transient
意味着对象总是不同的,因此在这种情况下不需要注册单个实例。来自文档

瞬态

每次从服务容器请求时都会创建瞬时生命周期服务。此生命周期最适合轻量级、无状态服务。使用 AddTransient 注册瞬态服务。
在处理请求的应用程序中,瞬态服务在请求结束时被释放。

如果您想要单个实例,请使用

AddKeyedSingleton
(并重载接受实现实例):

services.AddKeyedSingleton<SftpClient>(
    "SFTP1",
    new SftpClient(hostname1, portNo1, username1, password1));
© www.soinside.com 2019 - 2024. All rights reserved.