WCF回調(diào)契約如何進行正確定義
WCF作為一款功能強大的.NET Framework 3.5的重要組成部件,它的出現(xiàn)為開發(fā)人員帶來了非常大的好處。今天就先為大家講解一下WCF回調(diào)契約的相關(guān)定義方式。一個服務(wù)契約最多只能包含一個WCF回調(diào)契約。通過ServiceContract特性,可以指定回調(diào)契約:
- interface ISomeCallbackContract
- {
- [OperationContract] void OnCallback( );
- }
- [ServiceContract(CallbackContract = typeof(ISomeCallbackContract))]
- interface IMyContract {
- [OperationContract] intDoSomething( );
- }
WCF回調(diào)契約無須標(biāo)記ServiceContract特性,但是在回調(diào)契約中必須為服務(wù)的操作標(biāo)記OperationContract特性。
在導(dǎo)入回調(diào)契約的元數(shù)據(jù)中,回調(diào)契約以Callback結(jié)尾。為簡便起見,我們在定義回調(diào)契約時,***以Callback為后綴。
為了托管一個回調(diào)對象,客戶端需要實例化回調(diào)對象,然后通過它創(chuàng)建一個上下文對象:
- class MyCallback : IMyContractCallback {
- public void OnCallback( )
- {...}
- }
- IMyContractCallback callback = new MyCallback( );
- InstanceContext context = new InstanceContext(callback);
假定客戶端的代理類為MyContractClient,則在客戶端就可以通過上下文對象獲得代理對象:
- MyContractClient proxy = new MyContractClient(context);
注意,如果使用了WCF回調(diào)契約,則客戶端生成的代理類必須繼承自DuplexClientBase<T>代理類,這是一個專門的支持雙向通信的代理類。注意,該類的構(gòu)造函數(shù)參數(shù)既可以接收InstanceContext類型的上下文對象,也可以接收object類型的回調(diào)契約對象。
然而,如果是通過SvcUtil或Visual Studio 2005生成的代理,卻不能使用接收object類型對象的構(gòu)造函數(shù),若要創(chuàng)建代理對象,我們必須先創(chuàng)建上下文對象,如前面的代碼所示。
我們可以手動修改代理類,添加對它的支持,如下所示:
- partial class MyContractClient : DuplexClientBase
<IMyContract>,IMyContract- {
- public MyContractClient(object callbackInstance) :
base(callbackInstance) {} //More constructors- public void DoSomething( ) { Channel.DoSomething( );
- }
- }
- class MyClient : IMyContractCallback,IDisposable
- {
- MyContractClient m_Proxy;
- public void CallService( )
- {
- m_Proxy = new MyContractClient(this);
- m_Proxy.DoSomething( );
- }
- public void OnCallback( )
- {...}
- public void Dispose( )
- {
- m_Proxy.Close( );
- }
- }
注意,上述的代碼中直接由客戶端實現(xiàn)了回調(diào)契約,這是一種比較常見的實現(xiàn)方式。
客戶端通過回調(diào)傳遞給服務(wù)端的消息包含了WCF回調(diào)契約終結(jié)點的引用。在服務(wù)端,可以通過OperationContext類的泛型方法GetCallbackChannel<T>()獲得。如下所示:
- ISomeCallbackContract callback = OperationContext.Current.
GetCallbackChannel<ISomeCallbackContract>( );
【編輯推薦】