WCF (Windows Communication Foundation) is a technology of Microsoft that is being used to implement and deploy Service Oriented Architecture (SOA). Services can be hosted to different location or on different machine and client can consume hosted services in the form of APIs. Services can be consumed by multiple clients.
WCF provides the following four common ways of Hosting:
- IIS Hosting
- WAS Hosting
- Windows Hosting
- Self-Hosting (Hosting in Application)
I will not explain the detailed features, hosting, advantages and disadvantages of WCF, but I will explain the way of Windows hosting and consuming step by step.
Step 1: Create WCF Service Application.
WCF Service Application provides to create Operation Contract, Service Contract, Data Contract, etc. Operation contract provides methods those are being exposed to client side.
The following are the steps to create WCF Service Application:
- Create one empty project by Visual Studio 2013.
- Now, right click on the solution explorer, Add New Project, WCF, then WCF Service. Application with Project name “Servies”.
- Add reference "System.ServiceModel".
- Add One Interface "ICalculator" and write the following code:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.ServiceModel;
- using System.Text;
- using System.Threading.Tasks;
-
- namespace Services
- {
- [ServiceContract]
- public interface ICalculator
- {
- [OperationContract]
- double Add(double n1, double n2);
- [OperationContract]
- double Subtract(double n1, double n2);
- [OperationContract]
- double Multiply(double n1, double n2);
- [OperationContract]
- double Divide(double n1, double n2);
- }
- }
- Now, create one class “CalculatorService”. It will implement the interface “ICalculator” like the following:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
-
- namespace Services
- {
- public class CalculatorService : ICalculator
- {
- public double Add(double number1, double number2)
- {
- double result = number1 + number2;
- return result;
- }
-
- public double Subtract(double number1, double number2)
- {
- double result = number1 - number2;
- return result;
- }
-
- public double Multiply(double number1, double number2)
- {
- double result = number1 * number2;
- return result;
- }
-
- public double Divide(double number1, double number2)
- {
- double result = number1 / number2;
- return result;
- }
- }
- }
- Rebuild the “Services” project to create dll.
Step 2: Create WCF Window Service Project.
I will explain the concept of WCF Windows hosting, so this project will contain the contract and endpoint details and it will be installed in the form of windows service.
The following are the steps to create and host WCF window service:
- Right click on the solution explorer of VS 2013, Add New Project, Windows Desktop, then Windows Service.
- Rename the project from “Service1” to “CalculatorWindowsService”.
- Add reference of “Services” project.
- Now, open CalculatorWindowsService class - Click to switch to code view, then CalculatorWindowsService.cs and a file will open. This file contains the name of service, creates service host, starts and stops the services.
- Write the following code in CalculatorWindowsService.cs:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.ServiceModel;
- using System.ServiceProcess;
- using System.Text;
- using System.Threading.Tasks;
-
- namespace CalculatorWindowsService
- {
- public class CalculatorWindowsService : ServiceBase
- {
- public ServiceHost serviceHost = null;
- public CalculatorWindowsService()
- {
-
- ServiceName = "WCFWindowsServiceSample";
- }
-
-
- protected override void OnStart(string[] args)
- {
- if (serviceHost != null)
- {
- serviceHost.Close();
- }
-
-
-
- serviceHost = new ServiceHost(typeof(Services.CalculatorService));
-
-
-
- serviceHost.Open();
- }
-
- protected override void OnStop()
- {
- if (serviceHost != null)
- {
- serviceHost.Close();
- serviceHost = null;
- }
- }
-
- }
- }
- Right click on the project “CalculatorWindowsService” - Add New Item, Installer Class and name it “ProjectInstaller.cs”.
Basically this class instantiates ServiceProcessInstaller and service account types like “Local System, Local Service, Network Service, User”, Assign the Account to LocalSystem.
ServiceInstaller is being instantiated for defining the name of service.
This class adds ServiceProcessInstaller and Service which contains all information.
Here's the code:
- [RunInstaller(true)]
- public partial class ProjectInstaller : System.Configuration.Install.Installer
- {
- private ServiceProcessInstaller process;
- private ServiceInstaller service;
- public ProjectInstaller()
- {
- InitializeComponent();
- process = new ServiceProcessInstaller();
- process.Account = ServiceAccount.LocalSystem;
- service = new ServiceInstaller();
- service.ServiceName = "WCFWindowsServiceSample";
- Installers.Add(process);
- Installers.Add(service);
- }
- }
- Now, open “Program” file to run the services. Write the following code:
- static class Program
- {
-
-
-
- public static void Main()
- {
- ServiceBase.Run(new CalculatorWindowsService());
- }
-
- }
- Right click on the App.config file - Edit WCF configuration, then a configuration window will open. Configure App.config file by defining service name, baseAddress, binding, contract, etc. like the following:
- <?xml version="1.0" encoding="utf-8" ?>
- <configuration>
- <system.serviceModel>
- <services>
- <!-- This section is optional with the new configuration model
- introduced in .NET Framework 4. -->
- <service name="Services.CalculatorService"
- behaviorConfiguration="CalculatorServiceBehavior">
- <host>
- <baseAddresses>
- <add baseAddress="http://localhost:8000/ServiceModelSamples/service"/>
- </baseAddresses>
- </host>
- <!-- this endpoint is exposed at the base address provided by host: http:
- <endpoint address=""
- binding="wsHttpBinding"
- contract="Services.ICalculator" />
- <!-- the mex endpoint is exposed at http:
- <endpoint address="mex"
- binding="mexHttpBinding"
- contract="IMetadataExchange" />
- </service>
- </services>
- <behaviors>
- <serviceBehaviors>
- <behavior name="CalculatorServiceBehavior">
- <serviceMetadata httpGetEnabled="true"/>
- <serviceDebug includeExceptionDetailInFaults="False"/>
- </behavior>
- </serviceBehaviors>
- </behaviors>
- </system.serviceModel>
- </configuration>
- Rebuild the project.
- Open VS 2013 Developer Command Prompt, Run as administrator and navigate the path till bin like the following:
cd /d F:\Tutorials\C#\Wcf_Test\CalculatorWindowsService\bin\Debug
- Now run the following command:
WCF_Test>installutil.exe CalculatorWindowsService.exe
It will install and host the WCF Windows Service. You can start it with the following steps:
- Search - Services.mst: There you will find “WCFWindowsServiceSample” as mentioned in the installer.
- Right click on it and Start the service.
Now, Window service has been installed and hosted.
Step 3: Consume WCF Service to Client Side.
Client can consume services of hosted windows services in the form of APIs.
The following are the steps to consume APIs:
- Right click on Solution explorer - Add New Console project.
- Give the name of console project to “CalculatorClient”.
- Now, generate proxy file of service by the following steps:
- Open URL http://localhost:8000/ServiceModelSamples/service in the browser. Make sure windows service should be running.
- It will open the service details.
- Click on the URL : http://localhost:8000/ServiceModelSamples/service?wsdl
- You will get .wsdl file in the form of XML format.
- Save this file
- Open VS 2013 Developer Command prompt.
- Navigate till the folder of saved XML file and run the following command:
F:\Tutorials\WCF_Test>svcutil.exe service.xml
- It will generate proxy file like “CalculatorService”. Add it to this project.
- Add reference “System.ServiceModel”.
- Add one App.Config file and configure like the following:
- <configuration>
- <system.serviceModel>
- <bindings>
- <basicHttpBinding>
- <binding name="BasicHttpBinding_ICustomerService" closeTimeout="00:01:00"
- openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
- allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
- maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
- messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
- useDefaultWebProxy="true">
- <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
- maxBytesPerRead="4096" maxNameTableCharCount="16384" />
- <security mode="None">
- <transport clientCredentialType="None" proxyCredentialType="None"
- realm="" />
- <message clientCredentialType="UserName" algorithmSuite="Default" />
- </security>
- </binding>
- </basicHttpBinding>
- </bindings>
- <client>
- <endpoint address="http://localhost:8000/ServiceModelSamples/service" binding="wsHttpBinding"
- contract="ICalculator"/>
- </client>
- </system.serviceModel>
- </configuration>
- Rebuild the project.
- Now go to Class file “Program” and call the service API’s method like the following:
- static void Main(string[] args)
- {
- CalculatorClient calculator = new CalculatorClient();
- var addResult = calculator.Add(2, 4);
- Console.WriteLine("Sum: {0}", addResult);
- var result = calculator.Subtract(4, 2);
- Console.WriteLine("Subtract: {0}", result);
- Console.ReadKey();
- }
Folder structure is like the following:
See the attached code.