Share via


Acting on Open

How do I run a custom event once when the service is first started?

The easiest way to execute some custom code when a service is started is to hook the service's Open method. Although the Open method has two different moments in time that you might be interested in, I'll just say Open to refer to them both. Opening is the moment in time just before the service is started; Opened is the moment in time just after. There a few different ways of hooking Open depending on what objects you have available.

If you have access to a ServiceHost instance before Open is called, then you can hook Open by attaching an event handler to either the Opening or Opened events. This is the least invasive approach.

If you're the one that's actually responsible for creating the ServiceHost instance, then you can also build your custom event directly into the host. You do this by overriding either the OnOpened or OnOpening methods. In either case, be sure to call the base method at some point. This is a more invasive approach because you have to make a subclass but you have finer control over the timing of the custom event relative to other code.

If you don't control the ServiceHost, then you're probably running inside a hosted environment that uses ServiceHostFactory. Similar to subclassing ServiceHost, you can subclass ServiceHostFactory to install your custom event. Typically you would create an instance of a ServiceHost subclass from the ServiceHostFactory rather than putting the custom event logic in the ServiceHostFactory itself.

Here's an example program showing the ServiceHost subclass approach.

 using System;
using System.ServiceModel;
using System.ServiceModel.Channels;

public class MyServiceHost : ServiceHost
{
   public MyServiceHost(Type serviceType, params Uri[] baseAddresses)
      : base(serviceType, baseAddresses)
   {
   }

   protected override void OnOpened()
   {
      base.OnOpened();
      Console.WriteLine("On opened");
   }

   protected override void OnOpening()
   {
      base.OnOpening();
      Console.WriteLine("On opening");
   }
}

[ServiceContract]
public interface IMyService
{
   [OperationContract]
   string Echo(string s);
}

public class MyService : IMyService
{
   public string Echo(string s)
   {
      return s;
   }
}

class Program
{
   static void Main(string[] args)
   {
      string address = "localhost:8000/";
      Binding binding = new BasicHttpBinding();

      ServiceHost host = new MyServiceHost(typeof(MyService), new Uri(address));
      host.AddServiceEndpoint(typeof(IMyService), binding, "");
      host.Open();

      ChannelFactory<IMyService> proxyFactory = new ChannelFactory<IMyService>(binding);
      IMyService proxy = proxyFactory.CreateChannel(new EndpointAddress(address));
      Console.WriteLine(proxy.Echo("Test completed"));
      proxyFactory.Close();

      Console.ReadLine();
      host.Close();
   }
}

Next time: Serializing XML to XML