Alright; so I was working on a new project and I wanted to create a Windows Service that would host a WCF Service. The basic idea is that the Windows Service will use the WCF Service to do it’s heavy lifting on a schedule. The WCF Service will also be called from a management web site later on. In the past I’ve always wanted to reduce the amount of coding and configuration required to call one of these services.
So.. what did i come up with? The following lines create the service host in my Windows Service:
_wcfAsnService = new ServiceHost(typeof(Edi.Wcf.AsnService));
_wcfAsnService.AddServiceEndpoint(typeof(IAsnService), new NetTcpBinding(), Settings.Default.WcfAsnServer);
_wcfAsnService.Open();
The setting for that last parameter is defined as: net.tcp://localhost:8000
And I created this class to use for managing the life cycle of the client proxy:
using System;
using System.ServiceModel;
namespace EDI.AsnService
{
public class ServiceProxy : IDisposable
{
private readonly T _endPoint;
private readonly ICommunicationObject _proxy;
public ServiceProxy(string endPointAddress)
{
// Create a service client proxy
_endPoint = ChannelFactory.CreateChannel(new NetTcpBinding(), new EndpointAddress(endPointAddress));
// Create a CommunicationObject for state and end point closure
_proxy = _endPoint as ICommunicationObject;
}
public void Dispose()
{
// Close down the communication channel
if (_proxy != null)
_proxy.Close();
}
///
/// Returns the state object from the communication end point
///
public CommunicationState State
{
get { return _proxy.State; }
}
///
/// Returns the Endpoint where methods can be called
///
public T Client { get { return _endPoint; } }
}
}
Pretty simple. All you have to do is pass in the contract as the type and the proxy is created on the fly. Inside my method that executes the service client I have the following code to invoke the service:
using (ServiceProxy service = new ServiceProxy(Settings.Default.WcfAsnServer))
{
eventLog.WriteEntry(“Processing Start”);
eventLog.WriteEntry(service.Client.ExtractFromVisual().Message);
eventLog.WriteEntry(service.Client.UpdateGentran().Message);
eventLog.WriteEntry(“Processing Completed”);
}
The end result is that I don’t have to worry about configuring bindings in the config file. In fact the only thing I have in the config file in the endpoint address and port. I think this is much lighter weight and reduces some of the problems I’ve run into in the past with updating service references and duplication of the bindings in the config file.