首页 | 互联网 | IT动态 | IT培训 | Cisco | Windows | Linux | Java | .Net | Oracle | 软件测试 | C/C++ | 嵌入式开发 | 存储世界 | 服务器
网络设备 | IDC | 安全 | 求职招聘 | 数字网校 | 网页设计 | 平面设计 | 技术专题 | 电子书下载 | 教学视频 | 源码下载 | 搜索 | 博客 | 论坛
中国IT实验室Dotnet频道
中国IT教育
Google
首页 ASP.NET  C#  XML/WebService ADO.NET VC.NET VB.NET .NET 资讯动态 专题 RSS订阅 讨论 下载
您现在的位置: 中国IT实验室 >> Dotnet >> XMLWeb >> 正文

WCF中的发布-订阅服务

 
     通常,回调契约的每个操作都对应于特定的事件。ISubscriptionService的子接口(在本例中为IMySubscriptionService接口)不需要添加操作。ISubscriptionService接口提供了临时订阅的管理功能。每次调用Subscribe()或Unsubscribe()方法时,订阅者需要提供它需要订阅或取消订阅的操作名(以及事件名)。如果调用者希望订阅所有的事件,则传递一个空字符串,或者null值。

   我设计的框架提供了ISubscriptionService接口方法的实现,形式为SubscriptionManager<T>泛型抽象类:

public abstract class SubscriptionManager<T> where T : class 
{
public void Subscribe(string eventOperation);
public void Unsubscribe(string eventOperation);
//更多成员
}
   SubscriptionManager<T>的泛型类型参数为事件契约。注意,SubscriptionManager<T>并没有实现ISubscriptionService接口。

   应用程序需要以终结点形式暴露自己的临时订阅服务,该终结点需要支持ISubscriptionService接口的特定子接口。为此,应用程序需要提供派生自SubscriptionManager<T>的服务类,并将回调契约指定为类型参数,同时还要实现ISubscriptionService接口的子接口。例如,使用IMyEvent回调接口实现一个临时订阅服务:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] 
class MySubscriptionService : SubscriptionManager<IMyEvents>,IMySubscriptionService
{}
   MySubscriptionService的实现无需任何代码,因为IMySubscriptionService接口不会添加任何新的操作,而SubscriptionManager<T>已经实现了ISubscriptionService接口的方法。

   注意,仅仅继承SubscriptionManager<IMyEvents>是不够的,因为它没有派生自契约接口。我们必须添加对IMySubscriptionService的继承,才可以支持临时订阅。

   最后,应用程序需要定义IMySubscriptionService的终结点:

<services> 
<service name = "MySubscriptionService">
<endpoint
address = "..."
binding = "..."
contract = "IMySubscriptionService"
/>
</service>
</services>
   例B-2演示了SubscriptionManager<T>管理临时订阅的方式。

public abstract class SubscriptionManager<T> where T : class 
{
static Dictionary<string,List<T>> m_TransientStore;

static SubscriptionManager( )
{
m_TransientStore = new Dictionary<string,List<T>>( );
string[] methods = GetOperations( );
Action<string> insert = delegate(string methodName)
{
m_TransientStore.Add(methodName,new List<T>( ));
};
Array.ForEach(methods,insert);
}
static string[] GetOperations( )
{
MethodInfo[] methods = typeof(T).GetMethods(BindingFlags.Public|
BindingFlags.FlattenHierarchy|
BindingFlags.Instance);
List<string> operations = new List<string>(methods.Length);

Action<MethodInfo> add = delegate(MethodInfo method)
{
Debug.Assert(!operations.Contains(method.Name));
operations.Add(method.Name);
};
Array.ForEach(methods,add);
return operations.ToArray( );
}
static void AddTransient(T subscriber,string eventOperation)
{
lock(typeof(SubscriptionManager<T>))
{
List<T> list = m_TransientStore[eventOperation];
if(list.Contains(subscriber))
{
return;
}
list.Add(subscriber);
}
}
static void RemoveTransient(T subscriber,string eventOperation)
{
lock(typeof(SubscriptionManager<T>))
{
List<T> list = m_TransientStore[eventOperation];
list.Remove(subscriber);
}
}

public void Subscribe(string eventOperation)
{
lock(typeof(SubscriptionManager<T>))
{
T subscriber = OperationContext.Current.GetCallbackChannel<T>( );
if(String.IsNullOrEmpty(eventOperation) == false)
{
AddTransient(subscriber,eventOperation);
}
else
{
string[] methods = GetOperations( );
Action<string> addTransient = delegate(string methodName)
{
AddTransient(subscriber,methodName);
};
Array.ForEach(methods,addTransient);
}
}
}

public void Unsubscribe(string eventOperation)
{
lock(typeof(SubscriptionManager<T>))
{
T subscriber = OperationContext.Current.GetCallbackChannel<T>( );
if(String.IsNullOrEmpty(eventOperation) == false)
{
RemoveTransient(subscriber,eventOperation);
}
else
{
string[] methods = GetOperations( );
Action<string> removeTransient = delegate(string methodName)
{
RemoveTransient(subscriber,methodName);
};
Array.ForEach(methods,removeTransient);
}
}
}
//更多成员
}
 

上一页  [1] [2] [3] [4] [5] [6] 下一页

【责编:Zenghui】

中国IT教育

相关产品和培训
文章评论
 友情推荐链接
 认证培训
 专题推荐

 ·关于Java框架技术专题
 ·XML全攻略技术专题
 ·JAVA开源技术介绍专题
 ·Java嵌入式开发之J2ME技术专题
 ·超前体验 Oracle 11g的5个新特性…
 ·揭密使用VB.NET的五个实用技巧
 ·Oracle和SQL Server常用函数对比专题…
 ·展现C#世界 C#程序设计专题…
 ·Java入门 Tomcat的配置技巧精华专题…
 ·Oracle RMAN物理备份技术详解…
 今日更新
 社区讨论
 博客论点
 频道精选
 Dotnet频道相关导航