開發 Silverlight:在 Silverlight 上建置您的商務應用程式
Silverlight 已經發展為開發和部署主要商務應用程式所用的可靠平台。
Gill Cleeren 和 Kevin Dockx
Microsoft 是在距今三年前發表 Silverlight,首次亮相是在拉斯維加斯的 Mix07 上,當時它是第一版全新的 Microsoft 功能豐富網際網路應用程式 (RIA) 平台。現在 Silverlight 已經發展為可用來建置和維護商務應用程式的可靠平台了。
Silverlight 1.0 的程式撰寫模型是以 XAML 和 JavaScript 為基礎。由於後者不太適合建置企業應用程式,因此第一版主要是用於媒體中心案例。不過當 Silverlight 2 發表時,這個平台已經成為開發企業營運 (LOB) 應用程式的絕佳選擇了。最重要的改變是能夠以 .NET (C# 或 VB.NET) 取代 JavaScript 來編寫程式碼。
為了「測試」Silverlight 在建置 LOB 應用程式方面的功能和適用性,我們擬定了一份簡單的一般商務應用程式需求清單。接著我們就來看看 Silverlight 是否符合這些需求。
資料、資料、資料
一提到商務應用程式,首先您想到的是什麼?資料是王道。Silverlight 應用程式是在瀏覽器內的用戶端上執行,但資料卻是位於伺服器端的資料庫中。Silverlight 命名空間和組件並沒有 ADO.NET 支援,所以它不支援 DataReaders 或 LINQ-To-SQL 這類知名的功能。
而且 Silverlight 也沒有用戶端資料庫。所以它不能算是一種解決方案。您一定不希望無意中把資料庫的暫時副本和用戶端機器上的機密資訊儲存在同一個地方吧。
解決方法很簡單:在資料庫最上層再加上一個服務層。您可以利用這個服務層連接資料庫,而且最好是透過商務層。這麼一來 Silverlight 就可以在用戶端上連接這些服務,並且擁有資料的存取權 (請參閱 [圖 1])。
[圖 1] Silverlight 可以連接用戶端上的服務。
Silverlight 支援 ASMX、WCF 和 REST 服務類型。您也可以利用 Silverlight 來使用 Sockets 和 net.tcp 這類較為奇特的服務。如果您要把 Silverlight 加在企業內部現有的技術堆疊上,那麼您就有福了。Silverlight 可以從您在其他應用程式類型所用的服務取得其資料。
從 Silverlight 的角度來看,使用 ASMX 和 WCF 服務也是一樣的道理。如果您要實作這個服務,WCF 應該就是您的預設選項。讓我們看看一個連接 WCF 服務的基本範例。第一步是定義服務要做什麼。這個服務會傳回一份產品清單。
[ServiceContract(Namespace = "")]
publicclassOrderService
{
[OperationContract]
publicList<Product> GetAllProducts()
{
...
}
}
待服務準備就緒之後,我們就可以連接 Silverlight 了。我們可以從 Visual Studio 加入一個服務參考來連接 Silverlight (請參閱 [圖 2])。
[圖 2] 使用 Visual Studio 加入一個指向 Silverlight 的服務參考。
現在 Visual Studio 就要建置 Proxy 類別了。您可以把 Proxy 類別視為服務類別的用戶端副本,它以呼叫服務方法來取代方法實作。Silverlight 中所有的服務通訊,都是非同步進行的。在下面這個程式碼範例中,我們要使用這個 Proxy 取得產品清單:
privatevoid button1_Click(object sender, RoutedEventArgs e)
{
OrderService.OrderServiceClient proxy = new OrderService.OrderServiceClient();
proxy.GetAllProductsCompleted += newEventHandler<OrderService.GetAllProductsCompletedEventArgs>(proxy_GetAllProductsCompleted);
proxy.GetAllProductsAsync();
}
void proxy_GetAllProductsCompleted(object sender, OrderService.GetAllProductsCompletedEventArgs e)
{
ProductGrid.ItemsSource = e.Result;
}
REST 是目前非常熱門的通訊協定,因為它被廣泛運用在 Facebook 和 Twitter 等 Web 2.0 API 上。Silverlight 也完全支援它。另外,Silverlight 也具有一個以多層式 Silverlight 應用程式開發的特定服務架構:WCF RIA Services。
進入多層式架構
在建立 Silverlight 應用程式時,通常是透過服務層取得資料。但是目前並無現成的簡便方式,可以只靠編寫資料傳輸物件和類別 — 包括驗證/授權在內 — 一次完成。Silverlight 應用程式是針對限制版 Microsoft .NET Framework 4 所建置。因此您無法在 Silverlight 應用程式中,參考針對完整版 .NET Framework 4 所建置的組件 (例如,包含類別/驗證邏輯的組件)。
而這正是 WCF RIA Services 應運而生的原因,它正是為了簡化 LOB RIA 的開發而建立。它們會在伺服器端和用戶端提供架構、控制項和服務,以解決建置多層式應用程式的複雜性。
它們可以讓您編寫連結到伺服器端資料存放區的服務。這可以是 SQL Server 資料庫、您自己的 POCO 類別,或是實體模型。然後它會在您的用戶端產生這些實體。接著它會在用戶端產生必要的內容、方法和作業,以方便與您的服務交談。
如果您很熟悉 Entity Framework,那麼用起來就得心應手了。因為它可以讓您用類似的方法編寫程式碼。舉個例說,如果您的用戶端 DomainContext 負責追踨變更集合、含有實體清單,而且可讓您提交這些變更,這樣就可以「蒙蔽」您是透過服務層工作的事實。
WCF RIA Services 基本上是一種把程式碼注入用戶端的伺服器端技術。同時它也能簡化在服務與實體新增驗證和授權/驗證的作業。它可以大幅減少您建置 LOB Silverlight 應用程式所需耗費的開發時間。
控制問題
Silverlight 具有一個擴充的控制項集合,其中含有簡單的控制項,例如按鈕、文字方塊和下拉式方塊等。同時它的預設安裝套件還有許多更進階的控制項,例如 DataGrid、RichTextBox 和 MediaElement。Microsoft 每發行一個新版本,都會增加更多控制項。
Microsoft 也建立了 Silverlight 控制項工具組。這是一組額外的控制項,它們是開放原始碼,可以透過 CodePlex.com 免費取得。這個套件會定期更新,並且以頻外方式 (out-of-band) 隨著 Silverlight 定期發行。
它含有許多控制項,可讓身為 Silverlight 企業開發人員的您工作起來更加輕鬆。另外還有製表控制項,可在下一項需求派上用場:報告。
列印可能性
列印仍然是一項廣為需要的商務需求。現在有了 Silverlight 4,您就可以直接從 Silverlight 列印。您可以利用這個 API 指定您要列印的內容,無論是列印整個螢幕,還是列印像報告這類動態產生的內容都可以。因此,在 Silverlight 4 中搭配工具組提供的控制項 (例如豐富的圖表) 來建立報告解決方案,是相當容易的事。
典範與最佳作法
當您使用 Silverlight 或 XAML 應用程式時,必須考量的重點就是程式碼最好能夠採用有別於過去以傳統技術 (像是 ASP.NET 或 Windows Forms) 編碼的方式加以編碼。雖然您可以用同樣的方式編寫程式碼,但是最好不要這麼做,因為這樣就無法完全發揮技術的功效。
Silverlight 應用程式應該相當倚頼 DataContext、Data Binding 和 Observer 模式,而且指派 TextBox 值給物件不應該有重複的程式碼,或反之亦然。您必須撰寫的這類程式碼越多,就越可能在程式碼當中注入錯誤。其實您只要將物件繫結到 UI 元素,就會透過程式碼中的物件,自動產生正確的值。事實上,您根本不應該直接存取 UI 元素。
這就是 Model-View-ViewModel (MVVM) 設計模式派上用場的地方。它通常是用來鼓勵您區隔問題 (您的程式碼後置幾乎不含任何程式碼)。它可以讓您在應用程式 UI 上,與開發人員分開工作,同時也可以提升程式碼的測試性。
但最重要的優點是,它可以鼓勵開發人員充分發揮 DataContext 和 Data Binding 技術的功效。View 中的 ViewModel 是被當作 DataContext 使用,當中包含所有的資料內容。
這些內容是透過 Data Binding 繫結到 View 中的 UI 元素。因此 ViewModel 基本上會把它從 Model 取得的資料 (資料的物件表示法),轉換為 View 可以使用的資料。您可以把 ViewModel 當作是「打了類固醇的轉換器」。
待一切都準備妥當之後,您得將事件 (例如,Button Click) 轉送到 ViewModel,而不是轉送到 Views 程式碼後置。這一點可以透過命令完成。Silverlight 提供一種 ICommand 介面,讓您將 UI 元素繼承按鈕底層繫結到命令。這些命令是在 ViewModel 上定義。
接著您必須找到管道讓這些 ViewModel 在不互相參考的情況下,於不同的 ViewModel 之間彼此通訊。這一點您可以透過廣播/接聽原則做到。ViewModel 訂閱者會收到特定類型的訊息,而另一個 ViewModel 則會傳送另一個訊息。收到該訊息之後,您就可以採取必要動作了。
最後,您必須確保 View 知道它的 DataContext 是什麼。您可以利用幾種方法做到 — View 優先方法 (View 是由應用程式具現化,並且負責將它所需的 ViewModel 具現化) 或 ViewModel 優先方法 (與 View 優先方法相反)。這些方法通常都使用 IoC container 或 Managed Extensibility Framework (MEF) 來重新履行責任。
實作 MVVM 的方式相當多。您可以撰寫自己的實作,不過在開放原始碼社群中已經有很不錯的實作可供使用,像是 MVVM Light Toolkit、Caliburn 或 Prism 都是。
誠如您所見,Silverlight 已經準備好建置企業級的應用程式了。事實上,這就是我們兩個每天要做的例行公事。
Gill Cleeren是一位 Microsoft 區域經理 (theregion.com)、MVP ASP.NET、INETA 講師機構成員以及 Silverlight 從業人員。他現居比利時,在 Ordina 擔任 .NET 架構設計師。他也為各種開發人員雜誌撰寫許多文章,最近才剛出版他的第一部著作《Silverlight 4 Data and Services Cookbook》(Packt Publishing,2010 年)。他的部落格網址是 snowball.be。
Kevin Dockx在 RealDolmen 擔任 .NET Web 應用程式的技術專員/專案領導人,RealDolmen 是比利時規模最大的 ICT 公司之一。雖然他的工作偏重於 Silverlight,不過他也非常注意 Microsoft .NET (Web) Stack 新開發的其他產品。他固定在各種國內外活動上擔任講師,例如荷蘭的 Microsoft DevDays、葡萄牙的 Microsoft Techdays,還有 BESUG 活動 (比利時 Silverlight 使用者群組)。他的部落格有 Silverlight、.NET 和漫談隨筆等各種趣聞報導,網址為:blog.kevindockx.com。