IServiceProvider构造函数注入原理及实例创建自定义逻辑植入方案
解决方案:统一拦截DI实例创建流程,实现自定义逻辑
1. 抽离通用实例处理逻辑
先把你需要的检查+事件订阅逻辑封装成独立方法,方便复用:
private static void RegisterEventHandler(object instance, IEventBroker eventBroker) { if (instance is IHandle handler) { eventBroker.Subscribe(handler); // 可在此添加你需要的其他检查逻辑 } }
2. 修改批量注册逻辑,注入自定义实例化工厂
替换原有的AddSingleton/AddTransient直接注册方式,改用带工厂参数的重载,让DI容器在创建实例时自动执行你的逻辑:
private static void ConfigureViewModels(IServiceCollection services, Type[] types) { var viewModels = GetTypesAssignableTo(typeof(IViewModel), types); foreach (var viewModel in viewModels) { if (viewModel.IsAssignableTo(typeof(ISingletonViewModel))) { services.AddSingleton(viewModel, serviceProvider => { // 让DI自动解析构造函数依赖(依赖实例也会走相同工厂逻辑) var instance = ActivatorUtilities.CreateInstance(serviceProvider, viewModel); // 执行自定义逻辑 var eventBroker = serviceProvider.GetRequiredService<IEventBroker>(); RegisterEventHandler(instance, eventBroker); return instance; }); } else { services.AddTransient(viewModel, serviceProvider => { var instance = ActivatorUtilities.CreateInstance(serviceProvider, viewModel); var eventBroker = serviceProvider.GetRequiredService<IEventBroker>(); RegisterEventHandler(instance, eventBroker); return instance; }); } } }
3. 方案原理说明
- 覆盖构造注入场景:
ActivatorUtilities.CreateInstance会让DI容器递归解析构造函数的所有依赖(比如ThisViewModel依赖的AnotherViewModel),而依赖实例的创建同样会触发对应的工厂逻辑,确保注入前就完成检查和订阅。 - 统一逻辑入口:不管是构造注入自动解析,还是手动调用
GetService<T>,都会走工厂里的实例化流程,保证所有ViewModel实例都执行相同的自定义逻辑。 - 兼容原有注册规则:保留了原有的单例/瞬态判断逻辑,无需修改ViewModel的构造函数或继承关系。
注意事项
确保IEventBroker的注册优先级高于ViewModel,比如在调用ConfigureViewModels之前执行:
services.AddSingleton<IEventBroker, EventBroker>();
内容的提问来源于stack exchange,提问作者Alex Nicholas
相关产品推荐
相关产品推荐

