Bru*_*ell 5 c# generics dependency-injection asp.net-core
假设我们有以下服务:
interface IService { }
interface IService<T> : IService {
    T Get();
}
在 ASP.Net-Core 中,在我们注册了一些不同的实现后,T我们可以获得所有注册的服务,如下所示:
IEnumerable<IService> services = serviceProvider.GetServices<IService>();
现在,因为我需要从其他接口访问泛型类型参数,但这不是一个选项。如何在IService<T>不丢失泛型类型的情况下检索 的所有实现?就像是:
IEnumerable<IService<T>> services = serviceProvider.GetServices<IService<T>>();
foreach (var s in services) {
    Method(s);
}
// Here we have a generic method I don't have control over.
// I want to call the method for each `T` registered in DI
void Method<T>(IService<T> service) {
    Type t = typeof(T); // This here will resolve to the actual type, different in each call. Not object or whatever less derived.
}
所有这些都应该有一个相当不错的表现。
根据@JeroenMostert的有用评论,我发现了一种完全可以做我想做的事情的方法。正如他指出的,由于我们在编译时不知道通用参数类型,因此我们无法静态绑定该方法调用。我们需要的是后期绑定。
反射是一种后期绑定,但有一个更好的解决方案:dynamic
答案中的示例将变为:
IEnumerable<IService> services = serviceProvider.GetServices<IService>();
foreach (var s in services) {
    Method((dynamic)s);
}
void Method<T>(IService<T> service) {
    // This here will resolve to the actual type, different in each call. Not object or whatever less derived.
    Type t = typeof(T);
}
强制转换dynamic会将方法绑定推迟到运行时,当实际类型s已知时。然后它将寻找最合适的重载(如果没有,则会抛出异常)。与使用反射相比,这种方法有一些优点:
您可以在此处阅读一篇关于此方法及其与反射的比较的优秀深入文章。
| 归档时间: | 
 | 
| 查看次数: | 4457 次 | 
| 最近记录: |