我们正在开发一款SaaS应用程序,目前面临不同客户要求不同定制的情况。我已经通过谷歌搜索并阅读了很多关于多租户的内容。我也熟悉策略模式。
但是,这仍然让我对Angular 2+应用程序的良好概念感到有些困惑。业务逻辑不会成为问题,因为我可以使用Angular的依赖注入来加载和使用不同客户的自定义服务。主题本身也不是问题,因为我们使用Angular Material,它内置了一个很好的主题引擎。给我带来头痛的是模板本身。当然,我可以在HTML模板中使用
让我们举一个现实生活的例子。在搜索页面上,所有客户都可以搜索对象并将单个对象导出为文件下载。一位特定的客户要求我们实现一种专有文件格式的批量导出功能,这需要在页面上添加一个新按钮,显然其他所有客户都不应该看到。
我能想到的三个选项(但我真的不喜欢任何一个)如下:
1. 如前所述,在模板本身中使用 *ngIf 和/或 *ngSwitch* 2. 利用 Angular Material 的主题能力,仅使用 CSS(display: none;) 3. 维护组件的多个版本(根据需要使用组件继承),并根据用户加载正确版本的组件
它们都有明显的缺点,只是列举了其中一些:
但是,这仍然让我对Angular 2+应用程序的良好概念感到有些困惑。业务逻辑不会成为问题,因为我可以使用Angular的依赖注入来加载和使用不同客户的自定义服务。主题本身也不是问题,因为我们使用Angular Material,它内置了一个很好的主题引擎。给我带来头痛的是模板本身。当然,我可以在HTML模板中使用
*ngIf
和*ngSwitch
,但这正是我想避免的代码类型,因为一旦达到50个以上的客户版本,它将变得可怕。让我们举一个现实生活的例子。在搜索页面上,所有客户都可以搜索对象并将单个对象导出为文件下载。一位特定的客户要求我们实现一种专有文件格式的批量导出功能,这需要在页面上添加一个新按钮,显然其他所有客户都不应该看到。
我能想到的三个选项(但我真的不喜欢任何一个)如下:
1. 如前所述,在模板本身中使用 *ngIf 和/或 *ngSwitch* 2. 利用 Angular Material 的主题能力,仅使用 CSS(display: none;) 3. 维护组件的多个版本(根据需要使用组件继承),并根据用户加载正确版本的组件
它们都有明显的缺点,只是列举了其中一些:
- 当客户数量增加并且定制变得更加频繁时,维护起来会变成噩梦(想象一下一个有6个不同版本和50个客户的大型组件...)
- 目前是我的最爱,但功能并没有真正禁用,只是隐藏了(当然后端会检查权限,但仍然会传输比必要更多的信息给用户)
- 对于组件的代码部分运行良好,但意味着需要维护大量重复的模板代码
我相信我们不是第一个解决这个问题的人。我是否忽略了任何缺点更少的解决方案?是否有任何可以应用于此处的代码模式?
编辑:在我们公司进行更多讨论后,我们意识到还有另一个重要的问题:一些客户托管在自己的服务器上,但大多数客户都是从一个中央服务器提供服务的。这意味着可选功能必须在运行时检测和添加,这意味着某种程度上的笨拙。
所以我们的方法是扩展现有的许可证数据库,以包含客户特定的功能,这样显然只有该客户拥有许可证。现在简单的解决方案是拥有一个许可证端点并获取客户已获得的所有许可证,然后每个可选函数都可以坐在一个简单的单一*ngIf
中。我很欣赏这是一个简单和清洁的解决方案,但它提供了发现我们公司其他客户的一些业务事实的潜力(通过取消混淆代码并找到其他端点等)。因此,将其与服务器端渲染相结合可能是我目前能想到的最佳解决方案。