Search code examples
c#wcfc#-4.0castle-windsorwcffacility

Castle WCF Facility | Windows Service Hosting


I’m trying to use Castle WCF integration facility in my WCF project, but got lost in the way. Can you please help me out?

So, here is the situation:

I have a WCF Service Library, which is hosted inside a Windows Service over TCP. Following is what is in my WCF Service Library: Service Impl:

[ServiceContract]
    public interface ICalculatorService
    {
        [OperationContract]
        int Add(int x, int y);
    }

    public class CalculatorService : ICalculatorService
    {
        public int Add(int x, int y)
        {
            return x + y;
        }
    }

Configuration:

 <system.serviceModel>
    <services>
      <service name="namespace.CalculatorService">
        <endpoint address="" binding="netTcpBinding" bindingConfiguration=""
          contract="namespace.iCalculatorService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
          contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8732/CalculatorService/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="false" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

Container Configuration This is inside WCF project were I register everything to castle (I'm not sure where the wcf facility should be registered, whether it should be registered from the WCF service or from the Windows service which hosts the WCF service).

 public class ConfigureContainerCastle
    {
        private readonly IWindsorContainer container;

        public ConfigureContainerCastle(IWindsorContainer container)
        {
            this.container = container;
        }

        public void Configure()
        {
            // Any component registration.
            container.Register(Component.For<ICalculatorService>().ImplementedBy<CalculatorService>());
            //All other component registration.
        }
    }

Following is what is in my Windows Service:

 public class Host<T>:ServiceBase
    {
     private ServiceHost serviceHost = null;
            protected override void OnStart(string[] args)
            {
                if (serviceHost != null)
                {
                    serviceHost.Close();
                }

                // How do I call the DefaultServiceHostFactory and start the service?
                // Should I call the WCF facility from here or from WCF service library?
//                var container = new WindsorContainer();
  //              var configureContainer = new DataServicesConfigureContainer(container);
    //            var hostFactory = new DefaultServiceHostFactory(container.Kernel);

                serviceHost = new ServiceHost(typeof (T));
                serviceHost.Open();
            }

            protected override void OnStop()
            {
                if (serviceHost == null)
                    return;

                serviceHost.Close();
                serviceHost = null;
            }
    }

And my configuration(app.config) for Windows Service is same as my WCF service, literally line by line.

Now the question is, how do I wire this all together with WCF facility? I have seen lot of examples using http and global.asax, but none for windows services. Can you please help? Even an appropriate link to it will be helpful.

Thanks, -Mike


Solution

  • First of all a small point - if you are wanting TCP you need to specify the base address using the net.tcp protocol like so:

    <add baseAddress="net.tcp://localhost:8732/CalculatorService" />
    

    But that isn't your question, so crushing on...

    (I'm not sure where the wcf facility should be registered, whether it should be registered from the WCF service or from the Windows service which hosts the WCF service).

    I would suggest you register the facility somewhere close to where you register the service. So, in the WCF Service Library - in fact the bit of code you posted would be a fine place to register it (as long as it is registered I do not think it makes much difference where).

    Now the question is, how do I wire this all together with WCF facility? I have seen lot of examples using http and global.asax, but none for windows services. Can you please help? Even an appropriate link to it will be helpful.

    Pretty simply actually - if you want to keep your configuration in your config file you can just change your Configure method like this (I'm assuming you already have a reference to Castle.Facilities.WcfIntegration):

    public void Configure()
    {
        container.AddFacility<WcfFacility>();
    
        // Any component registration.
        container.Register(Component
            .For<ICalculatorService>()
            .ImplementedBy<CalculatorService>()
            .AsWcfService());
    
        //All other component registration.
    }
    

    And that is it - Windsor is now in charge of serving up the service when a WCF client connects to it (don't believe me - add some dependencies into your CalculatorService and marvel at the wonder).

    You may want to consider doing away with the config file altogether now and use the Windsor fluent API instead - it is pretty intuitive just have a look at what you can pass into the AsWcfService method and away you go (or just stick with the config file).