Code Highlighter

Friday 11 October 2013

WCF - Inject the Unity Container into the per call self host service

WCF - Inject the Unity Container into the per call self host service

Sometime you don't want use a singleton for sharing the transient data between per call services.  Therefore you need to use the Unit Container to inject the dependencies to your service. Here is the sample of how to do it.


Main Code :
      UnityServiceHostFactory wFactory = new UnityServiceHostFactory();
 
      try
      {
        ServiceHost wIosServiceHost = wFactory.CreateServiceHostWithType(typeof(DataAccessService));
        wIosServiceHost.Open();
        Console.WriteLine("running on endpoints:");
        foreach (var wServiceEndpoint in wIosServiceHost.Description.Endpoints)
        {
          Console.WriteLine(wServiceEndpoint.Address.ToString());
          Console.WriteLine("running");
        }
      }
 
      catch (Exception ex)
      {
        ... 
     }

UnityServiceHostFactory :

  public class UnityServiceHostFactory : ServiceHostFactory
  {
    private static IUnityContainer mContainer;
    public UnityServiceHostFactory()
    {
// create you container and register all the types
   
      mContainer = new UnityContainer();
      mContainer.RegisterType<DataAccess>();
     ... 
    }
 
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
      return new UnityServiceHost(mContainer, serviceType, baseAddresses);
    }
 
    public ServiceHost CreateServiceHostWithType(Type serviceType, Uri[] baseAddresses)
    {
      return new UnityServiceHost(mContainer, serviceType, baseAddresses);
    }
 
    public ServiceHost CreateServiceHostWithType(Type serviceType)
    {
      return new UnityServiceHost(mContainer, serviceType);
    }
 }
 
UnityServiceHost :
 public partial class UnityServiceHost : ServiceHost
  {
    public UnityServiceHost(IUnityContainer container, Type serviceType, params Uri[] baseAddresses)
      : base(container.Resolve(serviceType), baseAddresses)
    {
    }
 
    public UnityServiceHost(IUnityContainer container, Type serviceType)
      : base(container.Resolve(serviceType))
    {
    }
  }
 
 

WCF – Configure the entire self host service via the app.config only

WCF – Configure the entire self host service via the app.config only

Most the self host samples that your find on the web,  it shows you how to configure the service programmatically.

App.config:

  - The metadata can be access via the http://localhost:8080/DataAccessService/Mex.
  - The service can be access via the net.tcp://localhost:8081/DataAccessService


  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <dataContractSerializer maxItemsInObjectGraph="2147483647" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      
      <netTcpBinding>
        <binding   name="IosService_netTcpBinding"  maxReceivedMessageSize="2147483647" receiveTimeout="23:10:00">
          <readerQuotas maxArrayLength="2147483647" maxBytesPerRead="2147483647" />
          <security mode="None" />
        </binding>
      </netTcpBinding>
      
      <wsHttpBinding>
        <binding name="IosService_wsHttpBinding"  maxReceivedMessageSize="2147483647" receiveTimeout="23:10:00">
          <readerQuotas maxArrayLength="2147483647" maxBytesPerRead="2147483647" />
          <security mode="None" />
        </binding>
      </wsHttpBinding>   
      
    </bindings>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    <services>
      <service name="com_cae.Miss.ProductAdapter.CdbAdapter.DataAccess.DataAccessService">
        <endpoint address ="" binding="netTcpBinding"  
                  bindingConfiguration="IosService_netTcpBinding" 
                  name="Endpoint"
                  listenUriMode="Explicit"
                  contract="com_cae.Miss.ProductAdapter.CdbAdapter.ClientServer.IDataAccessService" />
 
        <endpoint address="mex" binding="mexHttpBinding"  name="MexEndpoint" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <!-- For the metadata -->
            <add baseAddress="http://localhost:8080/DataAccessService/" />
            <!--- For service -->
            <add baseAddress="net.tcp://localhost:8081/DataAccessService/" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
Main Code :


      try
      {
        ServiceHost wIosServiceHost = wFactory.CreateServiceHostWithType(typeof(DataAccessService));
        wIosServiceHost.Open();
        Console.WriteLine("running on endpoints:");
        foreach (var wServiceEndpoint in wIosServiceHost.Description.Endpoints)
        {
          Console.WriteLine(wServiceEndpoint.Address.ToString());
          Console.WriteLine("running");
        }
      }
 
       catch (Exception ex)
       {
         ...
       }