
WPF 模块化并不是简单地把代码拆成多个文件夹,而是建立一套清晰的契约。主程序只关心“有哪些模块”和“模块如何接入”,模块内部则负责自己的视图、视图模型、服务和资源。常见做法包括定义模块接口、使用依赖注入注册服务、通过区域或导航承载页面、用事件或消息机制进行模块通信。
一个可维护的 WPF 模块化架构通常包含四部分:模块契约定义模块名称和注册入口;模块目录负责发现和加载模块;依赖注入容器管理视图模型和服务;导航与通信机制让模块之间低耦合协作。主程序不再包揽所有业务,而是成为模块的宿主。
下面用一个简短示例说明模块注册思想。代码仅作结构示意。
public interface IAppModule
{
string Name { get; }
void Register(IServiceCollection services);
}
public class OrderModule : IAppModule
{
public string Name => "订单模块";
public void Register(IServiceCollection services)
{
services.AddSingleton<OrderView>();
services.AddSingleton<OrderViewModel>();
}
}主程序启动时收集所有 IAppModule,依次调用 Register,再由容器解析视图和视图模型。真实项目可结合 Prism、MEF 或自定义模块目录实现动态加载。关键在于:模块只暴露契约,不直接操作主窗口。
模块化后,模块之间不应频繁直接引用。常见通信方式包括共享服务接口、事件聚合器和消息总线。例如订单模块完成支付后发布“订单已支付”事件,库存模块订阅并扣减库存。这样两个模块无需知道对方类型。
生命周期也需要设计。模块可分为启动即加载、按需加载和延迟卸载。对于资源较重的报表模块,可以在用户首次打开时再加载;对于基础设置模块,则适合随主程序启动。模块初始化、导航进入、退出清理都应有明确钩子,避免资源泄漏。
第一,先划分业务边界,再划分工程。不要为了模块化而模块化,应按订单、库存、报表等业务能力拆分。第二,模块只依赖契约和基础设施,不依赖其他模块的具体实现。第三,视图模型通过依赖注入获取服务,避免在 View 后台代码中写业务逻辑。第四,建立统一的导航、日志、异常处理和权限机制,让模块共享基础设施。第五,保留人工可读的模块清单和加载日志,便于排查“模块未注册”“视图找不到”等常见问题。
C# + WPF 模块化的价值,不只是把代码拆小,而是把应用变成可组合的系统。主程序负责宿主能力,模块负责业务闭环,契约负责解耦,依赖注入和导航负责装配。对于中大型桌面应用,合理的模块化能显著降低耦合、提升协作效率,并为后续插件化、按需加载和独立发布留下空间。落地时应从清晰契约和少量核心模块开始,逐步完善通信、生命周期和治理机制。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。