WCF开发工具是一个建立于.Net Framework 2.0基础上的一个功能强大的开发插件,那么如何才能正确的应用这一插件来帮助我们在实际开发中获得帮助呢?这首先就需要我们来熟练掌握一些应用技巧,比如今天为大家介绍的WCF服务寄宿的相关内容。
在默认的情况下,基于IIS的服务寄宿是通过一个特殊的HttpModule实现的,其类型为System.ServiceModel.Activation.HttpModule,是一个定义在System.ServiceModel程序集中的内部类型。HttpModule的定义大体上如下面的代码所示,我们很清楚地看到其实现的原理:将实现WCF Service请求处理的逻辑注册到HttpApplication的PostAuthenticationRequest事件中。
- internal class HttpModule : IHttpModule
- {
- //其他成员
- public void Init(HttpApplication context)
- {
- context.PostAuthenticateRequest += new EventHandler
(HttpModule.ProcessRequest);- }
- private static void ProcessRequest
(object sender, EventArgs e)- {
- //服务请求处理实现
- }
- }
System.ServiceModel.Activation.HttpModule是一个特殊的HttpModule,说它特别是因为当HttpModule注册到HttpApplication的PostAuthenticateRequest事件处理程序执行后,不会再将请求进一步分发给后续的请求处理步骤。换句话说,就HttpApplication从BeginRequest到EndRequest整个请求处理的生命周期来说,对于基于.svc文件的请求仅仅延续到PostAuthenticateRequest阶段。我们可以通过一种简单的方式来证明这一点。
假设我们有一个WCF服务寄宿需要通过IIS进行寄宿,并把WCF服务相应的.svc文件定义在一个对应于某个IIS虚拟目录的ASP.NET Website中。现在我们为之添加一个global.asax,在该global.asax,我通过如下的代码注册了HttpApplication处理请求的前三个事件:BeginRequest、AuthenticateRequest和PostAuthenticateRequest,当这3个事件触发后,将一段代表当前事件的名称写入EventLog中。
- <%@ Application Language="C#" %>
- <%@ Import Namespace= "System.Diagnostics"%>
- <script runat="server">
- void Application_BeginRequest(object sender, EventArgs e)
- {
- string message = string.Format("BeginRequest Event is
raised at {0}", DateTime.Now);- EventLog.WriteEntry("Application", message,
EventLogEntryType.Information);- }
- void Application_AuthenticateRequest(object sender, EventArgs e)
- {
- string message = string.Format("AuthenticateRequst Event
is raised at {0}",DateTime.Now);- EventLog.WriteEntry("Application", message,
EventLogEntryType.Information);- }
- void Application_PostAuthenticateRequest(object sender, EventArgs e)
- {
- string message = string.Format("PostAuthenticateRequest
Event is raised at {0}", DateTime.Now);- EventLog.WriteEntry("Application", message,
EventLogEntryType.Information);- }
- </script>
如果我们上面的说法成立的话,只有HttpApplication的最初3个事件被触发。此外,HttpModule注册的操作会先于定义在global.asax的Application_PostAuthenticateRequest方法执行,那么在整个服务调用过程中,只有Application_BeginRequest和Application_AuthenticateRequest这两个方法会被执行。这一点我们可以从EventLog得到证实。当我们通过执行案例7-2中的代表客户端应用程序后,EventLog中WindowsLog的Application分组中,会多出两个日志项目(之前已经将日志清空)。#t#
日志的内容正是我们在Application_BeginRequest和Application_AuthenticateRequest方法中定义的日志文本。可见仅仅这两个方法被成功执行,Application_PostAuthenticateRequest方法却没有被执行。可以想象,后续的事件也不可能被触发。
到现在为止,我们仅仅是介绍了如何处理基于.svc文件的请求,并没有说明.svc文件对应的WCF Service是如何被寄宿的。WCF服务寄宿发生在对服务.svc文件的***次访问,具体的实现很简单:ServiceMode根据请求的目的地址加载相应的.svc文件,通过解析定义在<%ServiceHost%>指令的Factory和Service属性得到ServiceHostFactory和Service的类型(Factory默认为System.ServiceMode.ServiceHostFactory),通过反射创建继承自基类System.ServiceModel.Activation.ServiceHostFactoryBase的ServiceHostFactory对象。***通过ServiceHostFactory创建的继承自基类System.ServiceModel.ServiceHostBase的ServieHost对象对Serivce进行WCF服务寄宿。