Поделиться через


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.com

  • Anonymous
    January 09, 2008
    PingBack from http://sunali.com/2008/01/09/virtualpathprovider-in-precompiled-web-sites/

  • Anonymous
    June 28, 2008
    The comment has been removed

  • Anonymous
    May 29, 2009
    The comment has been removed

  • Anonymous
    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 basicHttpBinding

  • Anonymous
    August 05, 2014
    its working  ServiceHostBase.InitializeRuntime!!