How to Initialize Hosted WCF Services
There are different mechanisms to perform custom initialization for hosted WCF services in an ASP.NET application. ASP.NET provides ways to perform general initialization at application-level. For each WCF ServiceHost, we can also register and handle events such as Openning / Openned / Faulted to achieve service-level initialization. The sample code for this blog can be found at the sample link.
Using global.asax
The global.asax file is also known as the ASP.NET “HTTP” application file. It is an optional file and if there is one, it needs to be in the root of an ASP.NET application. It contains code to handle application-level events raised by ASP.NET or HttpModules. It is tightly coupled with the ASP.NET HTTP pipeline.
Most common events that are handled in global.asax are Application_Start, Application_Init, and Application_BeginRequest, etc. Here is a simple example global.asax:
<%@ Application="" Language="C#" Debug="true" %>
<script runat="server">
void Application_Start(object sender, EventArgs e)
{
System.Diagnostics.EventLog.WriteEntry("ASP.NET 2.0.50727.0",
"Test Application_Start", EventLogEntryType.Information);
}
</script>
In this example, the method Application_Start is called when the application is first started. To be more precisely, it is called when the HttpApplication type is instantiated. This happens when the first HTTP request comes into the application. Under the hook, the ASP.NET system compiles global.asax into a derived type of System.Web.HttpApplication and the corresponding global methods are mapped to the events exposed from HttpApplication.
Using AppInitialize
The above global.asax does not work for non-HTTP protocols such as net.tcp and net.pipe that is supported by the Windows Activation Service (WAS) on Windows Vista. There is no protocol-agnostic counterpart for HttpApplication in this case.
Fortunately, ASP.NET provides a simple hook that works in a protocol agnostic way. The hook is based on the following AppInitialize method:
public static void AppInitialize();
This method can be put in any type that is defined in a C# file in the application’s \App_Code directory. When the AppDomain is started, ASP.NET checks whether there is a type that has such as method (exact name and signature) and invokes it. Note that the AppInitialize method can be only defined once and it has to be in a code file instead of a pre-compiled assembly.
WCF ServiceHost Events
The type ServiceHostBase is a special CommunicationObject and thus it also exposes a list of state transitioning events such as “Opening”, “Opened”, “Closing”, “Closed”, and “Faulted”. It also exposes the event “UnknownMessageReceived”.
In self-hosted case, it is easy to understand how to hook up with these events in the application. For web hosted case, the ServiceHost is created internally by the WCF WebHost layer. However, there are still two ways to achieve this. One way is to use a custom ServiceHostFactory. Another way will be described in the next section.
The interface IServiceHostFactory is provided to support custom ServiceHost activation. In order to hook up the events for ServiceHost, we can implement this interface and put the type as the “Factory” attribute in the .svc file as following:
<%@ServiceHost Language="C#" Factory="HelloWorld.HelloServiceHostFactory" %>
Then in the CreateServiceHost method, we can do all of the interesting things as we can do in self-hosted case:
public ServiceHostBase CreateServiceHost(string service, Uri[] baseAddresses)
{
// The service parameter is ignored here because we know our service.
ServiceHost serviceHost = new ServiceHost(typeof(HelloService),
baseAddresses);
serviceHost.Opening += new EventHandler(serviceHost_Opening);
serviceHost.Opened += new EventHandler(serviceHost_Opened);
serviceHost.Closing += new EventHandler(serviceHost_Closing);
serviceHost.Closed += new EventHandler(serviceHost_Closed);
serviceHost.Faulted += new EventHandler(serviceHost_Faulted);
serviceHost.UnknownMessageReceived += new EventHandler<UnknownMessageReceivedEventArgs>(serviceHost_UnknownMessageReceived);
return serviceHost;
}
Using ServiceHostBase.InitializeRuntime
Besides the initialization logic with IServiceHostFactory as above, you can also perform service initialization by providing your own custom ServiceHost type. By deriving from ServiceHost type, you can implement the protected method ServiceHostBase.InitializeRuntime as following:
protected override void InitializeRuntime()
{
VirtualPathExtension extension = this.Extensions.Find<VirtualPathExtension>();
EventLog.WriteEntry("ASP.NET 2.0.50727.0",
"Service virtual path: " + extension.VirtualPath,
EventLogEntryType.Information);
base.InitializeRuntime();
}
Comments
Anonymous
September 29, 2006
hi
I am Pratap Gaikwad , Sir I am working on wcf services for the past 2 months and I have integrated these services into our project. I am facing the proble , How to use the global.asax file in wcf services. Our flow of data is like this
UI -- Business layer -- Service Layer -- DataBase.
In service layer we have implemented WWF and WCF.
WWF is using web services and global object is declared in global.asax file. We have to remove this web services and implement wcf services. Here the problem occurs this object declared in global.asax file is not recognised. We have declared wcf services as class library project. Can you suggest me how to over come this barrier.
You can send me the suggestion to my mail ID pratap.gaikwad@tcs.comAnonymous
January 09, 2008
PingBack from http://sunali.com/2008/01/09/virtualpathprovider-in-precompiled-web-sites/Anonymous
June 28, 2008
The comment has been removedAnonymous
May 29, 2009
The comment has been removedAnonymous
January 20, 2010
I am hosting wcf service in windows service and have event handlers for faulted event. How can I generate a fault for which control goes to faulted event handler. I tried doing infinite loop in one of the service opertaions, but it crashed the windows service, but control did not go to faulted _state. Any ideas on how can i test the faulted_state event handler. Closing and Closed event handlers are wrking properly.Anonymous
April 01, 2012
i am trying to find out at which time is a particular wcf service running and at what time is a service stopped...can any one provide the inputs..?Anonymous
March 19, 2014
Hi, I am using a Timer in a Initialize WCF. I want to dispose Timer variable at End() WCF, how to reach it ?Anonymous
July 22, 2014
ServiceHost.OnOpening() event is not getting fired when using basicHttpBindingAnonymous
August 05, 2014
its working ServiceHostBase.InitializeRuntime!!