設計期、執行期的區別雖然很清楚,但是如何在設計期未知,開發出能夠在執行期正確運作的系統呢?為了解決這件事,首先得將問題定義何為設計議題,何為部署議題,配合適當的開發架構,解決在未知情況之下設計出能夠正確運作的系統。
以 3 個例子說明何為設計議題,何為部署議題,以及在設計期未知的情況下,如何開發出執行期能正確運作的系統。
<檔案操作權限不足是部署議題>
檔案操作權限不足,有時會被誤解為是設計議題,其實這應該是部署議題,只要在部署時提供權限足夠的帳號即可。
藉由這個議題,額外說明 Kuick Utility Framework 提供的『執行期身份轉換』功能:
// 將這裡的數值,視為來自於 config 檔
string domain = "Kuick";
string userName = "tester";
string password = "Kuick";
string path = @"C:\Kuick\";
// 使用 Kuick.Impersonator 進行身份轉換,
// 因為 Impersonator 實作 IDisposable 介面,
// 所以可以使用 using 包裹處理區段,
// 程式依據不同情況,分別寫下合適的記錄檔,
// 如果有安全考量,請勿將密碼寫到記錄檔。
using(Impersonator imp = new Impersonator(domain, userName, password)) {
try {
if(Directory.Exists(path)) {
// 資料夾已經存在,寫出追蹤類型記錄 (Track)
Logger.Track(
"資料夾已經存在",
new Any("path", path)
);
} else {
// 資料夾不存在,寫出訊息類型記錄 (Message)
DirectoryInfo info = Directory.CreateDirectory(path);
Logger.Message(
"成功建立資料夾",
new Any("path", path)
);
}
} catch(Exception ex) {
// 發生例外錯誤,寫出錯誤類型記錄 (Error)
Logger.Error(
"建立資料夾失敗",
ex,
new Any("domain", domain),
new Any("userName", userName),
new Any("password", password),
new Any("path", path)
);
}
}
<資料庫連線是部署議題>
與其他 ORM 不同的是,Kuick Entity 在設計期間,完全不需考量執行時所對應的資料庫為何,僅需在系統部署時,經由 config 檔設定即可。Kuik 允許每一個 Entity 個別定義所對應的資料庫,例如,有 3 個 Entity 分別為 UserEntity, RoleEntity, DepartmentEntity,其資料庫連線設定可能為:
1. 單一資料庫連線設定
所有 Entity 使用共同的資料庫連線。
config 檔案裡定義一個 entityName 為 Default 的資料庫連線,代表所有 Entity 的預設資料庫連線。
<configuration>
<Kuick>
<database>
<add
entityName="Default"
vender="MSSQL"
connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=Kuick;User ID=tester;Password=ironman5;Max Pool Size=10;"/>
</database>
</Kuick>
</configuration>
2. 多重資料庫連線設定
因為資料安全性考量,人資部門要求 UserEntity 不可與其他資料放在相同的資料庫裡,所以 UserEntity 使用與 RoleEntity, DepartmentEntity 不同的資料庫連線。
config 檔案裡除了定義一個 entityName 為 Default 的預設資料庫連線之外,另外定義 UserEntity 的資料庫連線。執行期,Entity 會從資料庫連線設定快取 (Kuick.Date.DbSettingCache),取得正確的資料庫連線設定 (Kuick.Date.DbSetting)
<configuration>
<Kuick>
<database>
<add
entityName="Default"
vender="MSSQL"
connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=Kuick;User ID=tester;Password=ironman5;Max Pool Size=10;"/>
<add
entityName="UserEntity"
vender="Oracle"
connectionString="Data Source=Kuick2;User Id=tester2;Password=1111;"/>
</database>
</Kuick>
</configuration>
設計期相同的 Entity,在執行期可以設定連到不同的資料庫,甚至是不同類型的資料庫 (MSSql, Oracle, MySQL, ..),唯一需要考慮的是,當 Entity 之間資料存在 Join 選取操作時,部署時需要將這些 Entity 設定成相同的資料庫連線。
以專案思考,部署時每個 Entity 能任意切換資料庫的功能,看來是多餘的,但是當開發出來的是一個軟體,部署時如何滿足所有客戶不同的需求,這項功能就顯得重要。
<設計期未知的資料操作>
試想,實作一個網站,維護任何 Entity 的資料,功能包含資料查詢、排序、列表、新增、修改、刪除、統計,所有完整的功能,這是一個最典型在設計期未知的資料操作,該如何設計就留待最後的實作分享裡詳述,這裡僅以簡單的例子,呈現出在設計期未知的情況下,如何開發程式。
// 設計期已知:
// Actived 欄位值為 true
List<UserEntity> users1 = UserEntity
.Sql()
.Where(x => x.Actived == true)
.Query();
// 設計期未知:
// columnName 變數在執行期所指的欄位值為 true
string columnName = "Actived";
List<UserEntity> users2 = UserEntity
.Sql()
.Where(new SqlExpression(columnName).EqualTo(true))
.Query();
設計期未知,這程度上讓 Lambda Expression 無用武之地,還好 Kuick 實作各種設計期未知的解決方案,除了上圖呈現的例子之外,後續分享還會有更多的介紹。
======================================
即然這裡提及 Lambda Expression,下一篇分享內容就來介紹 Kuick 支援那些 Lambda Expression,以及這項功能是如何實作的。
========================================
鐵人賽分享列表:Kuick Application & ORM Framework
開放原始碼專案:kuick.codeplex.com
直接下載原始碼:Kuick
下載相關文件檔:C# Code Conventions and Design Guideline
相關教學影片區:Kuick on YouTube