C#依赖注入:组件注册覆盖问题如何解决?
问题解决方法
首先明确问题根源:你的DeclareServicesFor<T>方法大概率只将类型T注册为其最顶层抽象基类BaseWriter的实现,未单独注册T自身的服务。当DI容器需要解析CommonWriter或CustomWriter具体类型时,会向上匹配基类的注册,最终都返回CommonWriter实例。
以下是几种可行的解决方式:
1. 显式注册具体类型为自身服务
放弃依赖自动注册基类的逻辑,手动指定每个类型的注册方式,确保DI容器能精准解析具体类型:
// 注册CommonWriter为自身类型,同时作为BaseWriter的实现 services.AddTransient<CommonWriter>(); services.AddTransient<BaseWriter, CommonWriter>(); // 注册CustomWriter为自身类型,若需要它也作为BaseWriter的实现可额外添加 services.AddTransient<CustomWriter>(); services.AddTransient<BaseWriter, CustomWriter>(); // 若需区分可使用命名服务
这样RawReports中的Common属性会注入CommonWriter实例,Custom属性会注入CustomWriter实例。
2. 调整注册顺序并补充具体类型注册
如果必须使用DeclareServicesFor<T>方法,需确认该方法是否支持注册类型自身。若不支持,可补充注册具体类型:
// 先注册CustomWriter,再注册CommonWriter,避免基类注册被覆盖 services.DeclareServicesFor<CustomWriter>(); services.DeclareServicesFor<CommonWriter>(); // 补充注册具体类型,确保DI能直接解析 services.AddTransient<CustomWriter>(); services.AddTransient<CommonWriter>();
3. 使用命名服务区分不同实现
如果需要在其他场景中区分BaseWriter的不同实现,同时保证RawReports能获取正确实例:
// 注册具体类型服务 services.AddTransient<CommonWriter>(); services.AddTransient<CustomWriter>(); // 注册BaseWriter的不同命名实现 services.AddTransient<BaseWriter, CommonWriter>("Common"); services.AddTransient<BaseWriter, CustomWriter>("Custom");
后续在需要指定实现时,可通过名称获取对应的实例。
内容的提问来源于stack exchange,提问作者Mateus Lima Silveira
相关产品推荐
相关产品推荐

