Author:水如烟
总目录:行政区划数据方案设计
上一篇,行政区划程序的设计(十六),实现获取区划信息功能_2。
RegionalCodeCenter项目是为界面提供服务的中心。各项服务可能有一些特别的属性需要配置,所以也有一个服务环境问题需要纳入考虑。
这个方案比较简单,环境类Enviroment设置如下:
Enviroment.vb
Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.Windows.Forms.Design
Imports System.Drawing.Design
<Serializable()> _
Public Class Enviroment
Public Event EnviromentChanged()
Private gLogonInformations As New LzmTW.uSystem.uData.uSql.LoginInformations
Private gNetRegionalCodeFileName As String = ""
Private gDataSource As RegionalCodeCommon.Services.RegionalCodeServiceBase.DataSource = RegionalCodeCommon.Services.RegionalCodeServiceBase.DataSource.离线数据优先
Private gUseOldestVersion As Boolean = True
Private gRegionalCodeFileName As String = ""
Private gVersionDateFileName As String = ""
<Description("登录服务器信息"), Category("连接服务"), Browsable(False)> _
Public Property LogonInformations() As LzmTW.uSystem.uData.uSql.LoginInformations
Get
Return gLogonInformations
End Get
Set(ByVal value As LzmTW.uSystem.uData.uSql.LoginInformations)
gLogonInformations = value
End Set
End Property
<Description("本地区划码文件"), Category("更新服务"), Editor(GetType(FileNameEditor), GetType(UITypeEditor))> _
Public Property NetRegionalCodeFileName() As String
Get
Return gNetRegionalCodeFileName
End Get
Set(ByVal value As String)
If gNetRegionalCodeFileName <> value Then
gNetRegionalCodeFileName = value
OnEnviromentChanged()
End If
End Set
End Property
<Description("指定数据来源"), Category("数据服务")> _
Public Property DataSource() As RegionalCodeCommon.Services.RegionalCodeServiceBase.DataSource
Get
Return gDataSource
End Get
Set(ByVal value As RegionalCodeCommon.Services.RegionalCodeServiceBase.DataSource)
If gDataSource <> value Then
gDataSource = value
OnEnviromentChanged()
End If
End Set
End Property
<Description("指定如查询日期早于最旧版本日期,是否使用最旧的版本"), Category("数据服务")> _
Public Property UseOldestVersion() As Boolean
Get
Return gUseOldestVersion
End Get
Set(ByVal value As Boolean)
If gUseOldestVersion <> value Then
gUseOldestVersion = value
OnEnviromentChanged()
End If
End Set
End Property
<Description("本地版本信息文件"), Category("数据服务"), Editor(GetType(FileNameEditor), GetType(UITypeEditor))> _
Public Property VersionDateFileName() As String
Get
Return gVersionDateFileName
End Get
Set(ByVal value As String)
If gVersionDateFileName <> value Then
gVersionDateFileName = value
OnEnviromentChanged()
End If
End Set
End Property
<Description("本地区划信息文件"), Category("数据服务"), Editor(GetType(FileNameEditor), GetType(UITypeEditor))> _
Public Property RegionalCodeFileName() As String
Get
Return gRegionalCodeFileName
End Get
Set(ByVal value As String)
If gRegionalCodeFileName <> value Then
gRegionalCodeFileName = value
OnEnviromentChanged()
End If
End Set
End Property
Private Sub OnEnviromentChanged()
RaiseEvent EnviromentChanged()
End Sub
End Class
考虑到用户在应用的过程中会改变参数,因此建了一个事件EnviromentChanged通知服务中心环境变动了。
服务中心,类ServicesCenter
ServicesCenter.vb
Public Class ServicesCenter
Private gEnviroment As Enviroment
Private gRegionalCodeService As RegionalCodeService
Private gUpdateDatabaseService As UpdateDatabaseService
Private Const SQLSERVER2005 As String = "9.00"
Public ReadOnly Property Enviroment() As Enviroment
Get
Return gEnviroment
End Get
End Property
Public ReadOnly Property RegionalCodeService() As RegionalCodeService
Get
Return gRegionalCodeService
End Get
End Property
Public ReadOnly Property UpdateDatabaseService() As UpdateDatabaseService
Get
Return gUpdateDatabaseService
End Get
End Property
Sub New()
Initialize()
End Sub
Public Function TestConnectServer() As Boolean
Dim mResult As Boolean = False
'测试连接同时也获取SQLServer版本
mResult = Me.Enviroment.LogonInformations.TestConnect()
If mResult Then
If Me.Enviroment.LogonInformations.SqlVersion < SQLSERVER2005 Then
mResult = False
End If
End If
'无论是否能够连接上数据库,都提供服务
If gRegionalCodeService IsNot Nothing Then
gRegionalCodeService.Dispose()
gUpdateDatabaseService.Dispose()
End If
gRegionalCodeService = New RegionalCodeService(Me.Enviroment.LogonInformations.ConnectionStringBuilder.ConnectionString)
gUpdateDatabaseService = New UpdateDatabaseService(Me.Enviroment.LogonInformations.ConnectionStringBuilder.ConnectionString)
If Not mResult Then
Me.Enviroment.DataSource = RegionalCodeCommon.Services.RegionalCodeServiceBase.DataSource.离线数据优先
End If
RefleshServices()
Return mResult
End Function
Private Sub Initialize()
Dim mLocalDataPath As String = AppDomain.CurrentDomain.SetupInformation.ApplicationBase & "LocalData"
If Not IO.Directory.Exists(mLocalDataPath) Then
IO.Directory.CreateDirectory(mLocalDataPath)
End If
Me.gEnviroment = New Enviroment
With gEnviroment
.LogonInformations.Database = "RegionalCodeWorks"
.DataSource = RegionalCodeCommon.Services.RegionalCodeServiceBase.DataSource.离线数据优先
.UseOldestVersion = False
.NetRegionalCodeFileName = String.Concat(mLocalDataPath, "NetRegionalCode.xml")
.RegionalCodeFileName = String.Concat(mLocalDataPath, "RegionalCode.xml")
.VersionDateFileName = String.Concat(mLocalDataPath, "VersionDate.xml")
End With
AddHandler gEnviroment.EnviromentChanged, AddressOf gEnviroment_EnviromentChanged
gRegionalCodeService = New RegionalCodeService(Me.Enviroment.LogonInformations.ConnectionStringBuilder.ConnectionString)
gUpdateDatabaseService = New UpdateDatabaseService(Me.Enviroment.LogonInformations.ConnectionStringBuilder.ConnectionString)
RefleshServices()
End Sub
'环境改变了更新服务有关参数
Private Sub gEnviroment_EnviromentChanged()
RefleshServices()
End Sub
Private Sub RefleshServices()
If gRegionalCodeService Is Nothing Then Exit Sub
With Me.RegionalCodeService
.RegionalCodeFileName = Me.Enviroment.RegionalCodeFileName
.Source = Me.Enviroment.DataSource
.UseOldestVersion = Me.Enviroment.UseOldestVersion
.VersionDateFileName = Me.Enviroment.VersionDateFileName
End With
With Me.UpdateDatabaseService
.NetRegionalCodeFileName = Me.Enviroment.NetRegionalCodeFileName
End With
End Sub
Protected Overrides Sub Finalize()
If gRegionalCodeService IsNot Nothing Then
Me.RegionalCodeService.Dispose()
Me.RegionalCodeService.Dispose()
End If
RemoveHandler gEnviroment.EnviromentChanged, AddressOf gEnviroment_EnviromentChanged
MyBase.Finalize()
End Sub
End Class
考虑到多个服务实例使用的数据集是相同的,因此我已把几个关键的数据集修改了定义,为共享的:
Private Shared gNetDownloadLocalDataset As New Database.NetDownloadLocalDataSet
Private Shared gVersionDateList As New VersionDateList
Private Shared gRegionalCodeDataSet As New Database.RegionalCodeDataSet
Private Shared gVersionDateDataSet As New Database.VersionDateDataSet
相应的,为了保证数据集数据的安全修改,对DataTableCollection做了部分修改。修改后的方法是否有效,我也不大把握。我是参考了有关代码,只是没探究到底。在此列出来:
DataTableCollection类上,
Namespace uSystem.uData
Partial Class DataTableCollection(Of T As DataTable)
Public Sub Clear()
SyncLock Me.InternalSyncObject
For Each tableName As String In gTableNameList
Dim tmpTable As DataTable = gDataSet.Tables(tableName)
gDataSet.Tables.Remove(tmpTable)
tmpTable.Dispose()
Next
gTableNameList.Clear()
End SyncLock
End Sub
Public Sub Remove(ByVal tableName As String)
SyncLock Me.InternalSyncObject
If Not Contains(tableName) Then Exit Sub
Dim tmpTable As DataTable = gDataSet.Tables(tableName)
gDataSet.Tables.Remove(tmpTable)
tmpTable.Dispose()
gTableNameList.Remove(tableName)
End SyncLock
End Sub
Public Sub Add(ByVal table As DataTable)
Dim tmpTable As T = CommonServices.TableConverter(Of DataTable, T)(table)
Add(tmpTable)
End Sub
Public Sub Add(ByVal table As T)
SyncLock Me.InternalSyncObject
AddTable(table)
End SyncLock
End Sub
Protected Overridable Sub AddTable(ByVal table As T)
'如果已存在,则去除
Dim tmpTableName As String = table.TableName
Remove(tmpTableName)
gDataSet.Tables.Add(table)
gTableNameList.Add(tmpTableName)
End Sub
Private ReadOnly Property InternalSyncObject() As Object
Get
If gInternalSyncObject Is Nothing Then
Dim tmpObj As New Object
System.Threading.Interlocked.CompareExchange(gInternalSyncObject, tmpObj, Nothing)
End If
Return gInternalSyncObject
End Get
End Property
Private gInternalSyncObject As Object
End Class
End Namespace
对于两个委托,为了规范化,我也作了修改。修改后是否规范,也没把握。
Public Delegate Sub ServiceMessageEventHandler(ByVal sender As Object, ByVal e As ServiceMessageEventArgs)
Public Class ServiceMessageEventArgs
Inherits EventArgs
Private gMessage As String
Sub New()
gMessage = "待命"
End Sub
Sub New(ByVal message As String)
If String.IsNullOrEmpty(message) Then
gMessage = "待命"
Else
gMessage = message
End If
End Sub
Public ReadOnly Property Message() As String
Get
Return gMessage
End Get
End Property
End Class
Public Delegate Sub ServiceProgressPercentEventHandler(ByVal sender As Object, ByVal e As ServiceProgressPercentEventArgs)
Public Class ServiceProgressPercentEventArgs
Inherits EventArgs
Private gCurrentPercent As Integer
Sub New(ByVal currentPercent As Integer)
gCurrentPercent = currentPercent
End Sub
Public ReadOnly Property CurrentPercent() As Integer
Get
Return gCurrentPercent
End Get
End Property
End Class
目前为止的方案代码:代码
环境参数测试示图:
到目前为止,实现了整个方案的数据库和服务功能部分。
接下来的,是程序与用户的交互,也就是程序界面与数据的交互部分。
界面是否养眼,组装是否合理方便,这不是我的所能。
我做的,只是将用户想要的功能(方案分析中一开始列出来的简单需求)在界面上表现出来。
注意的,是怎样将界面与数据代码尽可能的分开。
以下我另设一个部分,叫行政区划程序界面的设计。
下一篇,行政区划程序界面的设计(一),实现界面表现的基本要点。