Question

I am trying to get a better understanding of some of the inner workings of WCF. I have done a fair amount of looking around, but I have not been able to find a clear explanation of what ChannelFactory.Open() does compared to IClientChannel.Open(). What is the purpose of opening the factory? If the channel is being used for communication, what part does the factory play in the process after the channel has been created and opened?

The question was asked here, among other questions, but never answered directly.

EDIT:

After de-compiling the source code, I found some of the specific reasons why Open needs to be called on ChannelFactory, which is documented below.

What I'm still having trouble understanding is why this work is being done through mechanisms provided by the ICommunicationObject, when the factory isn't actually communicating with anything (as far as I know). Why not just handle these things when the object is constructed or disposed of?

I think I'm probably far enough in the weeds that such an answer may not be publicly available. Thank you to those who weighed in on the original question.

Was it helpful?

Solution 2

After de-compiling a bunch of the related classes in System.ServiceModel, I was able to get a little more information.

The Open call appears to make its way down the inheritance tree to the CommunicationObject, where its Open method is called. All this seems to do is provide a bunch of diagnostic information and raise a number of events.

The ChannelFactory class uses the Open events do a number of things, including creating its inner channel factory:

protected override void OnOpening()
{
    base.OnOpening();
    this.innerFactory = this.CreateFactory();
    if (this.innerFactory == null)
    {
        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString("InnerChannelFactoryWasNotSet")));
    }
}

As has been mentioned by others here, the Close events are also used to do things like close all of the underlying channels, (by way of it's internal channel factory):

protected override void OnClose(TimeSpan timeout)
{
    TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
    while (true)
    {
        IChannel channel;
        lock (base.ThisLock)
        {
            if (this.channelsList.Count == 0)
            {
                break;
            }
            channel = this.channelsList[0];
        }
        channel.Close(timeoutHelper.RemainingTime());
    }
}

OTHER TIPS

Open needs to be called in the factory, since it's an ICommunicationObject - before you use one of those, it needs to be opened. But in most cases the factory is opened automatically for you when you call things such as CreateChannel, for example, so you seldom need to worry about explicitly opening the factory.

Regarding Close, it really depends on which binding the factory is using. In most cases you're correct, the resource is mostly associated with the channel. But it's possible that a certain binding would multiplex multiple channels in the same underlying connection, so closing the channel would simply remove the channel from the list to be multiplexed. Only when the factory is closed is that the underlying connection is actually released.

Opening ChannelFactory or the innerchannel just change the state of the object, when is instantiated is starts in the Created state, the object can be configured but it is not usable to send or receive message, in the Opened state, the communicationObject is usable but it is no longer configurable

So the purpose of opening the factory is just a design choice and it is indeed done automatically when you create the first channel, it does not to much under the hood, the factory is responsible to create the channel that will actually bring messages from the transport layer and send them to you application.

Channel factories are responsible for creating channels. Channels created by channel factories are used for sending messages. These channels are responsible for getting the message from the layer above, performing whatever processing is necessary, then sending the message to the layer below. The following graphic illustrates this process

http://msdn.microsoft.com/en-us/library/ms789050.aspx

Hope this helps

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top