我有一个架构问题。我有一个概念上类似的项目:
这似乎很简单,但有皱纹。一些背景,通过一个部分虚构的例子。这是一个ASCOM driver,它控制着一些电机,传感器和一些电源开关。硬件设备可以旋转天文台圆顶并报告其位置,打开和关闭快门,并打开和关闭各种观察仪器(望远镜,相机,聚焦器等)的电源。
硬件抽象层处理通过串行链路发送和接收命令以及随之而来的任何时序和排序问题。表示层可以调用HAL中的方法来使硬件执行某些操作,这可能会在串行端口上生成一系列命令和响应,或者根本不生成。未经请求的数据也可以到达串口,并在HAL中完全处理。
'表示层'由几个COM接口组成。一个接口(IDome)处理控制圆顶和快门,另一个(IPower)处理各种设备的功率控制。这是标准,不能更改。
当两个不同的程序想要访问设备时出现问题。例如,一个程序可能希望通过IDome接口控制球机,另一个程序可能希望使用IPower接口控制功率。在当前实现中,这会导致在不同进程中创建整个程序集的两个实例,并且由于串行端口上的争用而导致一个实例失败,这只能允许一个连接。
我需要找到一种解耦HAL和表示层的方法,这样COM接口可以由多个进程加载,而HAL只加载一次并服务于表示层的所有实例。
目前所有这些'层'都包含在一个.NET程序集中,如果可能的话,我宁愿保持这种方式。
哪种模式对这种情况有好处?任何和所有建议都非常感激。
答案 0 :(得分:1)
一种选择是将需要单身的东西(HAL)实际上放在盒子上。例如,您可以将HAL逻辑移动到Windows服务中,表示层可以通过进程间通信(管道或tcp套接字)进行通信。要确保只启动一个服务实例,您可以强制实施静态服务名称,但也可以通过让服务采用系统范围的互斥锁来防止在多个用户会话下运行的服务实例。
答案 1 :(得分:0)
您可以使用DCOM。我们的想法是将您的CLSID注册为进程外服务器(可选择使用COM+)。当您的客户端创建这些CLSID的实例时,它们都将在“代理进程”中创建,并且Windows将透明地封送客户端进程和此代理进程之间的调用。
请注意,要执行此操作,您的界面必须为“proxy/stub DLL”。如果编译包含接口定义的IDL文件,它将为此类代理/存根DLL生成C代码。然后,您必须注册此DLL以进行进程外通信,以便与自定义接口一起正常工作。
或者,您可以在HAL级别应用相同的进程外激活模型 - 即,为HAL创建COM接口,将HAL的CLSID注册为进程外服务器,并使您的内部组件通过DCOM进行通信。这样做的好处是您可以控制接口CLSID,并且可以注册您自己的代理/存根DLL,而不会与其他供应商的代理/存根DLL冲突。
答案 2 :(得分:0)
就模式而言,您需要一个控制对HAL的所有访问权限的代理,这是给定的。
在控制访问方面,多个UI是否可以控制一组资源?假设你确实也想要,那么代理会使用逻辑解决冲突等问题。
或者,您有两个代理逻辑部分,一个接受输入,另一个报告当前值,以便多个订户客户端(UI)可以跟上HAL所在的位置。事件驱动的方法在这里可以很好地工作,也可以查看发布/订阅模式。对于单一控件,请查看锁定模式。
在所有情况下,代理都是应用控制逻辑的地方,但代码结构本身会比这更复杂。