如何在多个F#模块间共享单个Windows记录实例?
实现F#中Windows记录的全局共享实例
步骤1:定义Windows记录类型
在F#中保留原有的记录类型定义:
open System open System.Windows type Windows = { createReportMenu: Func<Window> createProgressNote: Func<Window> createPatientRegistrationWindow: Func<Window> }
步骤2:创建全局共享模块
通过模块级可变绑定实现全局实例的存储与访问,用Option类型避免未初始化时的空引用问题:
module GlobalWindows = // 私有可变变量,存储Windows实例的可选值 let mutable private _instance: Windows option = None // 初始化方法,用于接收并设置全局实例 let init (windows: Windows) = _instance <- Some windows // 对外提供的实例访问方法 let getInstance () = match _instance with | Some win -> win | None -> failwith "GlobalWindows 未完成初始化,请先调用 init 方法"
步骤3:在主程序中初始化全局实例
修改F#的Program.main函数,接收C#传递的委托参数,创建Windows记录实例并完成全局初始化:
module Program = let main (mainWindow: Window) (createReportMenu: Func<Window>) (createProgressNote: Func<Window>) (createPatientRegistrationWindow: Func<Window>) = // 构建Windows记录实例 let windowsInstance = { createReportMenu = createReportMenu createProgressNote = createProgressNote createPatientRegistrationWindow = createPatientRegistrationWindow } // 初始化全局共享实例 GlobalWindows.init windowsInstance // 执行后续主程序逻辑...
步骤4:在其他F#模块中使用全局实例
任意F#模块都可以通过GlobalWindows.getInstance()获取实例,调用对应的窗口创建委托:
module PatientManagementModule = let openRegistrationWindow () = let windows = GlobalWindows.getInstance() let regWindow = windows.createPatientRegistrationWindow.Invoke() regWindow.ShowDialog()
注意事项
- 线程安全:如果应用是多线程环境,需要在
init和getInstance方法中添加锁(如lock语句)来避免竞态条件。 - 初始化时机:必须确保
GlobalWindows.init在任何模块调用getInstance之前执行,否则会抛出异常。如果希望更优雅地处理未初始化情况,可以将getInstance的返回值改为Windows option,让调用者自行处理None场景:let getInstance () = _instance
内容的提问来源于stack exchange,提问作者Alan Wayne
相关产品推荐
相关产品推荐

