交付可安装客户端时如何避免附带Onion Architecture冗余内层代码?
Onion架构下桌面/移动端配套应用的依赖问题处理方案
你提到的按消费端拆分核心业务程序集的方案,本质上是和Onion架构的核心设计原则相悖的——Onion架构的内层业务逻辑归属,是按照领域业务边界划分的,而非按照哪个客户端要用哪段代码划分。按客户端拆程序集不仅会造成同一领域逻辑的归属混乱,后续每新增一个消费端就要调整一次拆分边界,长期维护成本极高,完全没有必要这么做。
方案1:通过服务端接口开放共享逻辑,不直接在客户端引用领域程序集
这是最匹配你两个核心顾虑的方案:
- 对于配套应用需要用到的业务逻辑,直接在现有Web应用的服务端对外暴露轻量的HTTPS接口,所有计算逻辑还是在原有的内层领域层执行,客户端只需要发送请求、接收结果即可
- 这个方案完全不需要改动现有分层结构:剩下的核心机密逻辑全部留在服务端内层,客户端根本拿不到代码,不存在机密泄露的问题
- 配套客户端只需要实现UI交互、网络请求、本地缓存逻辑,没有冗余的领域代码,安装包体积可以压到最小
如果有离线场景的计算需求,可以把对应无状态、无机密的纯计算逻辑,抽成独立的共享内核静态类,这部分内容本来就是可公开的通用能力,不存在归属混乱的问题。
方案2:必须本地运行离线逻辑时,用发布裁剪替代主动拆分程序集
如果确实有部分逻辑必须在客户端离线执行,也不需要为了客户端拆分核心领域程序集:
- 现代支持AOT编译的技术栈(.NET、Native AOT等)原生支持发布时代码裁剪能力:就算你在客户端项目里引用了整个核心领域程序集,发布时编译器会自动扫描所有实际触发的代码路径,把没有被调用、不会执行的代码全部从最终安装包里剔除,从根源上减少冗余
- 对于需要保护的机密逻辑,不需要从物理上把代码移走,只需要把这部分逻辑的类、方法设置为
internal访问级别,搭配InternalsVisibleTo特性,只给服务端的外层项目开放访问权限。客户端就算引用了整个领域程序集,也在编译期就无法访问、更无法把这部分代码打包进安装包
这个方案的核心优势是完全不改动现有业务逻辑的代码归属:所有代码还是留在原来的领域层位置,不存在两个归属地的问题。不管后续来多少个新的消费端,你都不需要调整程序集的拆分边界,发布流程会根据实际引用情况自动处理裁剪,不会出现边界反复拉扯的问题。
常见认知误区
- 不要把"编译期引用程序集"等同于"整个程序集的所有代码都会打包到安装包":现在的发布裁剪、AOT编译能力已经可以做到只打包实际被调用的代码,引用关系只是用来保证编译时的类型检查,不是强制全量打包
- 不要按消费端维度拆分核心领域层:一旦开始按"哪个客户端要用"拆代码,最后核心领域层会被拆成十几个零散的程序集,完全丧失领域模型的内聚性
内容的提问来源于stack exchange,提问作者Sandro
相关产品推荐
相关产品推荐

