題外話:
對不住各位,本打算年前把這個系列寫完,結果由於雜務纏身一直推到年后
我特別痛恨我自己!我覺得不但對不起各位!也對不起自己。
最近煩躁不安,不能專心向學。也不知道如何是好。
……
好吧,言歸正傳
說個前提條件:
此項目雖然使用了silverlight 4.0
但是服務端只能在dotNet3.5下運行
這也是我們為什么自己實現riaService的原因
實體層設計
由於有這個限制條件,我們設計的實體層也有所區別
如下圖為實體層的程序集(只有MenuM實體類,其他實體類未加入。)

下面來看一下實體層MenuM的代碼
這里有幾點需要說明
1:
特性[DataContract]與[DataMember]標記
是為了客戶端與服務端傳輸數據的時候序列化與反序列化引入的
2:
MenuM類繼承自Entity類
然而在.net 3.5中是沒有Entity類的
那么我們就創建了這個類(就是Attr文件夾下的 Entity.cs類)
這個類雖然在這里看上去沒什么用
但是在silverlight客戶端用處就非常大(等會會說道為silverlight客戶端自動生成實體類型,silverlight 4.0是有Entity類的)
3:
[Display(Name = "菜單名稱")]
如上:Display特性在dotNet3.5中也是不存在的
同理,我們創建了DisplayAttribute特性,也是為了使用Silverlight4.0的客戶端特性
為客戶端動態生成服務代理和實體類型
使用過Silverlight RIA Service的人一定都知道
每次編譯的時候都會在Silverlight程序集中生成如下目錄和文件

此文件就包含了服務代理和實體類型
那么為了達到與RIA Service一樣的效果
我們為服務端程序集增加了VS2010的后期生成事件命令行
如下圖所示

命令行代碼為
$(SolutionDir)RTMDemo.Compile\bin\Debug\RTMDemo.Compile.exe
其中
$(SolutionDir)為宏,指解決方案的目錄(定義為驅動器 + 路徑);包括尾部的反斜杠“\”。
更多生成事件命令行的宏請參見這里:http://msdn.microsoft.com/zh-cn/library/42x5kfw4(v=vs.90).aspx
這個命令行的意思是
在編譯完服務端類庫后
執行RTMDemo.Compile\bin\Debug\RTMDemo.Compile.exe
也就是這個類庫的生成文件

那么我們來看一下這個程序集中的主要工作
1.保存目錄路徑以備讀取和寫入
2.添加實體類型
此端代碼大意為:
遍歷實體類庫文件夾內的文件,
讀取文件名以M結尾的文件(約定實體類名必須以M結尾)
然后按正則匹配[DataContract]以后的內容
把這些內容保存起來以備寫入目標文件
3.添加服務代理
獲取服務端類信息與獲取實體類信息不同
獲取服務端類信息使用了反射
我們反射出類的名字,類中的方法名,參數名,參數類型,返回值類型等
來生成形如下面這樣的服務端代理
至於ServiceInvoker是什么,我們將在下一節內容中介紹
注意:這樣生成服務端代理暫不支持生成服務端方法的重載代理
在獲取參數或返回值類型的時候,
會遇到獲取泛型類型的情況(如:List~<….>,就不能把這些拼到字符串內去)
我們使用諸如下面的函數來做簡單判別
4.寫入代理文件
原始的代理文件模版如下
寫入代理文件主要是匹配兩個region
然后插入之前生成的字符串
調用此函數的代碼如下
WriteToTar("服務", sb.ToString());
至此就把服務代理和實體類型都拷貝到客戶端去了
在下一節我們介紹怎么使用這些內容
………………………………………….寫文章不容易…………………請務必點個推薦吧………………………………………………