Catel依赖注入中如何为同一实现类注册多个接口
问题根因
- 字段初始化时机错误:你定义的
CustomerSearchFilterList是类级别的实例字段,字段初始化逻辑会在构造函数执行前运行,此时customersController还未在构造函数中完成赋值,自然无法读取到对应属性。 - 接口设计与注册逻辑不匹配:业务能力定义在
ICustomerSearch接口中,但你注册和注入的是无任何成员的空接口IService,即使实例是CustomerControlService类型,直接用IService访问也无法拿到ICustomerSearch的成员,手动强转也增加了类型转换异常的风险。 - 依赖注入用法冗余:构造函数已经传入了注入的服务实例,不需要再手动调用
ServiceLocator.Default.ResolveType二次解析,不符合DI最佳实践。
解决方案
1. 调整服务注册逻辑
直接注册业务对应的ICustomerSearch接口,避免绕空接口IService:
// App.xaml.cs 注册代码修改为 ServiceLocator.Default.RegisterType<ICustomerSearch, CustomerControlService>();
如果你的架构要求必须保留IService的注册,可以同时注册两个接口指向同一个单例实例:
var serviceInstance = new CustomerControlService(); ServiceLocator.Default.RegisterInstance<IService>(serviceInstance); ServiceLocator.Default.RegisterInstance<ICustomerSearch>(serviceInstance);
2. 重构ViewModel代码
直接注入需要的ICustomerSearch接口,将属性赋值逻辑放到构造函数中执行:
public class CustomerControlViewModel : ViewModelBase { private readonly ICustomerSearch _customerService; // 不要在字段初始化时访问未赋值的成员 public List<string> CustomerSearchFilterList { get; set; } // Catel会自动注入已注册的ICustomerSearch实例 public CustomerControlViewModel(ICustomerSearch customerService) { _customerService = customerService; // 构造函数中赋值,此时服务实例已完成初始化 CustomerSearchFilterList = _customerService.CustomerSearchFilterList; } }
3. 修复服务实现的语法缺陷
你当前CustomerSearchFilterList的set访问器是空实现,不符合接口定义约束,如果你不需要对外修改该属性,可以直接去掉接口中的set声明:
// 修改ICustomerSearch接口 public interface ICustomerSearch { // 移除不需要的set访问器 public List<string> CustomerSearchFilterList { get; } public int SelectedFilter { get; set; } public List<ICustomer> OnFindCustomer(); } // 对应简化实现类的属性写法 public List<string> CustomerSearchFilterList => GetAvailableFilters();
完成以上修改后即可正常读取到CustomerSearchFilterList的内容。
内容的提问来源于stack exchange,提问作者JeroenZenM
相关产品推荐
相关产品推荐

