1

I have got WCF service running as Windows service and I need to run a method of the WCF Service when Windows Service is starting. Is it possible in any way?

[ServiceContract]
public interface IWebMonitorServiceLibrary
{
    [OperationContract]
    void TestMethod();
}

[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class WebMonitorServiceLibrary : IWebMonitorServiceLibrary
{
    #region properties
    #endregion


    #region events
    #endregion


    public WebMonitorServiceLibrary()
    {
        Initialization();
    }

    private void Initialization()
    {
        /////////
    }


    public void TestMethod()
    {
        //////////
    }

}
petrppe
  • 145
  • 1
  • 14

2 Answers2

2

You don't explain why you want this initialization code to run, but given you almost never want to use a single-instance WCF service, the proper way would be to use dependency injection (see How do I pass values to the constructor on my wcf service?).

Create an object in which you store the things you want to initialize, which you initialize on your Windows Service start:

public class SomeSettingsYouWantToInitialize
{
    public string SomeSetting { get; set; }
}

public class WindowsServiceInstance : ServiceBase
{
    protected override void OnStart(string[] args)
    {
        InitializeWcfService();
    }

    private void InitializeWcfService()
    {
        var settings = new SomeSettingsYouWantToInitialize
        {
            SomeSetting = "Foo"
        };

        _yourDependencyContainer.Register<SomeSettingsYouWantToInitialize>(settings);       
    }
}

Then (using whatever dependency injection framework you use), inject that into your service's constructor:

public class WebMonitorServiceLibrary
{
    public WebMonitorServiceLibrary(SomeSettingsYouWantToInitialize settings)
    {
        // do stuff with settings
    }
}
Community
  • 1
  • 1
CodeCaster
  • 131,656
  • 19
  • 190
  • 236
1

Generally, no. This is because by default (and following best practice) you will have configured your service to run per-call (or per session), which means there can be multiple instances of your actual service running in your service host.

Therefore, any requirement for you to be able to return an instance of the service from the service host will involve some nasty plumbing code and is not advised.

Specifically, however, there are two approaches you could use to do what you want.

The first involves running your service in InstanceContextMode.Single - this means there will be a single service instance which will handle all requests. If you do this then you can simply create the service instance and then pass it into the servicehost when you start the windows service:

var service = new MyService();
var host = new ServiceHost(service);

You then have access to the service instance and can call the operation directly.

service.MyOperation("something");

The second thing you can do for when you don't want to run a singleton service you can make your service implementation just a wrapper around a static instance of a shared class that actually process the requests. As an example:

public class MyService : IMyService 
{ 
    private static IMyService instance = new MySharedServiceClass();

    public static IMyService Instance 
    { 
        get { return instance ; } 
    }

    public bool MyOperation(string something)
    {
       return instance.MyOperation(something);
    }
}

Then you can call the method on the class like this:

var host = new ServiceHost(typeof(MyService));
var instance = MyService.Instance;
instance.MyOperation("something");

I would still avoid doing this if at all possible. Think to yourself why do you even want this method called on startup? Surely it would be better to have this code directly in the windows service if it's something that needs to be run on startup?

tom redfern
  • 28,053
  • 12
  • 86
  • 116
  • Thanks, second option looks good, I have got exception "ServiceHost only supports class service types." though. – petrppe Mar 04 '15 at 13:16