.NET 5.0如何通过反射批量注册所有Hosted Service托管服务
实现方案
你可以直接通过反射筛选所有符合条件的Worker服务类型,手动注册为IHostedService单例即可,无需反射调用扩展方法,实现逻辑如下:
private static void RegisterHostedServices(IServiceCollection services) { // 定位Worker服务所在的程序集,可根据你的实际项目结构调整为其他定位方式 var assembly = Assembly.GetAssembly(typeof(BaseWorkerService<>)); // 筛选所有非抽象、非接口、继承自BaseWorkerService的实现类 var workerTypes = assembly.GetTypes() .Where(t => !t.IsAbstract && !t.IsInterface && t.BaseType != null && t.BaseType.IsGenericType && t.BaseType.GetGenericTypeDefinition() == typeof(BaseWorkerService<>) ); // 批量注册,等效于手动调用AddHostedService<T> foreach (var workerType in workerTypes) { services.TryAddEnumerable(ServiceDescriptor.Singleton(typeof(IHostedService), workerType)); } }
补充说明
- 如果你更习惯通过反射调用
AddHostedService扩展方法,可替换上述循环部分的逻辑:
// 获取AddHostedService泛型方法定义 var addHostedMethod = typeof(ServiceCollectionHostedServiceExtensions) .GetMethods(BindingFlags.Public | BindingFlags.Static) .First(m => m.Name == nameof(ServiceCollectionHostedServiceExtensions.AddHostedService) && m.GetParameters().Length == 1 ); foreach (var workerType in workerTypes) { // 构造对应泛型方法并执行 var genericMethod = addHostedMethod.MakeGenericMethod(workerType); genericMethod.Invoke(null, new object[] { services }); }
- 筛选条件可根据你的需求调整,比如你也可以通过是否实现
IAppHostedService接口来筛选,写法如下:
var workerTypes = assembly.GetTypes() .Where(t => !t.IsAbstract && !t.IsInterface && t.GetInterfaces().Contains(typeof(IAppHostedService)) );
- 如果你的Worker服务分布在多个程序集中,遍历所有相关程序集执行筛选逻辑即可。
内容的提问来源于stack exchange,提问作者Matt Ghafouri
相关产品推荐
相关产品推荐

