目 錄
第十章 宿主程序詳細設計... 2
10.1 配置文件設計... 3
10.2 加載設備驅動... 4
10.3 加載界面視圖... 8
10.4 加載數據導出... 12
10.5 加載服務組件... 14
10.6 全局異常監測... 17
10.7 小結... 19
前幾章對設備驅動、IO實例、外部接口和總體控制器等進行了詳細介紹,這些都是框架平台的有機組成部分,這部分相當於後台服務的支撐組件,通過模塊化實現框架平台的搭建;宿主程序也是框架平台的一部分,作為承載插件的一個軟件平台,是人機交互的唯一接口,通過鼠標點擊完成各種指令,是插件式框架平台最終要實現的部分。在《第2章 框架總體的設計》的“2.1 宿主程序設計”中對宿主程序的整體功能和界面進行了規劃和設計,但是並沒有涉及到細節層面,要實現這些設計的功能,包括3方面工作:界面的實現,也就是UI布局,涉及到少量的代碼控制;與插件(設備驅動、圖形顯示、數據導出和服務組件)進行交互,把需要的插件加載到宿主程序中,最終傳遞給後台服務;與《第8章 總體控制器的設計》中的IDeviceController總控制器接口進行交互,可以理解為與後台服務的支撐組件進行交互,接收宿主程序的輸入,一般為插件信息、操作響應等。交互的結構示意圖如下:
宿主程序接受來自人員的動作,通過配置文件完成加載插件或者把已經加載的插件與總控器進行交互。當然,宿主程序也可能與其他輔助事務進行交互。
加載插件的方式有很多種,可以通過遍歷指定目錄下的程序集,找到相應的插件接口類型,並且加載到框架平台,現在有很多編輯軟件都是采用的這樣方式。但是我感覺這種方式多少有些暴力,不能任何人來到你家門前就允許他進門的。所以,SuperIO框架平台采用一種更友好的方式,通過配置文件加載插件。把二次開發好的插件信息配置到相應的文件中,只有插件信息“合法”的情況下才會根據情況加載插件到框架平台中。
基於這樣思想,就需要對配置文件進行設計,以什麼樣的文件格式保存信息,以及都保存什麼樣的信息。
配置文件的格式采用XML方式,對.NET Framework的System.Configuration.Configuration工具類進行二次封裝。先定義一個接口,對操作配置文件進行規范,接口定義如下圖:
配置文件保存什麼樣的信息,取決於應用過程中所需要的信息,不同的插件可能用到的配置信息不一樣。那麼先定義一個基礎的配置信息,包括:插件文件路徑、實例類信息(命令空間和類名)、標題和標注等信息,以便可以通過反射工具類加載插件。配置信息類定義如下圖:
使用配置文件操作基類生成的文件格式如下圖:
設備驅動的配置文件與基礎配置文件不一樣,主要涉及到兩部分:可掛載的設備驅動信息和已經掛載到框架平台的驅動信息。
可掛載的設備驅動信息在AssemblyDeviceSectionGroup配置組中進行配置,當掛載新的設備驅動的時候,如增加設備,就會從這個配置組中加載信息,以便操作人員進行選擇。配置組下的設備驅動配置信息定義如下圖:
當調用增加設備窗體的時候會從配置文件讀取程序集信息,如下圖:
當觸發增加設備事件的時候,會創建新的設備驅動,代碼實現如下:
public static IRunDevice CreateDeviceInstance(int devid, int devaddr, string devname, int assemblyid, string assemblyname, string instance, CommunicationType type, DeviceType devType, object iopara1, object iopara2) { IObjectBuilder builder = new TypeCreator(); IRunDevice dev = builder.BuildUp<IRunDevice>(Application.StartupPath + "\\SuperIO\\DeviceConfig\\" + assemblyname, instance); dev.DeviceParameter.DeviceAddr = devaddr; dev.DeviceParameter.DeviceName = devname; dev.DeviceRealTimeData.DeviceName = devname; if (type == CommunicationType.COM) { dev.DeviceParameter.COM.Port = (int)iopara1; dev.DeviceParameter.COM.Baud = (int)iopara2; } else if (type == CommunicationType.NET) { dev.DeviceParameter.NET.RemoteIP = (string)iopara1; dev.DeviceParameter.NET.RemotePort = (int)iopara2; } dev.IsRegLicense = true; dev.CommunicationType = type; dev.UserLevel = UserLevel.High; dev.InitDevice(devid); if (!Device.DebugDevice.IsDebug) { //--------------------把設備信息配制到文件中------------------------// CurrentDeviceSection section = new CurrentDeviceSection(); section.DeviceID = dev.DeviceParameter.DeviceID; section.AssemblyID = assemblyid; section.X = 0; section.Y = 0; section.Note = String.Empty; section.CommunicateType = dev.CommunicationType; DeviceAssembly.AddDeviceToXml(section); //---------------------------------------------------------------// } return dev; }