38

I'm not sure if its possible, but I'd like to have a function run as soon as a WCF service is started to generate initial cache data. I'm not worried now about how to implement the cache, my question is strictly about having the function run when the service starts. The service will be RESTful.

The service will eventually be hosted in IIS and is using .Net Framework 4.5

SmashCode
  • 4,227
  • 8
  • 38
  • 56

3 Answers3

36

The easiest way is to create an App_Code folder underneath your WCF project root, create a class (I'll call it Initializer but it doesn't matter. The important part is the method name) like so:

public class Initializer
{
    public static void AppInitialize()
    {
        // This will get called on startup
    } 
}

More information about AppInitialize can be found here.

Community
  • 1
  • 1
Kirk Woll
  • 76,112
  • 22
  • 180
  • 195
  • That might be exactly what I'm looking for. Does it matter if the service is hosted in IIS? – SmashCode May 31 '12 at 21:55
  • 5
    Yes, in fact it requires IIS. – Kirk Woll May 31 '12 at 22:00
  • 2
    I found this to be a poor option. The module containing the 'AppInitialize' is not compiled with the project, but provided as 'content' and compiled dynamically when the service is loaded. As a result, many of the libraries required to properly implement IOC are not available (e.g. System.Reflection). While I agree with the need for a single initialization method, this solution is VERY limited by the fact that it's dynamically compiled. – Quark Soup Apr 26 '16 at 16:05
  • 1
    @DRAirey1, you can call any class in your assembly from `AppInitialize`, so I don't understand what you're getting at. – Kirk Woll Apr 26 '16 at 16:06
  • I'm getting at the fact that the AppInitialized is compiled on-the-fly. If IIS doesn't have the external library around, you get an 'Unable to load module' exception. I tried to feed several assemblies into a MEF container construction and IIS wasn't able to find 'System.Reflection'. I'm sure I could spend several hours constructing an application pool that had every assembly I needed ahead of time, but there's just too much room to screw up with this solution. The 'ServiceHostFactory' answer insures that all the assemblies you need are compiled into the code. – Quark Soup Apr 26 '16 at 20:51
  • For me, it works when running code in Visual Studio but not within IIS.... – Piero Alberto Mar 31 '20 at 08:27
  • I know this is old, but wanted to comment in case anyone had an answer, this works, until you want to use it to set a variable, to be accessed later from a service (like a configuration of some kind), there's no way I can find to access it, it's all in a different context. – Dan Chase Dec 15 '20 at 15:25
33

What @KirkWoll suggested works, but only if you're in IIS and that's the only AppInitialize static method under App_Code. If you want to do initialization on a per-service basis, if you have a different AppInitialize method or if you're not under IIS, you have these other options:

An example of a custom factory is shown below:

public class MyFactory : ServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        ServiceHost host = base.CreateServiceHost(serviceType, baseAddresses);
        host.Opening += new EventHandler(host_Opening);
        return host;
    }

    void host_Opening(object sender, EventArgs e)
    {
        // do initialization here
    }
}

}

carlosfigueira
  • 85,035
  • 14
  • 131
  • 171
  • 1
    For what it's worth, none of those options worked for me -- I had to use `AppInitialize` because I was taking over handling of `.svc` files to be auto-generated. But that aside, nice thorough answer. – Kirk Woll May 31 '12 at 22:02
  • 1
    And I experienced one strange side-effect using the IIS/4.5 'service configuration method': inside of "Configure" i had to add the line below, because it no longer read my web.config file settings and everything went haywire: `config.LoadFromConfiguration ()` – tntwyckoff Jan 13 '16 at 01:24
  • @user240374 Very helpful info! Reading the MSDN page that was linked in the main answer, it appears that point of the IIS/4.5 'service configuration method' is to allow you to configure the service in code, rather than from the web.config file. So I guess it makes sense that if you have one of these Configure methods, IIS will ignore the web.config unless you explicitly tell it to go read it. – bmode Jun 23 '16 at 14:52
  • I find this to be a huge drawback: `When defined, any service configuration settings specified in an app.config or web.config file will be ignored.` I want to execute some code at startup, but not disable file based configuration. – xr280xr May 14 '18 at 21:27
1

In my case I did like below. I have Windows service project that hosted a WCF Rest service. I wrote below code in my windows service project MyService.cs

protected override void OnStart(string[] args)
{
    try
      {
        ServiceHost myServiceHost = new ServiceHost(typeof(myservice));
        myServiceHost.Opening += OnServiceHostOpening;
        myServiceHost.Open();
      }
      catch (Exception ex)
      {
         //handle exception
      }
}

private void OnServiceHostOpening(object sender, EventArgs e)
{
   //do something
}
Ziggler
  • 3,361
  • 3
  • 43
  • 61
  • In case anyone wants a link for this, https://learn.microsoft.com/en-us/archive/msdn-magazine/2007/september/iis-7-0-extend-your-wcf-services-beyond-http-with-was states that "The WCF ServiceHost type features two events called Opening and Closing. They are the only proper ways to execute code at service startup and shutdown." – Dan Chase Dec 15 '20 at 15:39