我目前正在开发一个多租户系统,我已经实现了混合流,允许每个客户使用单个数据库和基于请求的共享数据库,
然而,某些客户需要一些定制,因为他们的流程稍有不同,但我只有一个单一的系统用户流。
如何在不影响系统上其他客户的情况下为客户实施此定制?
请看我现在的架构
编辑:客户化主要与用户旅程相关,例如工资单系统,客户A希望将工资单发送给MD进行审批,而客户B希望会计在MD之前进行审批。
如果我们谈论的是数据库。
我要做的是添加一个json类型的对象为他们的定制
比如加个custom_fields栏
Customer Table
//your properties
custom_fields : nvarchar(max)
带有样本值
custom_fields
NULL //for customers without custom_fields
{"CustomFieldA" : "ValueForA", "CustomFieldB" : "ValueForB"} \\for customers with specific request
然后在c#端,在动态对象或确定的类上对其进行理想化。
//if not determined
var customField = JsonSerializer.Deserialize<ExpandoObject>(jsonString);
然后访问值
foreach (var key in customField.Select(x => x.Key))
{
//to get the custom property name
var propertyName = key.ToString();
//to get the value
var value = customField.First(x => x.Key == key).Value;
}
从高层次的角度来看,在同一模式下运行的多租户解决方案中,我们可以通过对所有租户严格应用所有模式更改来解决许多问题,而不仅仅是那些请求更改的租户。
如果你能避免它,不要考虑动态模式,而是开发产品,以便所有租户都能享受到这些好处,并将那些过于苛刻或不符合核心产品的请求回击。
可以说不(或者要求淫秽的费用以使其值得努力)
诀窍是以向下兼容的方式实现任何更改,如果类获得了新属性,但您不希望它们自动对所有租户可用,那么使用继承来扩展类,如果您引入了新关系,请将它们设为可选的。如果您已经将您的表示层与数据模型充分解耦,那么保留以前不使用新属性的视图并有效地对任何需要新属性的视图进行皮肤处理就不会有任何问题。
如果您的域模型可以被抽象为有效的文档管理,那么主要的流程管理和配置方面就不需要知道特定的租户业务模型,只需要抽象的,在这种情况下,JSON或XML序列化技术可以使用回应。
一个很好的例子是第三方物流或经纪应用程序中的寄售、清单和采购订单,域模型仅通过一组公共标识符和几个公共描述性字段松散地跟踪寄售和行项,但原始内容可能是序列化并存储到数据库中的单个字段中,因为大多数数据和处理操作不需要知道特定的内容或其结构。
这在第三方物流中经常出现,因为使用不同数据平台和软件的不同运营商与发送端和接收端的客户进行交互,多个实体之间可能涉及TBT,但这些实体在本质上是在飞行过程中没有任何数据所有权或修改数据的权利。
数据的生命周期包括摄取、多阶段处理、通知和某种形式的出口。在引入时,我们应用特定的转换来解释标准模式需要从数据中知道什么,但是对于其他所有内容,以其本机形式查看序列化内容通常是可以接受的,这意味着对于每个定制的数据类型,都会有相应的转换可以呈现本机窗体的标准模型和视图。
如果唯一的更改是在数据处理的编排中,那么除了流程步骤的配置和一些状态管理之外,实际上不需要太多的模式更改来实现。
可能出现的编排解决方案包括Azure功能、Azure持久功能、逻辑应用程序或其他工作流引擎。即使您已经有了可以执行各种任务和操作的核心API或代码库,您仍然可以使用工作流技术基于配置的触发器执行这些endpoint。
您还可以研究用于处理数据的更微服务风格的体系结构,从模式的角度来看,Web钩子或域事件可能会有所帮助,请阅读域驱动设计和微服务体系结构中的域事件与集成事件