In web service, we can host the service only in IIS, but WCF provides
the user to host the service in any application (e.g. console
application, Windows form etc.). Very interestingly developer is
responsible for providing and managing the life cycle of the host
process. Service can also be in-pro i.e. client and service in the same
process. Now let's us create the WCF service which is hosted in Console
application. We will also look in to creating proxy using
'ClientBase' abstract class.
Note:
Host process must be running before the client calls the service, which typically means you have to prelaunch it.
Step 1:
First let's start create the Service contract and it implementation.
Create a console application and name it as MyCalculatorService. This is
simple service which return addition of two numbers.
Step 2:
Add the System.ServiceModel reference to the project.
Step 3:
Create an ISimpleCalculator interface, Add ServiceContract and
OperationContract attribute to the class and function as shown below.
You will know more information about these contracts in later session.
These contracts will expose method to outside world for using this
service.
IMyCalculatorService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace MyCalculatorService
{
[ServiceContract()]
public interface ISimpleCalculator
{
[OperationContract()]
int Add(int num1, int num2);
}
}
Step 4:
MyCalculatorService is the implementation class for IMyCalculatorService interface as shown below.
MyCalculatorService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyCalculatorService
{
class SimpleCalculator : ISimpleCalculator
{
public int Add(int num1, int num2)
{
return num1 + num2;
}
}
}
Step 5:
Now we are ready with service. Let's go for implementing the hosting
process. Create a new console application and name it as
'MyCalculatorServiceHost'
Step 6:
ServiceHost is the core class use to host the WCF service. It
will accept implemented contract class and base address as contractor
parameter. You can register multiple base addresses separated by commas,
but address should not use same transport schema.
Uri httpUrl = new Uri("http://localhost:8090/MyService/SimpleCalculator");
Uri tcpUrl = new Uri("net.tcp://localhost:8090/MyService/SimpleCalculator");
ServiceHost host
= new ServiceHost(typeof(MyCalculatorService.SimpleCalculator), httpUrl, tcpUrl);
Multiple end points can be added to the Service using
AddServiceEndpoint() method.
Host.Open() will run the service, so that it can be used by any client.
Step 7:
Below code show the implementation of the host process.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
namespace MyCalculatorServiceHost
{
class Program
{
static void Main(string[] args)
{
//Create a URI to serve as the base address
Uri httpUrl = new Uri("http://localhost:8090/MyService/SimpleCalculator");
//Create ServiceHost
ServiceHost host
= new ServiceHost(typeof(MyCalculatorService.SimpleCalculator), httpUrl);
//Add a service endpoint
host.AddServiceEndpoint(typeof(MyCalculatorService.ISimpleCalculator)
, new WSHttpBinding(), "");
//Enable metadata exchange
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
host.Description.Behaviors.Add(smb);
//Start the Service
host.Open();
Console.WriteLine("Service is host at " + DateTime.Now.ToString());
Console.WriteLine("Host is running... Press <Enter> key to stop");
Console.ReadLine();
}
}
}
Step 8:
Service is hosted, now we need to implement the proxy class for the client. There are different ways of creating the proxy
- Using SvcUtil.exe, we can create the proxy class and configuration file with end points.
- Adding Service reference to the client application.
- Implementing ClientBase<T> class
Of these three methods, Implementing ClientBase<T> is the best
practice. If you are using rest two method, we need to create proxy
class every time when we make changes in Service implementation. But
this is not the case for ClientBase<T>. It will create the proxy
only at runtime and so it will take care of everything.
MyCalculatorServiceProxy.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using MyCalculatorService;
namespace MyCalculatorServiceProxy
{
public class MyCalculatorServiceProxy :
//WCF create proxy for ISimpleCalculator using ClientBase
ClientBase<ISimpleCalculator>,
ISimpleCalculator
{
public int Add(int num1, int num2)
{
//Call base to do funtion
return base.Channel.Add(num1, num2);
}
}
}
Step 9:
In the client side, we can create the instance for the proxy class and call the method as shown below.
Add proxy assembly as reference to the project.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace MyCalculatorServiceClient
{
class Program
{
static void Main(string[] args)
{
MyCalculatorServiceProxy.MyCalculatorServiceProxy proxy ;
proxy= new MyCalculatorServiceProxy.MyCalculatorServiceProxy();
Console.WriteLine("Client is running at " + DateTime.Now.ToString());
Console.WriteLine("Sum of two numbers... 5+5 ="+proxy.Add(5,5));
Console.ReadLine();
}
}
}
Step 10 :
End point (same as service) information should be added to the configuration file of the client application.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client>
<endpoint address ="http://localhost:8090/MyService/SimpleCalculator"
binding ="wsHttpBinding"
contract ="MyCalculatorService.ISimpleCalculator">
</endpoint>
</client>
</system.serviceModel>
</configuration>
Step 11:
Before running the client application, you need to run the service. Output of the client application is shown below.
This self host shows advantage such as in-Pro hosting, programmatic
access and it can be used when there need singleton service. I hope you
have enjoyed the Self hosting session, now let go for hosting using
Windows Activation service.