In my last post I had discussed about what is happening in the channels at the service end and how they are related to the ServiceHost class that we normally use.In this post we will take a look at what is happening at the client side channels.In the server side we have channel listeners listening for incoming requests similarly at the client end we have channel factories to create the channels as the client initiates the connection.For sake of simplicity we will not consider the duplex channels for now.In short we need to the following to send messages to the service from client:
- Create a binding
- Create a ChannelFactory.
- Create a Channel
- Send/Receive messages over that channel.
Now let us take a closer look into the class ChannelFactory.The class definition : public class ChannelFactory<TChannel> : ChannelFactory, IChannelFactory<TChannel>, IChannelFactory, ICommunicationObject where TChannel is either IOutputChannel or IRequestChannel type.
- Create a ChannelFactory by it’s constructor .At this point State of the factory is Created.
- We need to Open the ChannelFactory via it’s Open() method.At this point State of the factory is Opened.
- Create a channel by calling ChannelFactory.CreateChannel() method.At this point State of the channel is Created.CreateChannel will return an instance of type IRequestChannel.
- Open the channel by calling IRequestChannel.Open() method.At this point State of the channel is Opened.
- Invoke IRequestChannel.Request() method to send the message to the desired endpoint and receive the reply back.
- Close the channel and the channel factory respectively after use.
But we do not do all this when we generate a proxy using svcutil or .NET IDE “Add Service Reference” menu option.So these tools provides us with a higher level abstraction with the above mentioned steps taken care under the hood.
If you take a look at the class generated in the Reference.cs file in the ServiceReference folder you will find that the custom proxy class inherits a class ClientBase<TChannel> : ICommunicationObject, IDisposable where TChannel : class.This class encapsulates the functionality of channel factory and channels.This class exposes the ChannelFactory and Channel via ChannelFactory and InnerChannel properties.Prior to invoking the Service methods we need to open the proxy via it’s Open() method.
This is the sequence in which ClientBase,ChannelFactory and InnerChannel works:
- When the proxy is instantiated via the ClientBase constructor the ChannelFactory is in “Created” state.
- When the Open method of the proxy or ClientBase is called then the ChannelFactory is “Opened”.
- After that the ClientBase/Proxy state is transitioned to “Opened”.
- Then the InnerChannel is “Opened”.
- Similarly when Close() method of the proxy is invoked then things happen in reverse order i.e. InnerChannel is closed,then Proxy/ClientBase finally followed by ChannelFactory.