Prism 8 WPF已发现服务使用及多实现可配置调用方案咨询
基于Prism 8的多服务实现动态加载最优方案
核心思路
完全复用Prism原生能力,无需自行实现任何程序集扫描、加载、发现逻辑,同时兼容带返回值的服务调用需求。
- 用Prism自带的
DirectoryModuleCatalog做模块自动发现,只需要将所有服务实现类库/模块统一放到指定的扫描目录即可,Prism会自动完成dll识别、加载、模块初始化全流程,无需自定义反射加载代码。 - 所有
IService接口的实现都封装为Prism模块(即使原本是普通类库,只要新增一个极简的IModule实现类即可,无需修改原有服务逻辑),每个模块在自身的IModule.Initialize()方法中,将自己的IService实现以命名注册的方式注入到Prism的依赖注入容器,示例如下:
// 服务实现A的模块类 public class ServiceAModule : IModule { public void RegisterTypes(IContainerRegistry containerRegistry) { // 注册时带上唯一标识,和服务实现一一对应 containerRegistry.Register<IService, ServiceAImplementation>("ServiceA"); } public void OnInitialized(IContainerProvider containerProvider) {} }
- 用户选择的服务标识可以存在配置文件(App.config、appsettings.json均可),或者根据目录中存在的模块动态生成可选列表,完全适配你提到的「配置选择」「文件夹内容选择」两种需求。
带返回值的服务调用方案
不需要使用EventAggregator,直接通过依赖注入解析对应服务实现即可:
- 在需要调用服务的ViewModel构造函数中注入
IContainerProvider和配置实例,启动时根据配置的选中标识,直接解析出对应的IService实现,示例如下:
public class BusinessViewModel : BindableBase { private readonly IService _selectedService; public BusinessViewModel(IContainerProvider containerProvider, IConfiguration appConfig) { // 读取用户选中的服务标识 var selectedServiceKey = appConfig.GetValue<string>("ActiveServiceKey"); // 解析对应服务实例 _selectedService = containerProvider.Resolve<IService>(selectedServiceKey); } // 直接调用服务方法拿返回值 public object ExecuteService() { return _selectedService.GetReturnValue(); } }
可选优化(按需加载场景)
如果服务实现模块数量多,不想启动时全量加载,可以用IModuleManager在用户选定服务后再按需加载对应模块,加载完成后再解析服务实例即可,进一步降低启动资源消耗。
注意事项
所有服务实现模块都需要依赖IService接口所在的公共共享类库,不要每个模块单独定义IService,避免类型不匹配导致解析失败。
内容的提问来源于stack exchange,提问作者EuroEager
相关产品推荐
相关产品推荐

