<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>/bill's House O Insomnia&lt;img src="http://www.williamgryan.com/images/originalcuckoo.jpg" alt="Bill Ryan" /&gt; : ChannelFactory</title><link>http://msmvps.com/blogs/williamryan/archive/tags/ChannelFactory/default.aspx</link><description>Tags: ChannelFactory</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>WCF to the rescue</title><link>http://msmvps.com/blogs/williamryan/archive/2008/07/07/wcf-to-the-rescue.aspx</link><pubDate>Mon, 07 Jul 2008 23:41:23 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1639700</guid><dc:creator>William</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/williamryan/rsscomments.aspx?PostID=1639700</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/williamryan/commentapi.aspx?PostID=1639700</wfw:comment><comments>http://msmvps.com/blogs/williamryan/archive/2008/07/07/wcf-to-the-rescue.aspx#comments</comments><description>&lt;p&gt;Although part of the idea below was mine, James Ashley was crucial to helping me figure this out.&lt;/p&gt; &lt;p&gt;Problem:&lt;/p&gt; &lt;p&gt;Without getting into the ghoury details, we have an application that allows users to send messages to large groups of people.&amp;nbsp; Anyone using a client application that is logged on will get a special notification which they can respond to once a message is sent. So far, Polling has been the bane of our existence.&amp;nbsp; We&amp;#39;re trying to fancy up the UI and Telerik&amp;#39;s Winforms controls have helped out a lot, but there&amp;#39;s simply no way I&amp;#39;ve been able to find to have a snappy UI with a lot of really cool looking effects - all the while polling every few seconds.&amp;nbsp; Until now, I just bit down, and took a walk through multi-threadedville.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I wanted to remove the polling.&amp;nbsp; We had experimented with a few different architectures, but all had the same problem, polling.&amp;nbsp; So let&amp;#39;s say you had 200 users logged on.&amp;nbsp; In the User&amp;#39;s bar, we wanted to show each user and their picture - much the same way IM does.&amp;nbsp; This app had to work across network boundaries and you couldn&amp;#39;t count on being able to use TCP so we had to at least make it work with http.&amp;nbsp; If you poll every three seconds, to get the latest info on who&amp;#39;s logged on and off, rebuilding the list of user&amp;#39;s was painful. We resorted to several tricks to determine if a user was already in the list, but all of it was putting lipstick on a pig.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Solution:&lt;/p&gt; &lt;p&gt;One of the big things you often hear about with WCF is self-hosting.&amp;nbsp; I had ignored it for the most part.&amp;nbsp; But today, I wanted to basically have a Winforms app host one service, and a Windows Service host the other part of the service, having the services talk to each other. The client winforms app would simply talk to the client service, it would never hit the Windows Service directly.&lt;/p&gt; &lt;p&gt;So we built a client service and server service, with a client winforms app hosting the client service and a mock Windows Service (which was simply another winforms app) that hosted the service.&lt;/p&gt; &lt;p&gt;The problem we kept running into is as each client signed on to the system, how could we tell the server svc that they were online?&amp;nbsp; Dynamically adding endpoints is child&amp;#39;s play, but with each winforms app, you could only interact with the ServiceHost - not the service.&lt;/p&gt; &lt;p&gt;We tried using traditional events to no avail - that wasn&amp;#39;t a surprise but we figured it&amp;#39;s worth a try.&amp;nbsp; Then James recommended a static event. I was completely skeptical, but alas it worked.&amp;nbsp; &lt;/p&gt; &lt;p&gt;After looking at Juval&amp;#39;s framework though, it became really clear. If we want the services to be able to interact with the hosts, then simply self-host the things.&lt;/p&gt; &lt;p&gt;So we had a method called ReceiveMessage which was called from the service (via a client proxy for the client service).&amp;nbsp; Here&amp;#39;s basically what the client looked like:&lt;/p&gt; &lt;p&gt;public partial class Form1 : Form, IClientService&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Form1()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; InitializeComponent();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ServiceHost currentHost = null;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private void btnStartService_Click(object sender, EventArgs e)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; currentHost = new ServiceHost(typeof(Form1));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; currentHost.Open();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lblServiceStatus.Text = &amp;quot;Started&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch (Exception ex)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lblServiceStatus.Text = ex.Message;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string ReceiveMessage(string msg)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String myMessage = msg;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageBox.Show(myMessage);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return msg;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;p&gt;.... &lt;p&gt;&amp;nbsp; &lt;p&gt;Now, from the Administrative application (which interacted with the service, you could Send a message by doing the following:) &lt;p&gt;private void btnSend_Click(object sender, EventArgs e)&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; proxy = new ClientServiceClient(new NetNamedPipeBinding(), endpoint );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; proxy.ReceiveMessage(rtbMessageText.Text);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch (FaultException ex)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lblServiceStatus.Text = ex.Message;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; } &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;ClientServiceClient is a stupid name for a client proxy class, but we were just experimenting - the main thing to note is that it&amp;#39;s simply a proxy class for the client service, the same service that&amp;#39;s effectively being hosted by the Winforms client.&amp;nbsp; There&amp;#39;s a server method called SendMessage(String msg) which you&amp;#39;d call on the service, which in turn would dynamically add endpoints for each active client , and then send the messages to them.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;You can easily store all the information for clients you want to send messages to in a List&amp;lt;&amp;gt; or similar structure - or if you need stronger persistence or have different needs, then you can use a database.&amp;nbsp; Either way the end result is the same - loop through all the clients, add an endpoint for each one, loop through each and call the method you want.&lt;/p&gt; &lt;p&gt;I&amp;#39;m having trouble getting to my ftp server from where i&amp;#39;m at, but I&amp;#39;ll post the code when I can. In the meantime, if you&amp;#39;re interested, just drop me a line.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1639700" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/williamryan/archive/tags/Misc+Technology/default.aspx">Misc Technology</category><category domain="http://msmvps.com/blogs/williamryan/archive/tags/WCF/default.aspx">WCF</category><category domain="http://msmvps.com/blogs/williamryan/archive/tags/WIndows+Communication+Foundation/default.aspx">WIndows Communication Foundation</category><category domain="http://msmvps.com/blogs/williamryan/archive/tags/.NET+3.5+Framework/default.aspx">.NET 3.5 Framework</category><category domain="http://msmvps.com/blogs/williamryan/archive/tags/ChannelFactory/default.aspx">ChannelFactory</category></item><item><title>ChannelFactory.CreateChannel goes to the Gentlemen's Club</title><link>http://msmvps.com/blogs/williamryan/archive/2008/05/12/channelfactory-createchannel-goes-to-the-gentlemen-s-club.aspx</link><pubDate>Mon, 12 May 2008 22:07:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1621334</guid><dc:creator>William</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/williamryan/rsscomments.aspx?PostID=1621334</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/williamryan/commentapi.aspx?PostID=1621334</wfw:comment><comments>http://msmvps.com/blogs/williamryan/archive/2008/05/12/channelfactory-createchannel-goes-to-the-gentlemen-s-club.aspx#comments</comments><description>&lt;p&gt;Currently, I&amp;#39;m tasked with getting some people up to speed on .NET 3.5 as well as WCF.&amp;nbsp; WCF is really cool and it&amp;#39;s easy to fall in love with, but it&amp;#39;s also easy to cause you to sleep when you&amp;#39;re first learning it. So instead of walking through Hello World, I changed course.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Basically, we&amp;#39;re using an architecture where the Business Layer and Data Layer are services. In most cases, we&amp;#39;d run them on the same machine, in Proc. In other cases, when scalability is more of an issue, we&amp;#39;d need to separate them out.&lt;/p&gt;
&lt;p&gt;Creating Services is nothing special and other than a few attributes (ServiceContract, OperationContract, often DataContract and/or DataMember or EnumMember) and an interface, there&amp;#39;s no real way to tell a wcf service from any other class (and since most of those attributes should&amp;nbsp;go on the interface, the class itself shows no sign of being a service other than the interface implementation).&amp;nbsp; One thing though, when you add a WCF service to an application through VS, it will stick the service class and the corresponding interface into the same project.&amp;nbsp; I typically move my interfaces out of the project and into a library so that I can share them.&amp;nbsp; In a case where your business methods just call the dal&amp;#39;s methods, the interfaces/contracts will be the same so you may be able to share them.&lt;/p&gt;
&lt;p&gt;WCF gives you similar hosting options to Remoting and Web Services.&amp;nbsp; You can add a Service Reference and have svcutil.exe generate a proxy class which is virtually identical to what you did with web services. Hosting them is the easy part and if you can run a Console application and remember to put Console.Readline at the end of it, you can start a service host.&amp;nbsp; There&amp;#39;s about a zillion examples out there and it&amp;#39;s usually one of the first things covered in WCF so I&amp;#39;m leaving that alone for now.&lt;/p&gt;
&lt;p&gt;On the client, you can add a service reference as I said. However that is not without its problems and you may want a little more flexibility. If you want to create your own proxies, there are two primary methods (outside of svcutil related approaches). Let&amp;#39;s say you have the following interface:&lt;/p&gt;&lt;code&gt;
&lt;p&gt;&lt;font color="#0000ff"&gt;namespace&lt;/font&gt; Cuckooz.Sample.WCFStripClub&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; [&lt;font color="#008080"&gt;DataContract&lt;/font&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;public&lt;/font&gt; &lt;font color="#0000ff"&gt;enum&lt;/font&gt; BounceLevel{&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;font color="#008080"&gt;EnumMember&lt;/font&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Lame,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;font color="#008080"&gt;EnumMember&lt;/font&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Woot,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;font color="#008080"&gt;EnumMember&lt;/font&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; YeahBaby&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;font color="#008080"&gt;DataContract&lt;/font&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;public enum&lt;/font&gt; PoleManeuver{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;font color="#008080"&gt;EnumMember&lt;/font&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Standard,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;font color="#008080"&gt;EnumMember&lt;/font&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LookMaNoHands,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;font color="#008080"&gt;EnumMember&lt;/font&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UpsideDownLookMaNoHands&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;font color="#008080"&gt;ServiceContract&lt;/font&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt; public interface&lt;/font&gt; IStripper&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;font color="#008080"&gt;OperationContract&lt;/font&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;String&lt;/font&gt; Bounce(&lt;font color="#008080"&gt;BounceLevel&lt;/font&gt; bouncin);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;font color="#008080"&gt;OperationContract&lt;/font&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;String&lt;/font&gt; SlideDownPoll(&lt;font color="#008080"&gt;PoleManeuver&lt;/font&gt; maneuver);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;font color="#008080"&gt;OperationContract&lt;/font&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt; long&lt;/font&gt; MilkSuckerForCash(&lt;font color="#008080"&gt;String&lt;/font&gt; customerName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;One approach is to create your own Proxy class , inheriting from ClientBase and passing in the type of the interface, while implementing the interface.&amp;nbsp; Pay attention to the implementations of this class:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&lt;font color="#0000ff"&gt;namespace&lt;/font&gt; Cuckooz.Sample.WCFStripClub&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;public partial class&lt;/font&gt; &lt;font color="#008080"&gt;PurePlatinumServiceClient&lt;/font&gt; : &lt;font color="#008080"&gt;ClientBase&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;IStripper&lt;/font&gt;&amp;gt;, &lt;font color="#008080"&gt;IStripper&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;public&lt;/font&gt; PurePlatinumServiceClient() { }&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;public&lt;/font&gt; PurePlatinumServiceClient(&lt;font color="#008080"&gt;String&lt;/font&gt; endpointConfigurationName) : &lt;font color="#0000ff"&gt;base&lt;/font&gt;(endpointConfigurationName) { }&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;public&lt;/font&gt; PurePlatinumServiceClient(&lt;font color="#008080"&gt;String&lt;/font&gt; endpointConfigurationName, &lt;font color="#008080"&gt;String&lt;/font&gt; remoteAddress) : &lt;font color="#0000ff"&gt;base&lt;/font&gt;(endpointConfigurationName, remoteAddress) { }&lt;/code&gt;&lt;/p&gt;&lt;code&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;public&lt;/font&gt; PurePlatinumServiceClient(&lt;font color="#008080"&gt;Binding&lt;/font&gt; binding, &lt;font color="#008080"&gt;EndpointAddress&lt;/font&gt; remoteAddress) : &lt;font color="#0000ff"&gt;base&lt;/font&gt;(binding, remoteAddress) { }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;public&lt;/font&gt; &lt;font color="#008080"&gt;String&lt;/font&gt; Bounce(&lt;font color="#008080"&gt;BounceLevel&lt;/font&gt; bouncin)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return base&lt;/font&gt;.Channel.Bounce(bouncin);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;public&lt;/font&gt; String SlideDownPoll(&lt;font color="#008080"&gt;PoleManeuver&lt;/font&gt; maneuver)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return base&lt;/font&gt;.Channel.SlideDownPoll(maneuver);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;public long&lt;/font&gt; MilkSuckerForCash(&lt;font color="#008080"&gt;String&lt;/font&gt; customerName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return base&lt;/font&gt;.Channel.SlideDownPoll(&lt;font color="#008080"&gt;customerName&lt;/font&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Note that b/c we are passing in the interface as a generic type parameter to ClientBase, we can refer to it through base.Channel.MethodName.&lt;/p&gt;
&lt;p&gt;You will need to have an endpoint configured in order to call the service and you should give the endpoint a name to make things easy.&amp;nbsp; In this case, I have a namedPipe endpoint configured named &amp;quot;NamedPipe&amp;quot;. With that in place, you simply need to create an instance of your proxy and have at it:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&lt;font color="#008080"&gt;PurePlatinumServiceClient&lt;/font&gt; dancerProxy = new &lt;font color="#008080"&gt;PurePlatinumServiceClient&lt;/font&gt;(&amp;quot;&lt;font color="#993300"&gt;NamedPipe&lt;/font&gt;&amp;quot;);&lt;br /&gt;&lt;font color="#008080"&gt;Console&lt;/font&gt;.WriteLine(dancerProxy.Bounce(&lt;font color="#008080"&gt;BounceLevel&lt;/font&gt;.YeahBaby));&lt;br /&gt;&lt;font color="#008080"&gt;Console&lt;/font&gt;.WriteLine(dancerProxy.SlideDownPoll(&lt;font color="#008080"&gt;PoleManeuver&lt;/font&gt;.UpsideDownLookMaNoHands));&lt;br /&gt;&lt;font color="#008080"&gt;Console&lt;/font&gt;.WriteLine(dancerProxy.MilkSuckerForCash(&amp;quot;&lt;font color="#993300"&gt;Peter Griffin&lt;/font&gt;&amp;quot;));&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If you are going to create your proxies like this, do yourself a favor and use CodeSmith, some other template, or if you&amp;#39;re just really hard up, copy and paste where applicable - it&amp;#39;ll save you a lot of time.&lt;/p&gt;
&lt;p&gt;If you don&amp;#39;t want to go this route though, you can skip the whole proxy altogether.&amp;nbsp; Using the ChannelFactory class, you can specify the same interface we used above and create a new ChannelFactory.&amp;nbsp; Remember to name your endpoints in the configuration file so that you can refer to them. Otherwise, you&amp;#39;ll need to specify the endpoint hard code style - which is lame.&amp;nbsp; Once you&amp;#39;ve done that, you instantiate an IYourInterface object using the CreateChannel method of the ChannelFactory you just created.&amp;nbsp; Then, you should cast it to an IDisposable object and throw it in a using block, and have at it from there. Note, you don&amp;#39;t have to use IDispose but the other approach is to cast it as a ICommuncationObject and then call Close.&amp;nbsp; For the money, it&amp;#39;s easier and safer to just go the IDispose route. So the code below is functionally equivalent to the preceding block:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&lt;font color="#008080"&gt;ChannelFactory&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;IStripper&lt;/font&gt;&amp;gt; stripperFactory = new &lt;font color="#008080"&gt;ChannelFactory&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;IStripper&lt;/font&gt;&amp;gt;(&amp;quot;&lt;font color="#993300"&gt;NamedPipe&lt;/font&gt;&amp;quot;);&lt;br /&gt;&lt;font color="#008080"&gt;IStripper&lt;/font&gt; serviceInstance = stripperFactory.CreateChannel();&lt;br /&gt;using (serviceInstance as &lt;font color="#008080"&gt;IDisposable&lt;/font&gt;)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;Console&lt;/font&gt;.WriteLine(serviceInstance.Bounce(&lt;font color="#008080"&gt;BounceLevel&lt;/font&gt;.Woot));&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;Console&lt;/font&gt;.WriteLine(serviceInstance.SlideDownPoll(&lt;font color="#008080"&gt;PoleManeuver&lt;/font&gt;.LookMaNoHands));&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;Console&lt;/font&gt;.WriteLine(serviceInstance.MilkSuckerForCash(&amp;quot;&lt;font color="#993300"&gt;Peter Griffin&lt;/font&gt;&amp;quot;));&amp;nbsp;&lt;br /&gt;}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Either of these approaches provides a ton of flexibility. For instance, you can create several endpoints, look at the environment and then decide which endpoint you want to talk on, hence, which binding you are going to use. Similarly, if you had several services you could easily change the execution to use on over the other ones.&amp;nbsp; All in all it really couldn&amp;#39;t be simpler and in this case, the hardest part of the equation is going to be setting up your configuration file properly.&lt;/p&gt;
&lt;p&gt;If I have time tomorrow I&amp;#39;ll post the next lesson which uses Duplexing, there&amp;#39;s a lot of potential with this interface and service when you enhance it with duplexing ;-)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1621334" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/williamryan/archive/tags/WCF/default.aspx">WCF</category><category domain="http://msmvps.com/blogs/williamryan/archive/tags/WIndows+Communication+Foundation/default.aspx">WIndows Communication Foundation</category><category domain="http://msmvps.com/blogs/williamryan/archive/tags/.NET+3.5+Framework/default.aspx">.NET 3.5 Framework</category><category domain="http://msmvps.com/blogs/williamryan/archive/tags/ChannelFactory/default.aspx">ChannelFactory</category><category domain="http://msmvps.com/blogs/williamryan/archive/tags/System.ServiceModel/default.aspx">System.ServiceModel</category><category domain="http://msmvps.com/blogs/williamryan/archive/tags/ClientBase/default.aspx">ClientBase</category></item></channel></rss>