4

I am trying to host two services using a single console app. However, when I am trying to do so, only one service gets hosted, while the other does not.

Program.cs:

namespace WWWCFHost
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(WWWCF.Login)))
            {
                host.Open();
                Console.WriteLine("Service1 Started");
            }
            using (ServiceHost host1 = new ServiceHost(typeof(WWWCF.UserRegistration)))
            {
                host1.Open();
                Console.WriteLine("Service2 Started");
                Console.ReadLine();
            }
        }
    }
}

App.config

<configuration>
  <system.serviceModel>

    <services>
      <service name="WWWCF.Login" behaviorConfiguration="WWWCF.mexBehaviour1">
        <endpoint address="Login" binding="basicHttpBinding" contract="WWWCF.ILogin">
        </endpoint>

        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange">
        </endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8080"/>
          </baseAddresses>
        </host>
      </service>

      <service name="WWWCF.UserRegistration" behaviorConfiguration="WWWCF.mexBehaviour2">
        <endpoint address="UserRegistration" binding="basicHttpBinding" contract="WWWCF.IUserRegistration">
        </endpoint>

        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange">
        </endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8090"/>
          </baseAddresses>
        </host>
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="WWWCF.mexBehaviour1">
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
        <behavior name="WWWCF.mexBehaviour2">
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

  </system.serviceModel>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
</configuration>

As in the code above, I am trying to host one service on port 8080 and the other on port 8090. When I run the application, the first service starts and then closed automatically and the second service remains started. How can I host both the services simultaneously ?

I have gone through the link : Two WCF services, hosted in one console application

I have gone through other threads as well.But they do not solve my issue.

Will be happy to provide any further details if required.

Community
  • 1
  • 1
AnkitMittal
  • 166
  • 2
  • 18

2 Answers2

5

You're instantly closing the first, since it's in the using. You need to set it up so the first using scope doesn't end until after the ReadLine() call.

Try:

using (ServiceHost host = new ServiceHost(typeof(WWWCF.Login)))
{
     host.Open();
     Console.WriteLine("Service1 Started");

     using (ServiceHost host1 = new ServiceHost(typeof(WWWCF.UserRegistration)))
     {
            host1.Open();
            Console.WriteLine("Service2 Started");
            Console.ReadLine();
     }
}
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • This solves my issue. Thanks. But I was wondering what would I do if I had a lot more than 2 services(say 100) to host. Nesting **using** inside another will increase nesting levels to 100s. The solution mentioned by @simonlchilds will be better off in such a case. – AnkitMittal Apr 09 '14 at 21:12
  • @AnkitMittal That solution is identical to this one - the only difference is syntax used (I didn't do it his way, as it changes the behavior in the case of exceptions - this, and yours, doesn't instantiate the second service if the first throws on open). – Reed Copsey Apr 09 '14 at 21:15
  • If you have 100's of services, you can just keep a collection of the references to each service, then after `Console.ReadLine()` loop through and `Dispose()` of them all. – Cam Bruce Apr 09 '14 at 21:16
  • 3
    @CamBruce That being said, if you have *hundreds* of self hosted services, I'd rethink your overall design, and really question why they're in the same console app... – Reed Copsey Apr 09 '14 at 21:17
  • In live scenario, I wouldn't be using a Console app though. @Cam - Yes. Disposing must be taken care of. I will do that. – AnkitMittal Apr 09 '14 at 21:23
  • 1
    @ReedCopsey regarding exception handling... I agree with you, maybe a better solution would be to avoid using `using` blocks and ensure the `Dispose()` was called on all non null host instances inside a `finally` block. That being said, this whole design is a bit funky! – Simon Apr 09 '14 at 21:24
5

Your first service jumps out of the using block and so is disposing too early. Try this...

using (ServiceHost host = new ServiceHost(typeof(WWWCF.Login)))
using (ServiceHost host1 = new ServiceHost(typeof(WWWCF.UserRegistration)))
{
     host.Open();
     Console.WriteLine("Service1 Started");

     host1.Open();
     Console.WriteLine("Service2 Started");
     Console.ReadLine();
 }

Take a look at this: http://msdn.microsoft.com/en-us//library/yh598w02.aspx

Simon
  • 2,810
  • 2
  • 18
  • 23
  • This solves my issue. With this solution I can host as many services as I want easily. Thanks so much. – AnkitMittal Apr 09 '14 at 21:14
  • You could, but be aware of memory consumption. Glad I could help :) – Simon Apr 09 '14 at 21:17
  • 1
    Keep in mind, if you are hosting "100s of services" via this console app, they are all on one thread, and will block each other. – Cam Bruce Apr 09 '14 at 21:18
  • @CamBruce Also true. This would be a bitch to debug! – Simon Apr 09 '14 at 21:25
  • I will not have 100s of services. That was just a what-if scenario.:) Still, if I did have 100s of services, would you have any particular approach to suggest? – AnkitMittal Apr 09 '14 at 21:26
  • Oh. Is there no better way to handle the situation? Even using IIS hosting? Coz console app will not be used in live scenario. – AnkitMittal Apr 09 '14 at 21:46