当前位置:编程学习 > 网站相关 >>

WCF后续之旅(4):WCF Extension Point 概览

在本系列的每篇文章中,我多次提到WCF是一个极具可扩展性的分布是消息通信框架。为了让读者对WCF Extension有一个总体的的认识,在这里我会简单列举了我们经常使用的绝大部分的扩展点,以及通过这些扩展点能够解决实现项目开发中的那些问题。

有一点需要特别提醒的是:对WCF extensions的灵活应用依赖于你对channel layer和service mode dispatching system的深入理解。所以,如果你对channel layer不甚了解,可以参阅本系列的第一个部分(html" target=_blank>WCF是如何通过Binding进行通信的)和第二部分(如何对Channel Layer进行扩展——创建自定义Channel), 若是想了解更多关于dispatching system的细节,可以参考本系列的第三部分(WCF Service Mode Layer 的中枢—Dispatcher)。

现在,我们按照在上一篇文章的Dispatching的执行流程,来介绍dispatching system中可以用于对WCF进行扩展的对象,已经这个可扩展对象具体解决的问题和扩展的方式。为了利于读者理解这些可扩展对象具体被使用在Dispatching整个的生命周期的哪个阶段,我们在标注Step 1、Step 2…字样,读者可以在上一篇文章中查阅对应的步骤在执行怎样的功能

 

1 、自定义InstanceContextProvider(Step 5)

在WCF infrastructure中, InstanceContext是以一个很重要的概念。InstanceContext是什么呢?简言之,InstanceContext就是对service instance的封装(service instance wrapper),对于每一个service instance来讲,WCF都会通过一些contextual information对其进行包装。这些contextual information存在的目的在于让不同的request关联到对应的service instance上。对于不同的Instancing Mode(PerCall、PerSession和Singleton),我们往往具有不同的InstanceContext。而对于PerSession方式的instancing mode,InstanceContext显得尤为重要,原因很简单,我们必须保证来自同一个Session的request被分发到同一个service instance,不然很难维护其session的信息。

InstanceContext的获取通过InstanceContextProvider来实现。在WCF中所有的InstanceContextProvider实现了System.ServiceModel.Dispatcher.IInstanceContextProvider interface。

public interface IInstanceContextProvider
{
// Methods
InstanceContext GetExistingInstanceContext(Message message, IContextChannel channel);
void InitializeInstanceContext(InstanceContext instanceContext, Message message,
IContextChannel channel);
bool IsIdle(InstanceContext instanceContext);
void NotifyIdle(InstanceContextIdleCallback callback, InstanceContext instanceContext);
}
  • GetExistingInstanceContext:当message有ChannelDispather交付到EndpointDispatcher的时候,该方法会被调用去试图获取一个已经存在的InstanceContext。比如:PerSession模式下,如果session已经开始,那个会返回绑定到当前session的InstanceContext,否则return null;对于Singleton模式,由于使用一个service instance来处理所有的request,所以一旦service instance被创建,后续的request都将返回同一个InstanceContext,否则return null;而对于PerCall来说,由于对于每个request来说,都需要创建一个新的service instance来处理,所以它永远是return null。
  • InitializeInstanceContext:如何GetExistingInstanceContext返回null,将通过这个方法来创建和初始化一个新的InstanceContext.
  • IsIdle:当所有的InstanceContext操作完成以后,该方法会被调用,返回的bool类型的结果将用作是否对InstanceContext进行清理和回收的依据。如何你不希望对创建的InstanceContext进行回收,那么你可以将此方法返回为false。比如:Singleton和PerSession模式下就直接return false;而PerCall则return true。
  • NotifyIdle:当对InstanceContext进行真正的清理和回收时,此方法会被回调。

和3种instancing mode相匹配, WCF定义了3种InstanceContextProvider:

  • System.ServiceModel.Dispatcher.PerCallInstanceContextProvider
  • System.ServiceModel.Dispatcher.PerSessionInstanceContextProvider
  • System.ServiceModel.Dispatcher.SingletonInstanceContextProvider

通过对InstanceContextProvider进行扩展,创建你自定义的InstanceContextProvider,你可以以你需要的方式关联request和service instance。比如:为了性能的提升,你可能试图通过一种对象池的机制实现对service instance的创建和提取,当需要使用到某个service instance的时候,先从对象池中获取该对象,如果不存在再从新创建对象。当service instance调用完毕,将其放入对象池中。这样避免了过于频繁的对象创建而引起对性能的影响。有兴趣的朋友不妨试着做一做。

注:当你自定义InstanceContextProvider的时候,一般继承base class:System.ServiceModel.Dispatcher.InstanceContextProviderBase而不是完全实现System.ServiceModel.Dispatcher.IInstanceContextProvider interface。

2 、自定义MessageFilter(Step 6)

通过对dispatching system的介绍,我们了解到:当ChannelDispather通过ChannelListener创建的Channel接收到request message之后,自己不会对message进行处理,而是遍历自己的EndpointDispatcher集合属性,找到与request message相匹配的EndpointDispatcher。到底怎样的匹配规则会被采用呢?

具体实现是这样的:每个EndpointDispatcher都定义了两个特殊的属性:AddressFilter和ContractFilter,它们的类型继承了abstract class:System.ServiceModel.Dispatcher.MessageFilter。

public abstract class MessageFilter
{
// Methods
protected MessageFilter();
protected internal virtual IMessageFilterTable<FilterData> CreateFilterTable<FilterData>();
public abstract bool Match(Message message);
public abstract bool Match(MessageBuffer buffer);
}

MessageFilter定义了两个Match重载,所以子类实现该重载实现自定义的匹配规则。在具体实现的时候,会解析request message或者MessageBuffer (message 的memory buffer表示)(一般是message header),来判断该request是否和对应的EndpointDispatcher相互匹配。

WCF为我们提供了一下6类Message Filter:

  • System.ServiceModel.Dispatcher.ActionMessageFilter:通过message Action header进行匹配。
  • System.ServiceModel.Dispatcher.MatchAllMessageFilter:匹配所有的message,也就是直接返回true。
  • System.ServiceModel.Dispatcher.EndpointAddressMessageFilter:根据message的To header 进行匹配。
  • System.ServiceModel.Dispatcher.MatchNoneMessageFilter:不会和任何的message匹配,也就是直接返回false。
  • System.ServiceModel.Dispatcher.PrefixEndpointAddressMessageFilter:和EndpointAddressMessageFilter相似,不过这次匹配的不是整个message的To header ,而是To header 的前缀。
  • System.ServiceModel.Dispatcher.XPathMessageFilter:给予Xpath expression的匹配方式。

那么EndpointDispatcher的ContractFilter和AddressFilter采

补充:综合编程 , 其他综合 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,