Introduction
WCF is a programming platform for building a network-distributed system. It is unified programming model which combines features of Web Service, Remoting, MSMQ and COM+. As a .NET developer, you just need to know the APIs that WCF provided, but if you know more about the implementation details, it will help you use WCF efficiently and build a more reliable system.
Background
In the last article, I introduced how to implement a simple WCF service host in process - Create a Self-Hosted WCF Service. Let's use this sample and dig into the WCF inside.
1 - ServiceHost
ServiceHost
is the most important class to host our service after we defined the configuration and the provisions of the behaviors and characteristics which the service have. The main work of ServiceHost class is to load the service, configure endpoint, apply security setting and turn on/off a channel to listen to the incoming message.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
using System.ServiceModel.Description;
namespace SelfHostedTest
{
class Program
{
static void Main(string[] args)
{
string address = "http://localhost:8090/SelfHostService/EchoSerivce";
Uri httpUrl = new Uri(address);
ServiceHost host = new ServiceHost(typeof(SelfHostService.EchoSerivce), httpUrl);
BasicHttpBinding binding = new BasicHttpBinding();
host.AddServiceEndpoint(typeof(SelfHostService.IEchoSerivce), new BasicHttpBinding(), address);
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
host.Description.Behaviors.Add(smb);
host.Open();
Console.WriteLine("Service is host at " + address);
Console.WriteLine("Host is running... Press <Enter> key to stop");
Console.ReadLine();
}
}
}
1.1 - Create ServiceDescription
No matter what kind of hosting (IIS, WAS, WS..) you used in your project, it all implements through ServiceHost
. ServiceHost
inherits the ServiceHostBase
class. According to the service we configured, ServiceHost
creates a ServiceDescription
object to describe the service, and copy it to its father ServiceHostBase
's behavior Description
.
public abstract class ServiceHostBase : ...
{
ServiceDescription description;
}
CreateDescription
methods are made to create ServiceDescription
. There are several tasks:
- Add Service Behavior that is applied when we defined the service.
[ServiceContract(CallbackContract = typeof(IPushCallback))] public interface IDuplexService {
[OperationContract(isOneWay = true)]
void SendMessage(string data)
}
- Initialize
ServiceDescription.Name
, ServiceDescription.Namespace
, ServiceDescription.ConfigurationName
- Add
ServiceBehavior
we defined in the config file (ServiceElement
) - Add
ServiceEndpointElement
according to the endpoint we defined
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior> ... </behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="HelloworldService">
<endpoint .../>
</service>
</services>
</system.serviceModel>
ServiceDescription
is created when we initialize a ServiceHost
object. We can call ServiceHost.AddServiceEndpoint
methods to add endpoints to Description
's endpoint collection.
1.2 - Validate the ServiceDescription is Valid
- Service behavior
- Endpoint behavior
- Contract behavior
- Operation behavior
1.3 - Group of Endpoints According to ListenUri and ListenUriMode
ListenUri
is a physical address, different endpoint could share the same listenUri
, listenUriMode
is ensured that the listen uri is unique, it will add a GUID to distinguish the address.
<service name="helloworldService">
<endpoint address="http://127.0.0.1:7777/HelloWorldService"
binding="basicHttpBinding"
contract="SelfHostService.IHelloWorldService"
listenUri="http://127.0.0.1:6666/HelloWorldService"
listenUriMode="Explicit">
</endpoint>
<endpoint address="http://127.0.0.1:8888/HelloWorldService"
binding="basicHttpBinding"
contract="SelfHostService.IHelloWorldService"
listenUri="http://127.0.0.1:6666/HelloWorldService"
listenUriMode="Explicit">
</endpoint>
<endpoint address="http://127.0.0.1:9999/HelloWorldService"
binding="basicHttpBinding"
contract="SlefHostService.IHelloWorldService"
listenUri="http://127.0.0.1:6666/HelloWorldService"
listenUriMode="Unique">
</endpoint>
</service>
Group 1: Endpoint 1
address : http:
listenUri : http:
listenUriMode : Explicit
Endpoint 2
address : http:
listenUri : http:
listenUriMode : Explicit
Group 2: Endpoint 3
address : http:
listenUri : http:
listenUriMode : Unique
After group of endpoints, WCF will create a BindingParameterCollection
object for each group and use this object to create a very important object --- BindingContext
.
ChannelDispather
and EndpointDispather
are the most important components in WCF Server Side. Each group above has a ChannelDispatcher
, each endpoint in the group has an EndpointDispatcher
. WCF will build a ChannelListener
for each listening address based on BindingContext
to listen to the incoming message. We will talk about the Channel Layer
in the next article. Find out how WCF listens to an incoming message and how to encode the message through the wire.
Besides, ServiceHost
also has an important task to apply the security setting, We will gather the security things to an independent series.