3

I have two WCF services in two separate DLL files. I want to host those in a single self-hosted project (console host).

I am trying to do this with following code, but I am getting this exception:

The type initializer for 'System.ServiceModel.Diagnostics.TraceUtility' threw an exception.

C# code:

public static void Main(string[] args)
{
    new Program().inital();
}

private void inital()
{
    ServiceHost myService = new ServiceHost(typeof(ClientNotificationService));
    ServiceHost myService2 = new ServiceHost(typeof(ServerNotificationService));

    try
    {
        myService.Open();
        myService2.Open();
        Console.ReadLine();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
        Console.ReadLine();
    }
}

In App.config:

<system.serviceModel>
<services>
  <service name="ClientNotification.ClientNotificationService">
    <endpoint address="net.tcp://localhost:7081/CVClientNotificationService"
      binding="netTcpBinding" contract="ClientNotification.IClientNotification">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8732/Design_Time_Addresses/ClientNotification/ClientNotificationService/" />
      </baseAddresses>
    </host>
  </service>
</services>
<services>
  <service name="ServerNotification.ServerNotificationService">
    <endpoint address="net.pipe://localhost/ServerNotificationService" binding="netNamedPipeBinding"
    contract="ServerNotification.IServerNotification">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8732/Design_Time_Addresses/ServerNotification/ServerNotificationService/" />
      </baseAddresses>
    </host>
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior>
      <serviceMetadata httpGetEnabled="True"/>
      <serviceDebug includeExceptionDetailInFaults="False" />
    </behavior>
  </serviceBehaviors>
</behaviors>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Hasanuzzaman
  • 1,822
  • 5
  • 36
  • 54
  • You can read the article *[Hosting multiple WCF Services under a single Windows Service ](http://blog.thijssen.ch/2009/08/hosting-multiple-wcf-services-under.html)*. It's very interesting and is based on ServiceManager. – Aghilas Yakoub Jul 29 '12 at 16:32

1 Answers1

0

The reason for this error

The type initializer for 'System.ServiceModel.Diagnostics.TraceUtility' threw an exception.

is triggered when the TraceUtility tries to initialize its Event Tracing in an internal method called SetEtwProviderId().

Inspection of the inner exception shows:

Configuration system failed to initialize

and its inner exception shows:

Sections must only appear once per config file.

So it is not your code but your config file that is wrong.

I can see where the confusion on this might start. When you add an Wcf Library project to the solution you'll find this in its app.config:

 <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
  <system.serviceModel>
    <services>
      <service name="WcfServiceLibrary2.Service1">
      <!-- rest omitted for brevity -->

So the instruction is to add that config to the app.config of your hosting applicaton, but is isn't very explicit about what exactly to copy.

You need to end-up with an app.config that is valid. You copied the <services> elements to the app.config of the application host. Now you have 2 <services> elements which is an invalid config section. Instead copy the child elements of <services> to the single <services> element in the app.config.

So to be clear:

<!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
  <system.serviceModel>
    <services>
      <!-- COPY FROM HERE ...  -->
      <service name="WcfServiceLibrary2.Service1">
        <host>
          <baseAddresses>
            <add baseAddress = "http://localhost:8733/Design_Time_Addresses/WcfServiceLibrary2/Service1/" />
          </baseAddresses>
        </host>
        <!-- Service Endpoints -->
        <!-- Unless fully qualified, address is relative to base address supplied above -->
        <endpoint address="" binding="basicHttpBinding" contract="WcfServiceLibrary2.IService1">
          <!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.
          -->
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <!-- Metadata Endpoints -->
        <!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. --> 
        <!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
      <!--
     .... TO HERE to the app.config of your application hosts config file
       -->
    </services> 

Assuming you already have a basic system.serviceModel config present.

If Visual Studio isn't complaining about your config file you can always start the WCF Service Configuration Editor (under the Tools menu in VS or in the context menu of the config file) to inspect the WCF config. If it is broken it will bark at you.

rene
  • 41,474
  • 78
  • 114
  • 152