2012年10月24日 星期三

WPF概觀:什麼是WPF



WPF Windows Presentation Foundation 的簡稱,中文直譯就是視窗表示介面基礎....翻得很爛,換個方式講就是視窗程式中編寫程式表達層(一般指UI)的技術與工具,他是微軟.NET 3.0表發表的幾個應用程式框架當中之一,以下節錄MSDN的描述:
----------------------------------------
WPF 是以 .NET Framework 型別子集的形式存在,這些型別多半位於 System.Windows 命名空間中。如果您以前曾使用 ASP.NET Windows Forms Managed 技術,以 .NET Framework 開發應用程式,那麼您應該熟悉基本 WPF 程式設計的過程,包括具現化類別、設定屬性、呼叫方法以及處理事件,全都使用您偏好的 .NET Framework 程式語言,如 C# Visual Basic
----------------------------------------
    看不懂?我們先別以程式語言的角度來看。
從發展史角度來看,以微軟對圖形化使用者介面(GUI)開發工具的支援發展史觀察「Win32API MFC ActiveX/COM/VB Windows Forms(.NET Framework)」一直到現在.NET 4.5都還持續擴充的Windows Presentation Foundation (WPF) ,可見WPF應該是未來微軟主推支援GUI的重要開發工具之一。

    從支援架構角度來看,簡單利用多層式架構來講解一下WPF的應用範圍;在多層式架構資料應用程式中至少包括三層:
1.          展示層(Presentation Tier):是使用者與應用程式進行互動的那一層,其中通常也包含其他應用程式邏輯,例如一醫療系統中,病人如何開始進行看病的流程;看病過程中各種資料呈現的方式(藥師的藥單、病人的收據)。常見的展示層通常包含:
n          資料繫結元件,例如 BindingSource BindingNavigator
n          資料的物件表示,例如在展示層中使用的 LINQ to SQL 實體類別。
n          本機資料庫,通常是作為資料庫快取的功能。
2.          中介層(Middle Tier) 是展示層和資料層用來彼此通訊的那一層 (Layer),例如醫生可以看哪些病人,掛號到取藥有什麼程序、住院到出院有什麼流程等。 典型的中介層元件包含下列各項:
n          商務邏輯,例如商務規則 (Business Rule) 和資料驗證。
n          資料存取元件和邏輯,例如ADO.NET、驗證、授權和個人化等。
3.          資料層(Data Tier) 基本上是儲存應用程式資料的伺服器 (SQL Server 的伺服器),例如醫院的藥品列表、人員列表、病例列表等。

其中,WPF的功能就是用來編寫應用程式的展示層,而中間層與資料層的開發上,微軟也有提出新的技術WCF(Windows Communiation Foundation)WF(Windows Workflow Foundation);當然,若程式的只是一個視窗的獨立程式,也一樣適合用WPF來架構(即展示層程式可視為Cient端程式,Cient端程式可視為獨立應用程式)。
從上面看起來好像WPF只是一個比較新版本的GUI編輯工具而已,跟以前的MFCVCL(Borland)等有何不同呢?當然有不同,而且是整個程式設計模式概念上的不同,不過可能要從WPF架構上開始講起才能講得比較明確,但這又是一段很長的故事了(其實是小弟所學未精的關係),簡單來講,WPF對於使用者介面的描述採用可延伸應用程式標記語言 (XAML)  (XML的一種)來進行實作,而相關需求功能行為則隱藏在背景的程式語言(如C#)實作 - MSDN稱為Managed 程式語言)。

2012年10月11日 星期四

.NET 動態程式碼的產生與編譯(一)-簡述



        由於工作上的需要,必須讓產品程式在RunTime階段,「可隨機載入可外部修改的部份編碼程式」;例如某產品的輸出結果,依需求在RunTime會有不同的邏輯運算組合方式—複雜點甚至不同的演算法邏輯的搭配組合,並且不希望為了部份程式碼的修改重新編譯整個程式。所以,針對此需求大概可分成幾個部份的問題概念:
1.          如何動態編碼與組譯?
2.          若要動態編譯的程式碼只是部份碼(會利用到DesignTime階段已建立的方法與成員),那要如何解決呢?
3.          動態程式碼編譯完成後,如何載入到主程式中?

綜合以上需求,其實就是在使用CodeDOM這個Namespace,其主要用來表示程式碼中的項目和結構的相關類別。

以下擷取自MSDN
The .NET Framework includes a mechanism called the Code Document Object Model (CodeDOM) that enables developers of programs that emit source code to generate source code in multiple programming languages at run time, based on a single model that represents the code to render.
To represent source code, CodeDOM elements are linked to each other to form a data structure known as a CodeDOM graph, which models the structure of some source code.
The System.CodeDom namespace defines types that can represent the logical structure of source code, independent of a specific programming language. The System.CodeDom.Compiler namespace defines types for generating source code from CodeDOM graphs and managing the compilation of source code in supported languages. Compiler vendors or developers can extend the set of supported languages.
Language-independent source code modeling can be valuable when a program needs to generate source code for a program model in multiple languages or for an uncertain target language. For example, some designers use the CodeDOM as a language abstraction interface to produce source code in the correct programming language, if CodeDOM support for the language is available.
The .NET Framework includes code generators and code compilers for C#, JScript, and Visual Basic.
         
MSN的敘述中我們可以看出,CodeDOM提供了我們外部源碼在RunTime階段的生成與編譯功能,而其強大的CodeDom名稱空間包含了許多以語言中立的形式描述常見程式結構的物件,其中每一種語言的細節則由與該種語言對應的 CodeProvider物件負責處理。簡單講其包括了兩個主要部份:
1.          System.CodeDom讓程式自行產生一個通用程式語言的虛擬架構,例如CodeCompileUnit是用來為CodeDom程式容器提供容器,CodeEntryPointMethod則提供程式的進入點(eg. Main(){….}
2.          System.CodeDom.Complier則提供生成實際文檔,並提供編譯相關的功能,例如CodeDomProvider提供基底類別 (Base Class) 以轉換成其他語言eg. C#Microsoft.CSharp.CSharpCodeProvider)。

所以CodeDom基本上就可以解決源碼動態生成與編譯的問題;那要「動態程式碼編譯完成後,如何載入到主程式中?」的問題呢?這裡我們會用到.NET另外一個特別的技巧「反映 (Reflection)」,在下列狀況中,十分有利於Reflection的使用(節錄自MSDN:
·         當您需要存取程式中繼資料的屬性。請參閱使用反映存取屬性主題。
·         檢查與執行個體化組件中的型別。
·         在執行階段建置新型別。請使用 System.Reflection.Emit 中的類別。
·         執行晚期繫結,存取在執行階段所建立型別的方法。請參閱主題動態載入和使用型別

Reflection的概念很繁雜,在這裡其實主要只有MethodInfo的調用而已,等之後用到的時候再來細談。