Thursday, 5 February 2009

How to create WCF service manually

This article will show you how to create a WCF service by hand instead of the VS IDE. The reason of doing so is we can get rid of all the rubbish code created by VS and also it will help us understand more the infrastructure of WCF skills.

To build a WCF service manually we will create 5 assemblies:
1, Contract
2, Service
3, Host
4, ClientProxy
5, Client/WebClient

The Contract assembly (a class library) is the core of a particular WCF service. All the other 4 assemblies need a reference to this Contract.dll. The Contract assembly need a reference to System.ServiceModel so it can use all the related attributes: ServiceContract, OperationContract etc etc.

The Service assembly (a class library) includes the implementation of all the Contract Interfaces. You no need reference to System.ServiceModel for this assembly.

Now we are going to finish our first WCF service. To do so we need create a host. The Host assembly (a console app) will reference to Contract, Service, System.ServiceModel dlls and will need a Service configuration file. Below is a very sample config including two endpoints (using net.tcp and http proxy)
//Config file
<configuration>
  <system.serviceModel>
    <services>
      <service name="WcfTraining.Service.MyFirstService">
        <endpoint address="net.tcp://localhost:4002/MyFirstService"
                  binding="netTcpBinding"
                  contract="WcfTraining.Service.IHelloService"></endpoint>
        <endpoint address="http://localhost:9002/MyFirstService"
                          binding="wsHttpBinding"
                          contract="WcfTraining.Service.IHelloService"></endpoint>
      </service>
    </services>
  </system.serviceModel>
</configuration>


//Code behind
ServiceHost serviceHost = new ServiceHost(typeof(MyFirstService), 
        new Uri("net.tcp://localhost:9002/"));
serviceHost.Open();

Now you can run this Host app and a WCF service is online immediately. How easy it is. Warming: the <configSections> tag has to be always the first tag in the configure file.

Note: the second param of the ServiceHost method IMO is used to test if the Uri address is available. It could be any valid Uri address but if it is not exited in your endpoint list then it means nothing to client.

When the service is runing it is time to build our client. The first thing we need do is build a ClientProxy assembly which is a class library referenced the Contract and System.ServiceModel assemblies. Inside we simply implement the Contract Interface and inherit a generic class CProxy<Interface> which supply a ChannelFactory instance, which is used to communicate with the service. For example if we have a service named GetMessage and we are inheriting from System.ServiceModel’s inner Proxy ClientBase<> then the code will simply be:
    public class Proxy : ClientBase<IHelloService>, IHelloService
    {
        public string GetMessage(string name)
        {
            return Channel.GetMessage(name);
        }
    }

We are almost there now. The final is build our own client which could be a win app, console app or web app. The client need reference the ClientProxy, Contract and System.SerivceModel assemblies. And also the Client need a config file to tell where the service is runing. Please remembet there should be only one endpoint inside the client config file. Below is a client config sample.
  <system.serviceModel>
    <client>
      <endpoint address="net.tcp://localhost:4002/MyFirstService"
                binding="netTcpBinding"
                contract="WcfTraining.Service.IHelloService" />
    </client>
  </system.serviceModel>

Remember the abc in the config file: address, binding and Contract. Inside the Client class, simply create a instance of ClientProxy and directly call any service method you want. All Done.
Proxy proxy = new Proxy();
MessageBox.Show(proxy.GetMessage(textBox1.Text));

No comments: