WCF作为一款功能强大的.NET Framework 3.5的重要组成部件,它的出现为开发人员带来了非常大的好处。今天就先为大家讲解一下WCF回调契约的相关定义方式。一个服务契约最多只能包含一个WCF回调契约。通过ServiceContract特性,可以指定回调契约:
interface ISomeCallbackContract
{
[OperationContract] void OnCallback( );
}
[ServiceContract(CallbackContract = typeof(ISomeCallbackContract))]
interface IMyContract {
[OperationContract] intDoSomething( );
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
WCF回调契约无须标记ServiceContract特性,但是在回调契约中必须为服务的操作标记OperationContract特性。
在导入回调契约的元数据中,回调契约以Callback结尾。为简便起见,我们在定义回调契约时,***以Callback为后缀。
为了托管一个回调对象,客户端需要实例化回调对象,然后通过它创建一个上下文对象:
class MyCallback : IMyContractCallback {
public void OnCallback( )
{...}
}
IMyContractCallback callback = new MyCallback( );
InstanceContext context = new InstanceContext(callback);
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
假定客户端的代理类为MyContractClient,则在客户端就可以通过上下文对象获得代理对象:
MyContractClient proxy = new MyContractClient(context);
- 1.
注意,如果使用了WCF回调契约,则客户端生成的代理类必须继承自DuplexClientBase<T>代理类,这是一个专门的支持双向通信的代理类。注意,该类的构造函数参数既可以接收InstanceContext类型的上下文对象,也可以接收object类型的回调契约对象。
然而,如果是通过SvcUtil或Visual Studio 2005生成的代理,却不能使用接收object类型对象的构造函数,若要创建代理对象,我们必须先创建上下文对象,如前面的代码所示。
我们可以手动修改代理类,添加对它的支持,如下所示:
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( );
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
注意,上述的代码中直接由客户端实现了回调契约,这是一种比较常见的实现方式。
客户端通过回调传递给服务端的消息包含了WCF回调契约终结点的引用。在服务端,可以通过OperationContext类的泛型方法GetCallbackChannel<T>()获得。如下所示:
ISomeCallbackContract callback = OperationContext.Current.
GetCallbackChannel<ISomeCallbackContract>( );
- 1.
- 2.
【编辑推荐】