如何将动态加载程序集中的服务添加至ServiceCollection?
动态加载类型的依赖注入注册解决方案
你的问题核心在于:泛型版本的TryAddSingleton<TService, TImplementation>要求泛型参数必须是编译时已知的类型,但myVendorType是通过反射在运行时获取的类型,所以无法直接作为泛型参数传入。
下面是两种可行的解决方案:
方案1:使用非泛型的TryAddSingleton重载
直接传入服务接口类型和动态获取的实现类型,容器会自动处理实例化逻辑:
private IServiceProvider ConfigureServices() { const string vendor = "MyVendor"; Assembly assembly = null; try { assembly = Assembly.LoadFrom($"{vendor}.dll"); } catch (FileNotFoundException) { throw new Exception($"Module '{vendor}' not found"); } var myVendorType = assembly.GetType($"{vendor}.Services.{vendor}Service"); if (myVendorType == null) throw new Exception($"Module '{vendor}' service implementation not found"); var services = new ServiceCollection(); // ... 注册其他服务 // 使用非泛型重载,直接传入类型 services.TryAddSingleton(typeof(IMyService), myVendorType); return services.BuildServiceProvider(); }
注意:原代码中存在变量名不一致问题(声明了services却用serviceCollection调用方法),上面的代码已经修正。
方案2:自定义实例化工厂
如果需要手动控制实例的创建逻辑(比如需要传入构造参数),可以使用工厂委托的重载:
services.TryAddSingleton(typeof(IMyService), sp => { // 这里可以根据需要自定义实例化方式,比如注入其他依赖 var dependency = sp.GetRequiredService<ISomeDependency>(); return Activator.CreateInstance(myVendorType, dependency) as IMyService; });
这两种方式都能解决动态类型无法通过泛型方法注册的问题,其中方案1最简洁,适合无特殊构造需求的场景。
内容的提问来源于stack exchange,提问作者bquarta
相关产品推荐
相关产品推荐

