c# - 如何注入 IEnumerable这也是作为单例生命周期的托管服务
问题描述
我希望利用 .Net Core 来处理与整个应用程序相同的服务的生命周期,我想将它们注入另一个托管服务。我知道我可以自己在服务器的启动/停止中实现侦听器的启动/停止。但是,如果我可以在下面的场景中工作,那感觉没有必要。
我宁愿将其简化为一行以进行注册。我正在为 IServiceCollection 创建扩展方法。
public class Server: IHostedService
{
public Server(IEnumerable<IConnectionListener> listeners)
{
foreach(var l in listeners)
{
l.Connected += HandleConnection;
}
}
private void HandleConnection(object src, Foo foo) { }
public async Task StartAsync(CancellationToken ct)
{}
public async Task StopAsync(CancellationToken ct)
{}
}
public interface IConnectionListener
{
event ConnectionHandler Connected;
}
public class ConnectionListener: BackgroundService, IConnectionListener
{
public async Task ExecuteAsync(CancellationToken ct)
{
// Open TcpListener and register with the ct to stop the listener.
}
}
public class SslConnectionListener: BackgroundService, IConnectionListener
{
public async Task ExecuteAsync(CancellationToken ct)
{
// Open TcpListener and register with the ct to stop the listener.
// Add some extra SSL stuff
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hc, services) =>
{
// This appears to work. But I have concerns about whether the life times will truly
// be singleton and automatic disposal of the objects (having used the factory, I do
// want the automatic disposal by the container).
var listener = new ConnectionListener();
var sslListener = new SslConnectionListener();
services.AddSingleton<IConnectionListener>(sp => listener);
services.AddSingleton<IConnectionListner>(sp => sslListener);
services.AddHostedService(sp => listener);
services.AddHostedService(sp => sslListener);
// This doesn't work
services.AddHostedService<SslConnectionListener>();
services.AddHostedService<ConnectionListener>()
services.AddHostedService<Server>();
}
解决方案
你可以考虑这种方法
//register the instances
services.AddSingleton<ConnectionListener>();
services.AddSingleton<SslConnectionListener>();
//register their abstractions
services.AddSingleton<IConnectionListener>(sp => sp.GetService<ConnectionListener>());
services.AddSingleton<IConnectionListener>(sp => sp.GetService<SslConnectionListener>());
//register hosted services.
services.AddHostedService(sp => sp.GetService<ConnectionListener>());
services.AddHostedService(sp => sp.GetService<SslConnectionListener>());
services.AddHostedService<Server>();
通过这种方式,容器管理所创建实例的整个生命周期。
这可以巧妙地包装在扩展方法中以简化调用。
推荐阅读
- linux - 使用 MDEV-17458 将 galera-cluster 更新到 10.3.15
- firebase - 如何在 Vue.js 应用程序中配置 firebase cdn / 缓存?
- python-3.x - 使用 python psycopg2 在 PostgreSQL 数据库中插入嵌套 json 数据(某些键不存在)时出现问题
- excel - VBA 在 Outlook 2016 中发送电子邮件效率变差了?
- java - 从集合中提取对象
基于地图输入 - c# - 在 library(.dll) 项目中使用 WCF 时放置服务参考是一种好习惯吗?
- html - 我在用于滚动文本的“数据文本”和“数据文本”之间存在语法问题
- javascript - 如何使用 jQuery 将 url 的 #-part 保留在 load() 上?
- php - 数据在数据库中保存为数组 - 使用 laravel
- kendo-grid - 如何为剑道网格编辑器配置自定义验证规则