59

What is the best way to get notified when a WCF service is first started?

Is there something similar to the Application_Start method in the Global.asax for an ASP.NET application?

user89166
  • 815
  • 2
  • 9
  • 10
  • 1
    A answer by Job Vermeulen blow links a working solution and gives you options. It can be done. Also a related question that provides a working solution can be found here - http://stackoverflow.com/questions/2453353/what-is-the-global-asax-application-start-equivalent-when-using-was-in-iis7 – Taras Alenin May 02 '12 at 23:57

7 Answers7

87

Since it's just a class, you can use a static constructor which will be called the first time the Type is used.

public Service : IContract
{
    public Service(){ // regular constructor }
    static Service(){ // Only called first time it's used. }
}
Paul Alexander
  • 31,970
  • 14
  • 96
  • 151
  • 1
    I was hoping for something more host-specific, i.e. something in the application that's hosting the service. – user89166 Apr 11 '09 at 01:01
  • 7
    paul answer worked for me. Static constructor is the savior!! – CodeNinja Feb 11 '11 at 10:09
  • 7
    Perfect. And today I learned about `static` constructors for the first time. – eouw0o83hf Mar 20 '12 at 20:07
  • Yet another option would be using a custom service host factory and put a static constructor there. This will work both for multiple services and IoC containers which are using custom factories. Say if you are using `Autofac.Integration.Wcf` that will do the trick: `public class MyHostFactory : AutofacServiceHostFactory { static MyHostFactory() { /* init code goes here */ } }` – Anton Krouglov Jun 21 '17 at 15:11
9

You can always manually add global.asax files to your WCF Service Application as it hosted on IIS and integrates with ASP.NET pipeline:

<%@ Application Codebehind="Global.asax.cs" Inherits="WcfApplication" Language="C#" %>

public class WcfApplication : HttpApplication
{
    protected void Application_Start()
    {
    }
}
Boris Lipschitz
  • 9,236
  • 5
  • 53
  • 63
9

Well, that might be a bit tricky since the preferred way of calling WCF services is on a "per-call" basis, e.g. you don't really have anything that's "started" and then just hangs around, really.

If you're hosting your service in IIS or WAS, it's even "on-demand loading" of your service host - when a message arrives, the host is instantiated and handles the request.

If you self-host, you either have a console or Winforms app - so you could hook into there to know when they start. If you have a Windows service to host your service host, you most likely override the OnStart and OnStop methods on the ServiceBase class --> hook into there.

The question is more: what exactly are you trying to accomplish? Just logging or something like that, or do you want to have something built up in memory to stick around??

Marc

Matthew Murdoch
  • 30,874
  • 30
  • 96
  • 127
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 88
    (-1) I really don't understand how this "answer" helps anyone. You basically asked him back and didn't answered his question. – Eran Betzalel Oct 16 '09 at 05:02
  • 11
    I tried to explain that there's nothing exactly like Application_Start in WCF, but tried to provide ideas where he could hook into to detect what he needs to detect.... sorry you feel that way - I tried my best, but feel free to provide a better answer! – marc_s Oct 16 '09 at 07:40
  • 4
    Paul Alexander supplied a better answer that actually helped me a lot. – Eran Betzalel Oct 16 '09 at 10:16
  • 3
    This answers the question - there is no start event for the application, they're on demand. Presumbly there must be a way of tying into the AppDomain.AssemblyLoaded but at that point it's too late – Chris S Aug 25 '10 at 10:43
  • I guess Application_Start might be appropriate if you wanted to do something that was specific to HTTP binding such as initialising SimpleMembership so that the web service can then use roles/membership functions internally. – Monstieur Feb 13 '13 at 12:01
  • @Locutus: a WCF service doesn't have to have an `Application_Start` event - it can be hosted absolutely independent of ASP.NET and thus won't have access to HttpContext or the Globals.asax file..... – marc_s Mar 10 '14 at 12:26
  • @marc_s I have a WCF application fully hosted on WCF. And as a warm up activity I do not want to just log, But I want to instantiate a few classes in the w3wp process which can be used by client when request comes. Can you please help me out in that – Bhagirath N Sai Dec 19 '14 at 10:33
  • @marc_s I have hosted WCF on IIS, here I would like to register my WCF service as an subscriber of RabbitMQ, like micro services. So i would like to wherever my wcf service started it should register itself to the RabbitMQ so it can process the message as they arrived in the queue. I am facing the issue that my wcf service did not get registered as subscriber until it not receive any request. I tried using Owin startup and adding global.asax, both are not working, any idea? – Ashish Shukla Feb 12 '19 at 07:20
5

If you have a Self-Hosted WCF Service, you can add an Event to the Opening of the service, and inside this Event you can assign a static variable, just like this post:

//Static Variables in a WCF Service
public class Post2331848
{
    [ServiceContract]
    public interface ITest
    {
        [OperationContract]    
        string GetString();
    }    

    public class Service : ITest
    {
        public static string TheString; 
        public string GetString()
        {
            return TheString;
        }
    }

    static void host_Opening(object sender, EventArgs e)
    {
        Service.TheString = "This is the original string";
    } 

    public static void Test() 
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service"; 
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress)); 
        ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), ""); 

        //This is the magic line!
        host.Opening += new EventHandler(host_Opening);

        host.Open();

        Console.WriteLine("Host opened"); 
        Console.ReadLine();
        host.Close();
    }
}

(Originaly from http://www.eggheadcafe.com/community/aspnet/18/10162637/help-in-maintain-global-variable-in-wcf.aspx)

Good Luck!

Gustavo G.
  • 79
  • 1
  • 7
2
Imports System.ServiceModel
Imports System.ServiceModel.Description

Public Class MyServiceHost
   Inherits Attribute
    Implements IServiceBehavior

    Public Sub AddBindingParameters(serviceDescription As System.ServiceModel.Description.ServiceDescription, serviceHostBase As System.ServiceModel.ServiceHostBase, endpoints As System.Collections.ObjectModel.Collection(Of System.ServiceModel.Description.ServiceEndpoint), bindingParameters As System.ServiceModel.Channels.BindingParameterCollection) Implements System.ServiceModel.Description.IServiceBehavior.AddBindingParameters

    End Sub

    Public Sub ApplyDispatchBehavior(serviceDescription As System.ServiceModel.Description.ServiceDescription, serviceHostBase As System.ServiceModel.ServiceHostBase) Implements System.ServiceModel.Description.IServiceBehavior.ApplyDispatchBehavior
        AddHandler serviceHostBase.Opened, AddressOf serviceHostBase_Opened
        AddHandler serviceHostBase.Closed, AddressOf serviceHostBase_Closed
    End Sub

    Public Sub Validate(serviceDescription As System.ServiceModel.Description.ServiceDescription, serviceHostBase As System.ServiceModel.ServiceHostBase) Implements System.ServiceModel.Description.IServiceBehavior.Validate

    End Sub




#Region "Event Handlers"


    Private Sub serviceHostBase_Opened(ByVal sender As Object, ByVal e As EventArgs)



    End Sub

    Private Sub serviceHostBase_Closed(ByVal sender As Object, ByVal e As EventArgs)



    End Sub


#End Region
wakurth
  • 1,644
  • 1
  • 23
  • 39
0

The standard ServiceHost API for hosting services in Windows Communication Foundation (WCF) is an extensibility point in the WCF architecture. Users can derive their own host classes from ServiceHost, usually to override OnOpening to use ServiceDescription to add default endpoints imperatively or modify behaviors, prior to opening the service.

http://msdn.microsoft.com/en-us/library/aa702697%28v=vs.110%29.aspx

NidhiSree
  • 65
  • 1
  • 7
0

There is a nuget package called WebActivator that I found useful for IIS hosting.

https://www.nuget.org/packages/WebActivatorEx/

You add some assembly attributes to your WCF project.

[assembly: WebActivatorEx.PreApplicationStartMethod
(
    typeof(MyActivator),
    "Start")
]

public static class MyActivator
{
    public static void Start()
    {
        // do stuff here
    }
}
Craig Celeste
  • 12,207
  • 10
  • 42
  • 49