c# - 从通用接口转换为对象返回 null
问题描述
我有这种情况
interface INotification<T>
{
Task Handle(T t)
}
和多种实现
class Notification1 : INotification<SomeEvent>
{
//....
}
class Notification2 : INotification<SomeEvent>
{
//....
}
我正在使用 ServiceProviderGetServices(Type)
来获取所有的实现
async Task RunAsync<TNotification>(TNotification notification)
{
Type notificationType = notification.GetType();
var handlerType = typeof(INotification<>).MakeGenericType(notificationType);
var handlers = _serviceProvider.GetServices(handlerType);
foreach (var handler in handlers)
{
var instance = handler as INotification<TNotification>;
await instance.Handle(notification);
}
}
在handlers
我得到实现的处理程序INotification<T>
在 foreach 循环中,我试图进行强制转换INotification
并触发 Handle 方法。
但演员阵容失败
var instance = handler as INotification<TNotification>;
我得到null。
我的代码有什么问题?
解决方案
基于构造的泛型类型,
var handlerType = typeof(INotification<>).MakeGenericType(notificationType);
我相信泛型可能会有些混淆。
考虑使用服务提供者的通用GetServices<T>()
扩展,这将简化上述代码。
async Task RunAsync<TEvent>(TEvent @event) {
var handlers = _serviceProvider.GetServices<INotification<TEvent>>();
foreach (var handler in handlers) {
await handler.Handle(@event);
}
}
由于强类型泛型,它简化了对处理程序的调用,因为它们已经是所需的类型
这也可以重构为异步处理所有通知,而不是像循环Task.WhenAll
中那样按顺序处理foreach
async Task RunAsync<TEvent>(TEvent @event) {
var handlers = _serviceProvider.GetServices<INotification<TEvent>>();
if(handlers.Any()) {
var tasks = handlers.Select(handler => handler.Handle(@event));
await Task.WhenAll(tasks);
}
}
推荐阅读
- javascript - 为什么我无法预览我上传的内容?
- scala - 如何惯用地将元素添加到不可变集合并获得成功?
- python - Python、Kivy、Labels 每次我点击运行时都会切换位置,这是一个错误吗?
- powerapps - 在组合框中选择特定项目
- c# - 构建 Selenium Specflow 解决方案时出错
- java - 使用正则表达式解析 Java url 域
- ios - 在 iOS 上创建动画指示箭头
- android - java.lang.NoClassDefFoundError:解析失败:Lcom/sun/mail/util/PropUtil;尝试使用 javax.mail 时
- batch-file - 用于将文件移动到尚不存在的文件夹的批处理文件
- python - Groupby 对象的百分比变化(按组)