I have been spending some time migrating some of my own projects from Windows Communication Foundation (WCF, previously - Indigo) B1 to the Sept-CTP (PDC-Bits) drop. These latest bits are pretty much what we are going to see in Beta 2, which will then closely resemble the release version of WCF when it RTMs.
From the looks of things in the blogsphere, there is not much activity that relates to the inner plumbings of Channels, Listeners and Factories in WCF B2, so I thought I drop some thoughts here.
While the higher levels of the System.ServiceModel Programming Model such as the ServiceHost has not changed much (if at all), there are a few changes take should be taken note of underneath the plumbings of ServiceHost.
This is nothing alarming though. Unless you are one of the few SOAP Plumbers in the world, it is unlikely you will feel any pinch. Morever, from the looks of things in the WCF Forums and newsgroups, I dont see that many people have actually grok into the inner depths of Windows Communication Foundation (WCF, previously - Indigo) B1 yet so this should be nothing but casual observation to most.
I am going to attempt to split this into a few parts that form a series of short snippets. I hope I have the time to see this through. 
Again, the context of this piece is to find out what lies beneath the ServiceHost. I will end right at the top with the ServiceHost.
Remember, it is the ultimate goal of the WCF team to give you all (or most) you will ever need at the ServiceHost ServiceModel level. There should be little use for you to muck around with the inner plumblings unless you want to write your own transport which Kenny Wolf has some great information on (since he is a Transport Developer Lead whi owns the TCP transport stack of WCF). While I am just digging around the SDK here, it would be highly recommended that most developers stick to the high level ServiceModel programming model. It is the easiest, fastest and the most abstract, which will shield you from the most pain as the WCF drops gravitate towards the final release. Pain, which I am sharing with you here. 
One thing that most plumbers will notice in Beta 2 as in contrast to Beta 1 is the disapperance of the concrete Listener Factories. Things like HttpListenerFactory and the SecurityListenerFactory are gone from the developers. This change is made so that there is no demux-ing at the transport-level anymore and that makes it much easier to write your own transport, which is a Good Thing™
Let us see some code. In Beta 1, if I wanted to set up just a single HTTP (transport) factory and open up a listening channel to it, I would do this on the service side:
Dim factory As New HttpListenerFactory
factory.SetUri(New Uri("http://localhost:8080/DemoIInputChannel"))
factory.MessageEncoderFactory = New TextMessageEncoderFactory
factory.Open()
Dim actFilter As New ActionFilter("urn:someAction")
'Listening for Channels
Dim listener As IListener(Of IInputChannel) = factory.CreateListener(Of IInputChannel)(actFilter, 0)
'Accepting Channels
Dim channel As IInputChannel = listener.AcceptChannel
channel.Open()
'Once the Channel opens, a message will pop right out
Dim m As Message = channel.Receive
DumpMessageOutToConsole(m)
'Clean-Up
m.Close()
channel.Close()
factory.Close()
If you had done some System.Net sockets programming before, this pattern should be very familiar to you. It is the
Winsock pattern, which validates the work done by
these people for the UNIX environment.
At the client side of things in B1:
Dim factory As New HttpChannelFactory
factory.MessageEncoderFactory = New TextMessageEncoderFactory
factory.Open()
Dim channel As IOutputChannel = factory.CreateChannel(Of IOutputChannel) _
("http://localhost:8080/DemoIInputChannel")
channel.Open()
'Defining the message
Dim content As New StringReader("<WilliamTay> is still </WilliamTay>")
Dim xreader As New XmlTextReader(content)
Dim m As Message = Message.CreateMessage("urn:someAction", xreader)
'Sending message on the Channel
channel.Send(m)
'Clean-Up
m.Close()
channel.Close()
factory.Close()
As mentioned above, the HttpListenerFactory is removed in B2. So, how would one do the same in B2. Say Hello to the the IChannelListener and the BuildChannelListener. All things should start from System.ServiceModel.Binding now. In other words,
On the service side: Binding <-> Listener Factories <-> Channel.Receive()
On the client side: Binding <-> Channel Factories <-> Channel.Send()
I could go on and on about this but I will spare the reader and not do it here. As Steve had said: IChannelListener is the wave of the future. 
This does give some form of consistency to the programming model on both client and service sides as there are no XXXListenerFactory and XXXChannelFactory to deal with anymore.
Let us see how things have progressed in B2: On the service side, to do the same - Code is now changed to look like this:
Dim transBinding As New HttpTransportBindingElement
Dim custBinding As New CustomBinding
custBinding.Elements.Add(transBinding)
Dim bPCollection As New BindingParameterCollection
Dim uri As New Uri("http://localhost:8080/DemoIInputChannel")
'Say Hello to IChannelListener and BuildChannelListener
Dim iChannelList As IChannelListener(Of IInputChannel) = _
custBinding.BuildChannelListener(Of IInputChannel)(bPCollection)
'Open the Channel Listener
iChannelList.SetUri(uri)
iChannelList.Open()
'Open Input Channel
Dim iInputChann As IInputChannel = iChannelList.AcceptChannel
iInputChann.Open()
'Once the Channel receives, a message will pop right out
Dim msg As Message = iInputChann.Receive
DumpMessageOutToConsole(msg)
'Clean-Up
msg.Close()
iInputChann.Close()
iChannelList.Close()
On the client side in B2:
Dim transBinding As New HttpTransportBindingElement
Dim custBinding As New CustomBinding
custBinding.Elements.Add(transBinding)
Dim bPCollection As New BindingParameterCollection
Dim uri As New Uri("http://localhost:8080/DemoIInputChannel")
'Open the Channel Factory
Dim iChannelFact As IChannelFactory(Of IOutputChannel) = _
custBinding.BuildChannelFactory(Of IOutputChannel)(bPCollection)
iChannelFact.Open()
'Create and open the Output Channel
Dim iOutputChann As IOutputChannel = iChannelFact.CreateChannel(Of IOutputChannel)(uri)
iOutputChann.Open()
'Defining the message
Dim content As New StringReader("<WilliamTay> is still </WilliamTay>")
Dim xreader As New XmlTextReader(content)
Dim msg As Message = Message.CreateMessage("urn:someAction", xreader)
'Sending message on the Channel
iOutputChann.Send(msg)
'Clean-Up
msg.Close()
iOutputChann.Close()
iChannelFact.Close()
As you can see from the differences that I have documented, the starting point from defining elements is a constant now on both service and client ends. Then, it is on to create the Listener/Channel factories, hook up the respective AcceptChannel()/CreateChannel() then finally accomodate the message dispatching process with channel Receive()/Send()
There you go. Pretty straight-forward. There is a functionality difference in the B1 code above that is not in my B2-CTP code. Can you spot it?
I will document that in Part II of this series in the coming days or weeks.
Enjoy.