WCF繼承實際應用技巧分享
當我們在使用WCF開發工具進行相應功能的開發時,首先要熟練掌握的當然是基于這一工具下的代碼的編寫方式。那么今天我們就先來體驗一下WCF繼承的相關應用方式,以此加深我們對這方面的認知程度。
在過去中,我們已經習慣了C#繼承的各個特性,我們可以按如下的方式定義我們的繼承關系:
- [ServiceContract]
- public interface ISimpleCalculator
- {
- //Other Members
- [OperationContract]
- int Add(int arg1, int arg2);
- }
- [ServiceContract]
- public interface IScientificCalculator : ISimpleCalculator
- {
- [OperationContract]
- int Multiply(int arg1, int arg2);
- }
Ok,不要擔心,在服務端這樣的特性依然穩健地存在著:
- public class ScientificCalculatorService : IScientificCalculator
- {
- //Other Members
- #region IScientificCalculator Members
- public int Multiply(int arg1, int arg2)
- {
- return arg1 * arg2;
- }
- #endregion
- #region ISimpleCalculator Members
- public int Add(int arg1, int arg2)
- {
- return arg1 + arg2;
- }
- #endregion
- }
但是緊接著,Client端呢?
- [System.CodeDom.Compiler.GeneratedCodeAttribute
("System.ServiceModel", "3.0.0.0")]- [System.ServiceModel.ServiceContractAttribute(ConfigurationName=
"ServiceReference.IScientificCalculator")]- public interface IScientificCalculator {
- //Other Members
- [System.ServiceModel.OperationContractAttribute(Action=
"http://tempuri.org/ISimpleCalculator/Add", ReplyAction=
"http://tempuri.org/ISimpleCalculator/AddResponse")]- int Add(int arg1, int arg2);
- [System.ServiceModel.OperationContractAttribute(Action=
"http://tempuri.org/IScientificCalculator/Multiply",
ReplyAction="http://tempuri.org/IScientificCalculator/MultiplyResponse")]- int Multiply(int arg1, int arg2);
- }
在Reference.cs文件內,我們只能看到IScientificCalculator 接口的身影,卻找不到ISimpleCalculator的蹤跡。而事實上我們在服務端對這兩個接口都定義了ServiceContract的Attribute,也許這對你來說并不重要,或者你不太關心這些繼承特性所帶來的優勢,但是正也是因為這些繼承特性所能帶來的優勢(包括多態等經典的OO特性)我們需要改造這個Reference.cs以使其適應我們“真正的需要”。類似以下的應用將會失敗:
- static void Main(string[] args)
- {
- ScientificCalculatorClient calculator = new ScientificCalculatorClient();
- UseScientificCalculator(calculator);
- calculator.Close();
- }
- //Will not be supported now
- static void UseSimpleCalculator(ISimpleCalculator calculator)
- {
- Console.WriteLine("Calculator Add : {0}", calculator.Add(5, 4));
- }
- static void UseScientificCalculator(IScientificCalculator calculator)
- {
- Console.WriteLine("Calculator Add : {0}", calculator.Add(5, 4));
- Console.WriteLine("Calculator Multiply : {0}", calculator.Multiply(5, 4));
- }
當前的WCF繼承問題就是:#t#
ISimpleCalculator接口在客戶端是不被識別的。要解除這樣的矛盾,就是要讓客戶端也擁有該接口。
首先我們考慮到我們與Service之間的通信是依賴ServiceContract來描述的,ServiceContract就類似OO中的Interface,一經發布就不可以修改了(盡量!)。我們能做的最好就是能在Client端將這些內容重新搭建起來,包括之間的繼承關系。
在Add ServiceReference之后系統為我們自動生成了很多內容,找到Reference.cs,這將是我們大刀闊斧的地方……
我們可以看到它里面只實現了一個IScientificCalculator接口,這是我們先前就提到過的,我們的系統調用服務,都是通過從這里獲取它們想要的“服務端”的一些類去構造本地實例來完成一系列操作的。那么我們現在只需要在這里引入相應的接口繼承結構即可……
將原來實現的唯一接口注釋掉,并添加以下代碼:
- //[System.CodeDom.Compiler.GeneratedCodeAttribute
("System.ServiceModel", "3.0.0.0")]- //[System.ServiceModel.ServiceContractAttribute(ConfigurationName =
"ServiceReference.IScientificCalculator")]- [ServiceContract]
- public interface ISimpleCalculator
- {
- //Other Members
- // TODO: Add your service operations here
- [OperationContract]
- int Add(int arg1, int arg2);
- }
- //[System.CodeDom.Compiler.GeneratedCodeAttribute
("System.ServiceModel", "3.0.0.0")]- //[System.ServiceModel.ServiceContractAttribute(ConfigurationName =
"ServiceReference.IScientificCalculator")]- [ServiceContract(ConfigurationName="ServiceReference.
IScientificCalculatorVolnet")]- public interface IScientificCalculator : ISimpleCalculator
- {
- [OperationContract]
- int Multiply(int arg1, int arg2);
- }
我們需要using System.ServiceModel之后才可使用以上的WCF繼承代碼,該代碼片斷其實沒有什么很特別的地方,它與服務端的接口繼承沒有什么大的出入,唯一需要關注的則是我黑體標注的“ConfigurationName="ServiceReference.IScientificCalculatorVolnet"”,注意,我這里不是在為自己的昵稱做廣告噢,而是以示區別。