<?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; : WIndows Communication Foundation</title><link>http://msmvps.com/blogs/williamryan/archive/tags/WIndows+Communication+Foundation/default.aspx</link><description>Tags: WIndows Communication Foundation</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>WF Persistence - Where [DataContract] != [Serializable]</title><link>http://msmvps.com/blogs/williamryan/archive/2008/11/01/wf-persistence-where-datacontract-serializable.aspx</link><pubDate>Sat, 01 Nov 2008 07:27:07 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1652742</guid><dc:creator>William</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/williamryan/rsscomments.aspx?PostID=1652742</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/williamryan/commentapi.aspx?PostID=1652742</wfw:comment><comments>http://msmvps.com/blogs/williamryan/archive/2008/11/01/wf-persistence-where-datacontract-serializable.aspx#comments</comments><description>&lt;p&gt;Let&amp;#39;s say you were using Workflow Foundation (WF) and Windows Communication Foundation (WCF). Assume you wanted to use WF&amp;#39;s Persistence mechanism (which requires types to be &lt;a href="http://msdn.microsoft.com/en-us/library/system.serializableattribute(VS.71).aspx"&gt;Serializable&lt;/a&gt;). And assume that all the objects you were using in the workflow were decorated with the &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx"&gt;[DataContract]&lt;/a&gt; attribute.&amp;nbsp; Would you expect any problems related to Serialization?&amp;nbsp; &lt;em&gt;(I can but to the chase really quickly here if you don&amp;#39;t want my belabored background information and explanation. If you&amp;#39;re creating a type to use w/ Workflow Foundation that will be saved via the Workflow Foundation Persistence Service which makes use of the &lt;a href="http://msdn.microsoft.com/en-us/library/system.workflow.runtime.hosting.sqlworkflowpersistenceservice.aspx"&gt;SqlWorkflowPersistenceService&lt;/a&gt; class, marking the class as a &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx"&gt;[DataContract]&lt;/a&gt; alone will not work for WF&amp;#39;s persistence mechanism. It does make the class &lt;a href="http://msdn.microsoft.com/en-us/library/system.serializableattribute(VS.71).aspx"&gt;serializable&lt;/a&gt; in a literal sense and will suffice [provided you meet the other requirements of a &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx"&gt;[DataContract]&lt;/a&gt;  for WCF&amp;#39;s serialization needs, but it is insufficient for WF (see the References section at the end of this post for more details on WF Serialization) - so make sure you use the &lt;a href="http://msdn.microsoft.com/en-us/library/system.serializableattribute(VS.71).aspx"&gt;Serializable&lt;/a&gt; attribute on any type that&amp;#39;ll be consumed by the Persistence Service).&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;MSDN describes the &lt;/strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx"&gt;&lt;strong&gt;DataContract class&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; the following way:&lt;/strong&gt;&lt;/p&gt; &lt;blockquote&gt; &lt;p align="left"&gt;&lt;em&gt; Specifies that the type defines or implements a data contract and is serializable by a serializer, such as&amp;nbsp;&amp;nbsp; the &lt;/em&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx"&gt;&lt;em&gt;DataContractSerializer&lt;/em&gt;&lt;/a&gt;&lt;em&gt;. To make their type &lt;a href="http://msdn.microsoft.com/en-us/library/system.serializableattribute(VS.71).aspx"&gt;serializable&lt;/a&gt;, type authors must define a data contract for their type.&lt;/em&gt; &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;If you spend a lot of time in WCF, you&amp;#39;d likely assume that b/c types decorated with the &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx"&gt;DataContract&lt;/a&gt; attribute would satisfy any requirement for the type to be &lt;a href="http://msdn.microsoft.com/en-us/library/system.serializableattribute(VS.71).aspx"&gt;Serializable&lt;/a&gt;.&amp;nbsp; But you&amp;#39;d likely be wrong. Yes, a type that is a &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx"&gt;[DataContract]&lt;/a&gt;&amp;nbsp; is serializable in the literal sense, but it&amp;#39;s serialized by the &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx"&gt;DataContractSerializer&lt;/a&gt; (see the &lt;em&gt;References&lt;/em&gt; section at the end of this post for more details on WF Serialization) &lt;p&gt;So why is this an issue and what do you do about it?&amp;nbsp; Often, non-trivial workflows span an amount of time that exceeds any given user&amp;#39;s session.&amp;nbsp; In fact, it&amp;#39;s not uncommon for a non-trivial workflow to span as much as 30 days.&amp;nbsp; Using a simple example, let&amp;#39;s say that you are writing a Workflow to manage new employees.&amp;nbsp; Further assume that there are several document requirements and that any deficiencies would result in severe penalties or liability risks.&amp;nbsp; Just to make it clear, assume that each of the following must be procured before a new employee can start working.&amp;nbsp; Further, assume that b/c of fees associated with each, if any previous one fails, that the whole process terminates (if someone&amp;#39;s reference checks don&amp;#39;t pass, there&amp;#39;s no need to spend the money for a full background investigation as you know you&amp;#39;re not going to hire them). [Also, this isn&amp;#39;t a post on workplace hiring guidelines and is solely used for illustration - no need to point out why &amp;#39;its bad business to drug test or whatever else]. &lt;ol&gt; &lt;li&gt;Employment Application&lt;/li&gt; &lt;li&gt;Proof of Citizenship or ability to work in the U.S.&lt;/li&gt; &lt;li&gt;State withholding form&lt;/li&gt; &lt;li&gt;Federal withholding form&lt;/li&gt; &lt;li&gt;Reference check&lt;/li&gt; &lt;li&gt;License check&lt;/li&gt; &lt;li&gt;Completed Drug Screen&lt;/li&gt; &lt;li&gt;Full Background check&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Implementation policies will vary from company to company but assume that all of these tasks wouldn&amp;#39;t be completed within the user session that first created the entity. If you couldn&amp;#39;t persist the workflow somehow and come back to it later, it would be of very little use.&amp;nbsp;&amp;nbsp; Workflow foundation provides an out-of-the-box solution named not surprisingly -&amp;nbsp; &lt;a href="http://msdn.microsoft.com/en-us/library/ms735722(VS.85).aspx"&gt;Windows Workflow Persistence Service&lt;/a&gt; to help with long running workflows&lt;/p&gt; &lt;p&gt;Since Workflow Foundation is still in its infancy in terms of user adoption, many shops don&amp;#39;t have well established design rules in place specifically for Workflow items.&amp;nbsp; This can have some profound (although easily addressed in most cases) effects on Workflow development. It&amp;#39;s common for a workflow to start out small in terms of steps and happen relatively quickly.&amp;nbsp; When this is the case, there&amp;#39;s little need for a persistence mechanism for the workflow.&amp;nbsp; But as people get comfortable with WF and are willing to try more involved solutions, steps get added that often increase the time span the workflow could run to a point that&amp;#39;s longer than the user session.&amp;nbsp; For people new to WF, adding that first activity that&amp;#39;ll possibly span a large amount of time is the first time they actually think seriously about the persistence service. And that&amp;#39;s the point at which they often go back and try to retrofit things.&amp;nbsp; In many cases, the number of &amp;quot;things&amp;quot; will be fairly substantial so it&amp;#39;s quite easy to overlook something.&amp;nbsp; Once you implement the persistence service, you&amp;#39;ll typically go through the testing phase and make sure everything persist and can be retrieved correctly.&amp;nbsp; And this is the time serialization problems with show themselves - often in a manner that&amp;#39;s hard to isolate b/c the number of items involved.&amp;nbsp; &lt;/p&gt; &lt;p&gt; In some cases, if there&amp;#39;s a serialization problem, a fault will result.&amp;nbsp; &lt;a href="http://odetocode.com/Blogs/scott/archive/2007/01/24/9943.aspx"&gt;Unhandled faults&lt;/a&gt; in WF cause behavior that deviates from what you&amp;#39;d typically expect. So depending on your logging and tracing, you may or may not find the issue quickly. in many cases, you&amp;#39;ll find the fault is related to serialization and you&amp;#39;ll address it on the specific type, then go back and try to find every other type and make it &lt;a href="http://msdn.microsoft.com/en-us/library/system.serializableattribute(VS.71).aspx"&gt;serializable&lt;/a&gt; as well.&amp;nbsp; This is likely to be overkill though - b/c you&amp;#39;re likely to have some types that aren&amp;#39;t involved in anything that&amp;#39;s persisted and consequently don&amp;#39;t require persistence.&amp;nbsp; So you try to only make the items that will be persisted &lt;a href="http://msdn.microsoft.com/en-us/library/system.serializableattribute(VS.71).aspx"&gt;serializable&lt;/a&gt;. Until you get to the point where you&amp;#39;re addressing everything in the planning and design stages, you&amp;#39;re likely to run into situations like this and the only way out typically involves a lot of trial-and-error.&amp;nbsp; That&amp;#39;s why this post is relevant. If you go back and define each type that will be persisted as a &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx"&gt;[DataContract]&lt;/a&gt; , it&amp;#39;ll take you some time to do, may necessitate you adding new references to some projects and ultimately, after all that&amp;#39;s done, won&amp;#39;t fix the problem. The following type may work all day long when just dealing with WCF&amp;#39;s serialization requirements...&lt;/p&gt; &lt;p&gt;namespace Ger911.HCStandard.Core.Shared&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [DataContract]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class MatrixItem&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; [DataMember]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String EntityName { get; set; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [DataMember]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String ContactName { get; set; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [DataMember]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Int32 BedCount { get; set; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [DataMember]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String HospitalStatus { get; set; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [DataMember]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public DateTime ModifiedDateTime { get; set; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;} &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;But unless you modify it like this, you&amp;#39;ll be in for some unpleasant surprises in WF:&lt;/p&gt; &lt;p&gt;namespace Ger911.HCStandard.Core.Shared&lt;br /&gt;{&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Serializable]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [DataContract]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class MatrixItem&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; [DataMember]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String EntityName { get; set; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [DataMember]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String ContactName { get; set; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [DataMember]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Int32 BedCount { get; set; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [DataMember]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String HospitalStatus { get; set; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [DataMember]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public DateTime ModifiedDateTime { get; set; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/p&gt; &lt;p&gt;References:&lt;/p&gt; &lt;p&gt;Using &lt;a href="http://www.red-gate.com/products/reflector/"&gt;Red Gate&amp;#39;s Reflector&lt;/a&gt;, here&amp;#39;s what you&amp;#39;ll see under the hood of the &lt;a href="http://msdn.microsoft.com/en-us/library/system.workflow.runtime.hosting.workflowpersistenceservice.aspx"&gt;WorkflowPesistenceService&lt;/a&gt; class&amp;#39;s &lt;a href="http://msdn.microsoft.com/en-us/library/system.workflow.runtime.hosting.workflowpersistenceservice.restorefromdefaultserializedform.aspx"&gt;RestoreFromDefaultSerializedForm&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/system.workflow.runtime.hosting.workflowpersistenceservice.getdefaultserializedform.aspx"&gt;GetDefaultSerializedForm&lt;/a&gt;.&amp;nbsp; For further insight into this, use &lt;a href="http://www.red-gate.com/products/reflector/"&gt;Reflector&lt;/a&gt; and examine the &lt;a href="http://msdn.microsoft.com/en-us/library/system.workflow.runtime.hosting.sqlworkflowpersistenceservice.aspx"&gt;SqlWorkflowPersistenceService&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font size="3"&gt;&lt;strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.workflow.runtime.hosting.workflowpersistenceservice.restorefromdefaultserializedform.aspx"&gt;RestoreFromDefaultSerializedForm&lt;/a&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;protected static Activity RestoreFromDefaultSerializedForm(byte[] activityBytes, Activity outerActivity)&lt;br /&gt;{&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; Activity activity;&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; DateTime now = DateTime.Now;&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; MemoryStream stream = new MemoryStream(activityBytes);&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; stream.Position = 0L;&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; using (GZipStream stream2 = new GZipStream(stream, CompressionMode.Decompress, true))&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;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; activity = Activity.Load(stream2, outerActivity);&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;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TimeSpan span = (TimeSpan)(DateTime.Now - now);&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; WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, &amp;quot;Deserialized a {0} to length {1}. Took {2}.&amp;quot;,&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new object[] { activity, stream.Length, span }); return activity;&lt;br /&gt; } &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.workflow.runtime.hosting.workflowpersistenceservice.getdefaultserializedform.aspx"&gt;GetDefaultSerializedForm&lt;/a&gt;&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;protected static byte[] GetDefaultSerializedForm(Activity activity)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DateTime now = DateTime.Now;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using (MemoryStream stream = new MemoryStream(0x2800))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&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;&amp;nbsp;&amp;nbsp; stream.Position = 0L;&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;&amp;nbsp;&amp;nbsp; activity.Save(stream);&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;&amp;nbsp;&amp;nbsp; using (MemoryStream stream2 = new MemoryStream((int)stream.Length))&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;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using (GZipStream stream3 = new GZipStream(stream2, CompressionMode.Compress, true))&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;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; stream3.Write(stream.GetBuffer(), 0, (int)stream.Length);&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;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ActivityExecutionContextInfo info = (ActivityExecutionContextInfo)activity.GetValue(Activity.ActivityExecutionContextInfoProperty);&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TimeSpan span = (TimeSpan)(DateTime.Now - now);&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, &amp;quot;Serialized a {0} with id {1} to length {2}. Took {3}.&amp;quot;, new object[] { info, info.ContextGuid, stream2.Length, span });&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; byte[] array = stream2.GetBuffer();&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Array.Resize&amp;lt;byte&amp;gt;(ref array, Convert.ToInt32(stream2.Length));&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return array;&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;&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; }&lt;br /&gt;} &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx"&gt;&lt;font size="3"&gt;&lt;strong&gt;DataContractSerializer&lt;/strong&gt;&lt;/font&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;public sealed class DataContractSerializer : XmlObjectSerializer&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Fields&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private IDataContractSurrogate dataContractSurrogate;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private bool ignoreExtensionDataObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal Dictionary&amp;lt;XmlQualifiedName, DataContract&amp;gt; knownDataContracts;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private ReadOnlyCollection&amp;lt;Type&amp;gt; knownTypeCollection;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal IList&amp;lt;Type&amp;gt; knownTypeList;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private int maxItemsInObjectGraph;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private bool needsContractNsAtRoot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private bool preserveObjectReferences;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private DataContract rootContract;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private XmlDictionaryString rootName;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private XmlDictionaryString rootNamespace;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Type rootType;  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Methods&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public DataContractSerializer(Type type);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public DataContractSerializer(Type type, IEnumerable&amp;lt;Type&amp;gt; knownTypes);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public DataContractSerializer(Type type, string rootName, string rootNamespace);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public DataContractSerializer(Type type, XmlDictionaryString rootName, XmlDictionaryString rootNamespace);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public DataContractSerializer(Type type, string rootName, string rootNamespace, IEnumerable&amp;lt;Type&amp;gt; knownTypes);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public DataContractSerializer(Type type, XmlDictionaryString rootName, XmlDictionaryString rootNamespace, IEnumerable&amp;lt;Type&amp;gt; knownTypes);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public DataContractSerializer(Type type, IEnumerable&amp;lt;Type&amp;gt; knownTypes, int maxItemsInObjectGraph, bool ignoreExtensionDataObject, bool preserveObjectReferences, IDataContractSurrogate dataContractSurrogate);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public DataContractSerializer(Type type, string rootName, string rootNamespace, IEnumerable&amp;lt;Type&amp;gt; knownTypes, int maxItemsInObjectGraph, bool ignoreExtensionDataObject, bool preserveObjectReferences, IDataContractSurrogate dataContractSurrogate);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public DataContractSerializer(Type type, XmlDictionaryString rootName, XmlDictionaryString rootNamespace, IEnumerable&amp;lt;Type&amp;gt; knownTypes, int maxItemsInObjectGraph, bool ignoreExtensionDataObject, bool preserveObjectReferences, IDataContractSurrogate dataContractSurrogate);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal static DataContract GetDataContract(DataContract declaredTypeContract, Type declaredType, Type objectType);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal override Type GetDeserializeType();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal override Type GetSerializeType(object graph);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal static Type GetSurrogatedType(IDataContractSurrogate dataContractSurrogate, Type type);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private void Initialize(Type type, IEnumerable&amp;lt;Type&amp;gt; knownTypes, int maxItemsInObjectGraph, bool ignoreExtensionDataObject, bool preserveObjectReferences, IDataContractSurrogate dataContractSurrogate);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private void Initialize(Type type, XmlDictionaryString rootName, XmlDictionaryString rootNamespace, IEnumerable&amp;lt;Type&amp;gt; knownTypes, int maxItemsInObjectGraph, bool ignoreExtensionDataObject, bool preserveObjectReferences, IDataContractSurrogate dataContractSurrogate);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal override bool InternalIsStartObject(XmlReaderDelegator reader);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal override object InternalReadObject(XmlReaderDelegator xmlReader, bool verifyObjectName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal override void InternalWriteEndObject(XmlWriterDelegator writer);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal override void InternalWriteObject(XmlWriterDelegator writer, object graph);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal override void InternalWriteObjectContent(XmlWriterDelegator writer, object graph);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal override void InternalWriteStartObject(XmlWriterDelegator writer, object graph);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override bool IsStartObject(XmlDictionaryReader reader);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override bool IsStartObject(XmlReader reader);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override object ReadObject(XmlReader reader);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override object ReadObject(XmlReader reader, bool verifyObjectName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal static object SurrogateToDataContractType(IDataContractSurrogate dataContractSurrogate, object oldObj, Type surrogatedDeclaredType, ref Type objType);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void WriteEndObject(XmlDictionaryWriter writer);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void WriteEndObject(XmlWriter writer);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void WriteObject(XmlWriter writer, object graph);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void WriteObjectContent(XmlDictionaryWriter writer, object graph);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void WriteObjectContent(XmlWriter writer, object graph);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void WriteStartObject(XmlDictionaryWriter writer, object graph);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void WriteStartObject(XmlWriter writer, object graph);  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Properties&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IDataContractSurrogate DataContractSurrogate { get; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public bool IgnoreExtensionDataObject { get; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal Dictionary&amp;lt;XmlQualifiedName, DataContract&amp;gt; KnownDataContracts { get; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public ReadOnlyCollection&amp;lt;Type&amp;gt; KnownTypes { get; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public int MaxItemsInObjectGraph { get; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public bool PreserveObjectReferences { get; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private DataContract RootContract { get; }&lt;br /&gt;}&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1652742" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/williamryan/archive/tags/.NET+General/default.aspx">.NET General</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.0+Framework/default.aspx">.NET 3.0 Framework</category><category domain="http://msmvps.com/blogs/williamryan/archive/tags/Workflow/default.aspx">Workflow</category><category domain="http://msmvps.com/blogs/williamryan/archive/tags/.NET+3.5+Framework/default.aspx">.NET 3.5 Framework</category></item><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>Cool Powershell script</title><link>http://msmvps.com/blogs/williamryan/archive/2008/05/20/cool-powershell-script.aspx</link><pubDate>Wed, 21 May 2008 03:59:14 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1625389</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=1625389</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/williamryan/commentapi.aspx?PostID=1625389</wfw:comment><comments>http://msmvps.com/blogs/williamryan/archive/2008/05/20/cool-powershell-script.aspx#comments</comments><description>&lt;p&gt;I can&amp;#39;t take credit for this, I came across it in &lt;a href="http://www.amazon.com/Windows-Communication-Foundation-Unleashed-WCF/dp/0672329484"&gt;Windows Communication Foundation Unleashe&lt;/a&gt;d - but it&amp;#39;s very helpful for administering &lt;a href="http://msdn.microsoft.com/en-us/netframework/aa663324.aspx"&gt;Windows Communication Foundation&lt;/a&gt;...&lt;/p&gt; &lt;p&gt;In the &amp;lt;diagnostics&amp;gt; tag of your service&amp;#39;s configuration, two available options are &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.configuration.diagnosticsection.wmiproviderenabled.aspx"&gt;wmiProviderEnabled&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.configuration.diagnosticsection.performancecounters.aspx"&gt;performanceCounters&lt;/a&gt;.&amp;nbsp; So ideally you&amp;#39;ll want to set both, but if you just need to identify the endpoint then only the first one is necessary:&lt;/p&gt; &lt;p&gt;&lt;font size="1" face="Courier New"&gt;&amp;lt;system.serviceModel&amp;gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="1" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;diagnostics &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="1" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; wmiProviderEnabled=&amp;quot;true&amp;quot;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="1" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; performanceCounters=&amp;quot;ServiceOnly&amp;quot;/&amp;gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="1" face="Courier New"&gt;&amp;lt;/system.ServiceModel&amp;gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;After you have that in place for your service(s), you can use the following Powershell script&lt;/p&gt; &lt;p&gt;&lt;font size="1" face="Courier New"&gt;PS C:\Windows\System32&amp;gt; get-wmiobject endpoint -n root\ServiceModel | ft name&lt;/font&gt;&lt;/p&gt; &lt;p&gt;I don&amp;#39;t know if I love Powershell more than Windows Communication Foundation or WCF more than Powershell, but few things are cooler than using them together and this is one script you&amp;#39;ll undoubtedly find helpful.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1625389" 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/Visual+Studio+.NET+Orcas/default.aspx">Visual Studio .NET Orcas</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></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><item><title>Pro WCF: Practical Microsoft SOA Implementation</title><link>http://msmvps.com/blogs/williamryan/archive/2007/02/18/pro-wcf-practical-microsoft-soa-implementation.aspx</link><pubDate>Sun, 18 Feb 2007 23:41:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:595155</guid><dc:creator>William</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/williamryan/rsscomments.aspx?PostID=595155</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/williamryan/commentapi.aspx?PostID=595155</wfw:comment><comments>http://msmvps.com/blogs/williamryan/archive/2007/02/18/pro-wcf-practical-microsoft-soa-implementation.aspx#comments</comments><description>&lt;P&gt;I went on&amp;nbsp; a book binge this week and have had my nose buried in WCF all week.&amp;nbsp; There's a lot of really good stuff out there, but without a doubt, &lt;A href="http://www.amazon.com/Pro-WCF-Practical-Microsoft-Implementation/dp/1590597028/sr=8-1/qid=1171842173/ref=pd_bbs_sr_1/102-7496017-5356110?ie=UTF8&amp;amp;s=books"&gt;Pro WCF: Practical Microsoft SOA Implementation&lt;/A&gt;&amp;nbsp;by &lt;A href="http://www.chrispeiris.com/"&gt;Chris Peiris&lt;/A&gt;&amp;nbsp;is probably my favorite.&lt;/P&gt;
&lt;P&gt;Overall, the book is just over 400 pages but the author says quite a bit in those 400 pages.&amp;nbsp; The coolest part is that they go over just about every topic that the MSDN Documentation is short on.&amp;nbsp; I found that a lot of things that I stumbled my way through were covered there as well.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;I can't find the link, but a while ago, &lt;A href="http://www.brains-n-brawn.com/"&gt;KC&lt;/A&gt; had a post where his server program uploaded&amp;nbsp;itself&amp;nbsp;his web server and ran itself. His comment was something to the effect about "What did the first Blacksmith use".&amp;nbsp; I was always really impressed with that program. And not just b/c &lt;A href="http://www.brains-n-brawn.com/"&gt;of the lower cased one&lt;/A&gt;'s coding skill. The idea itself was really cool.&amp;nbsp; So when&amp;nbsp;&amp;nbsp;&lt;A href="http://msdn2.microsoft.com/en-us/webservices/aa740663.aspx"&gt;WSE 3.0&lt;/A&gt; came out and &lt;A href="http://en.wikipedia.org/wiki/MTOM"&gt;MTOM&lt;/A&gt;&amp;nbsp; was implemented, I tried to bite his style and accomplish the same thing with MTOM. It's an easy port so it didn't take much skill on my part.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;Anyway, I've been trying to figure out how to port most of the WSE 3.0 code from&amp;nbsp; my 70-529 book over to WCF. I've been able to do most of it, however it's been frustrating at times.&amp;nbsp; I'm make a lot of typos and copy/paste errors and neither play well with .config files.&amp;nbsp; After wasting about 3 hours trying to get the MTOM port to work, I read through this book and Viola'. I was kinda mad at myself for overcomplicating things that much.&amp;nbsp; So I guess I really like the book in large part b/c I've had quite a few similar experiences with it.&lt;/P&gt;
&lt;P&gt;My favorite chapters are discussed below:&lt;/P&gt;
&lt;P&gt;Chapter 4 - It discusses installation and configuration.&amp;nbsp; This is the single most frustrating area when learning WCF.&amp;nbsp; Writing code instead of using .config files is lame so I try to avoid it. But getting some help in avoiding common mistakes is priceless..&lt;/P&gt;
&lt;P&gt;Chatper 6 discusses managing WCF Services. Not a glamorous subject but being able to monitor and troubleshoot your programs is critical.&amp;nbsp; Moreover, when you're first learning how to do things, it's easy to ignore performance. It's easy to overlook things that can kill performance.&amp;nbsp; After reading this chapter, I am in a lot better shape to find problems&lt;/P&gt;
&lt;P&gt;Chaper 7 discusses security. Obviously a pretty big issue when you're building services.&amp;nbsp; Just for good measure there's some CardSpace stuff at the end which was a nice touch.&lt;/P&gt;
&lt;P&gt;Chapter 9 discusses transactions. For obvious reasons, this is a subject you need to learn well and although I thought I was pretty familiar with them, I learned more than a few things from this chapter.&lt;/P&gt;
&lt;P&gt;-------------------&lt;/P&gt;
&lt;P&gt;All in all, this book was pretty impressive.&amp;nbsp; They do mostly real world stuff and while they certainly talk theory, they stick to stuff that you'll encounter in your day to day development.&amp;nbsp; You can only take so much theory and I've found that the documentation on MSDN is really heavy on theory and not enough implementation.&amp;nbsp; This book will bridge that gap. &lt;A href="http://www.amazon.com/Professional-WCF-Programming-Development-Communication/dp/0470089849/sr=1-1/qid=1171843376/ref=sr_1_1/102-7496017-5356110?ie=UTF8&amp;amp;s=books"&gt;Scott Klein's WCF book&lt;/A&gt;&amp;nbsp;will help quite a bit too but won't be out for another month or two. &lt;/P&gt;
&lt;P&gt;I also picked up &lt;A href="http://www.amazon.com/Microsoft-Windows-Communication-Foundation-Developer/dp/0735623368/sr=1-1/qid=1171843548/ref=sr_1_1/102-7496017-5356110?ie=UTF8&amp;amp;s=books"&gt;John Sharp's Microsoft Windows Communication Foundation &lt;EM&gt;Step by Step&lt;/EM&gt;&lt;/A&gt;.&amp;nbsp; So far, my impressions are quite favorable although I haven't went through it in quite the detail I did with this one.&amp;nbsp; I worked through each of the examples and found them pretty cool.&amp;nbsp; Should have a review of it up shortly.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=595155" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/williamryan/archive/tags/Books/default.aspx">Books</category><category domain="http://msmvps.com/blogs/williamryan/archive/tags/.NET+General/default.aspx">.NET General</category><category domain="http://msmvps.com/blogs/williamryan/archive/tags/Visual+Studio+.NET+2005/default.aspx">Visual Studio .NET 2005</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.0+Framework/default.aspx">.NET 3.0 Framework</category></item><item><title>Windows Activation Hosting (WAS) and WCF</title><link>http://msmvps.com/blogs/williamryan/archive/2007/01/28/windows-activation-hosting-was-and-wcf.aspx</link><pubDate>Sun, 28 Jan 2007 15:32:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:525235</guid><dc:creator>William</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/williamryan/rsscomments.aspx?PostID=525235</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/williamryan/commentapi.aspx?PostID=525235</wfw:comment><comments>http://msmvps.com/blogs/williamryan/archive/2007/01/28/windows-activation-hosting-was-and-wcf.aspx#comments</comments><description>&lt;P&gt;A few years ago, I took a job at &lt;A href="http://www.tibasolutions.com/"&gt;Tiba Solutions&lt;/A&gt; .&amp;nbsp;One of the coolest things about that job was working with &lt;A href="http://blogs.msdn.com/tobint/"&gt;Tobin Titus&lt;/A&gt;.&amp;nbsp; Tobin is pretty much a bad a55 at all sorts of things and one of the things he really rocked at was &lt;A href="http://www.amazon.com/Pro-NET-Remoting-Reflection-Threading/dp/1590594525/sr=8-2/qid=1169998484/ref=sr_1_2/104-8028824-2026339?ie=UTF8&amp;amp;s=books"&gt;Remoting&lt;/A&gt;.&amp;nbsp;I learned most of what I know from him.&amp;nbsp;He has long since left Tiba as have I and moved on to greener pastures.&amp;nbsp; Currently he's at Microsoft.&amp;nbsp; Now that I've sucked up enough to Tobin hopefully I can get him to explain to me how to get my GD WCF service configured properly to run in IIS 7.0 under WAS.. So if I run&amp;nbsp;&lt;A href="http://technet2.microsoft.com/WindowsServer/en/library/8e1bba31-de8c-4b82-9a09-9ac8ea102ce31033.mspx"&gt;appcmd.exe&lt;/A&gt; from the VS Command Line, this file is generated and all is good. If I create a new site and do this manually, it bombs on me telling me the target machine is actively refusing my connection. I can't see any difference for the life of me. Does &lt;A href="http://technet2.microsoft.com/WindowsServer/en/library/8e1bba31-de8c-4b82-9a09-9ac8ea102ce31033.mspx"&gt;appcmd.exe&lt;/A&gt;&amp;nbsp;do something else critical that I'm missing?&lt;/P&gt;&lt;CODE&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;?&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;xml&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;version&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;1.0&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;encoding&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;utf-8&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; ?&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;configuration&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;system.applicationhost&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;sites&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;site&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;CuckooClock&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;1&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;bindings&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;binding&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;protocol&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;http&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;bindinginformation&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;*:80*&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;/&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;binding&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;protocol&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;net.msmq&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;bindinginformation&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;*&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;/&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;binding&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;protocol&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;net.tcp&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;bindinginformation&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;*&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;/&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;binding&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;protocol&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;net.pipe&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;bindinginformation&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;*&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;/&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;bindings&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt; &lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;site&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;sites&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;system.applicationhost&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;configuration&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/CODE&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=525235" 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/IIS+7.0/default.aspx">IIS 7.0</category></item><item><title>Is my Windows Communication Foundaton Service configured correctly?</title><link>http://msmvps.com/blogs/williamryan/archive/2007/01/27/is-my-windows-communication-foundaton-service-configured-correctly.aspx</link><pubDate>Sat, 27 Jan 2007 23:55:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:524288</guid><dc:creator>William</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/williamryan/rsscomments.aspx?PostID=524288</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/williamryan/commentapi.aspx?PostID=524288</wfw:comment><comments>http://msmvps.com/blogs/williamryan/archive/2007/01/27/is-my-windows-communication-foundaton-service-configured-correctly.aspx#comments</comments><description>&lt;P&gt;One of the really sucky things about doing presentations is that you have to learn what you're talking about first.&amp;nbsp; Actually, there's nothing sucky about learning things, it's just that at until you hit your learning curve, it can be frustrating.&amp;nbsp; It's after that point though that things become sucky.&amp;nbsp; Why?&amp;nbsp; Because all too often you start going "Wow, is this cool, I wonder if I can_____________" and then you give it a try. Some stuff works on the first pass, some stuff doesn't.&amp;nbsp; Then you start debugging and searching around, figure out how to make it work and you in my case, it usually takes something like the dog pooping on the floor to make me realize how long I've been zoned out on the computer.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;If you're familiar with Windows Communication Foundation (WCF) then you realize that it's so configurable its almost hard to fathom (I really woulnd't be surprised if the next version negates the need for code altogether and you simply flip around config file settings to do what you want).&amp;nbsp; Configuration is as cool as hard coding stuff is lame, but one problem with it is that it's fussy.&amp;nbsp; If you screw something up in a XAML file (which is similar in form to config files) for instance, the compiler jumps in and lends you a hand telling you rather precisely what you did wrong. If you screw something up in a configuration file for WCF, you get the same behavior you did with .NET Remoting (for the uninitiated, that means it just sits there and laughs at you as you try to figure out which word you incorrectly spelled).&lt;/P&gt;
&lt;P&gt;So I'm trudging through a bunch of samples I was thinking about and then realized most of what I've done entails hosting the service in a Console application.&amp;nbsp; Time to take off the training wheels and host it in IIS right?&amp;nbsp; I ask myself "Hell, how hard can that be?"&lt;/P&gt;
&lt;P&gt;I created my virtual director and started copying stuff over.&amp;nbsp; Carefully, I changed my configuration file settings.&amp;nbsp; Just to be safe I left out all the fancy stuff I was doing with CustomBindings and just left in the simple stuff.&amp;nbsp; "This should be a breeze" I'm thinking the whole time.&amp;nbsp; So far so good.&amp;nbsp; Normally, as I progress along each step of the way I test that part to make sure I got it right up until then, just so it's easier to isolate problems down the road should they arise.&amp;nbsp; My ego got ahead of my brain and off I went.&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;CODE&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;configuration&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;xmlns&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;http://schemas.microsoft.com/.NetConfiguration/v2.0&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;system.serviceModel&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;services&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;service&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;MarkBrownService&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;behaviorConfiguration&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;returnFaults&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;endpoint&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;contract&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;IKnightEmailHelper&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff&gt; &lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;binding&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;wsHttpBinding&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;/&amp;gt; &lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;service&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;service&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;BlueCuckooService&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;behaviorConfiguration&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;returnFaults&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;endpoint&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;contract&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;IPeck &lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;binding&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;wsHttpBinding&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;/&amp;gt; &lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;service&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;service&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SausageDogService&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;behaviorConfiguration&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;returnFaults&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;endpoint&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;contract&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;ITakeADump&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff&gt; &lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;binding&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;wsHttpBinding&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;/&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;service&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;service&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;DigitalStripperService&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;behaviorConfiguration&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;returnFaults&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;endpoint&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;contract&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;IStrip&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff&gt; &lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;binding&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;wsHttpBinding&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;/&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;service&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;/CODE&gt;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Now, the first of these is really lame but the other three do quite a bit of stuff.&amp;nbsp; I do a second glance to make sure everything looks ok and it does.&amp;nbsp; I hand coded the client classes and was pretty sure they were good. So I fire everyting up and I see this:&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;The contract name 'IPeck ' could not be found in the list of contracts implemented by the service 'BlueCuckooService'.&lt;/EM&gt; &lt;/P&gt;
&lt;P&gt;&lt;EM&gt;The contract name 'ITakeADump ' could not be found in the list of contracts implemented by the service 'SausageDogService'.&lt;/EM&gt;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;EM&gt;The contract name 'IStrip ' could not be found in the list of contracts implemented by the service 'DigitalStripperService'.&lt;/EM&gt;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Wheewwwy, I screwed up every single one of them.&amp;nbsp; So I tried to eliminate them one at a time, same problem.&amp;nbsp; I check the name, check the interface name.&amp;nbsp; Both look good.&amp;nbsp; So what have I done differently?&amp;nbsp; I put the interfaces into a shared assembly, that must be it.&amp;nbsp; So I removed the project reference and copied the classes back into the project.&amp;nbsp; Double checked the namespaces and figured, this has to be it. But it wasn't.&amp;nbsp; I went through everything I could think of and nothing.&amp;nbsp; Fortunately, Nikki the sausage dog got that look in his eye that he usually does right before chewing up one of my shoes or taking a dump on the floor and sharing it with me.&amp;nbsp; Upon getting up I realized I had&amp;nbsp;went wayy tooo far down WindowsCommuncationFoundation express today and needed to do other things like walk the dog.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;When I arrived back, I saw what the problem was by the time I got comfortably seating.&amp;nbsp; A lot of times things just work like that.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;So, take one last look at the problem and see if you can figure it out - it's totally glaring if you're careful. (If you've been a reader of my blog for a while, it's&amp;nbsp; a well known thing that I due and have done the same thing many times before.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;I tend to type fairly quickly and while I use both thumps to space with, I frequently double this the space bar.&amp;nbsp; In T-SQL and C#, it seldom matters. MS Word and Excel both just fix it for me.&amp;nbsp; So I don't even realize I"m doing it. But configuration files - well, I think that they were made by a bunch of German guys who though it'd be a great goof to give guys like me a hard time "So uuwwe really sink dat Lexus have betta quality control den der BMW, You fool, we'll teach you a lesson!"&lt;/P&gt;
&lt;P&gt;So I looked around and looked around and realized I put an extra space in after an interface name. Ok, that's fixed. All is good. But each new service I added suffered from the same problem. This time I knew exactly what it was, but it was easy to mess up b/c of muscle memory in my fingers.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;A quick way to know if you're service is configured correctly is as simple as one like in a browers:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://localhost:2361/CuckooService/EvilBlueCuckooService.svc?wsdl"&gt;&lt;CODE&gt;http://localhost:2361/CuckooService/EvilBlueCuckooService.svc?wsdl&lt;/CODE&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Substitute the name and location of your service(s) and use the good old ?wsdl method to make sure it works. If everything is in place, a browser window with a bunch of nested funky looking&amp;nbsp;xml should appear that looks like your service definition.&amp;nbsp; If not, well you gotta problem.&amp;nbsp; So simple to use, it's worth it's price in gold.&lt;/P&gt;
&lt;P&gt;So far, I got the images of the Cuckoo coming out of his clock, the SausageDog making "pinchy loaf loaf" all wired into to a client UI.&amp;nbsp; If any of my reliable friends like &lt;A href="http://www.brains-n-brawn.com/"&gt;KC&lt;/A&gt;&amp;nbsp;, &lt;A href="http://msmvps.com/blogs/brianmadsen/"&gt;Brian Madsen&lt;/A&gt;&amp;nbsp;, &lt;A href="http://blah.winsmarts.com/"&gt;Sahil&lt;/A&gt;&amp;nbsp;or &lt;A href="http://community.strongcoders.com/blogs/default.aspx"&gt;Ryan&lt;/A&gt;&amp;nbsp;wanna help me with the UI for the last one, I got the back end stuff worked out ;-)&lt;/P&gt;
&lt;P&gt;And hopefully none of the &lt;A href="http://www.charlescarroll.com/"&gt;Usual&lt;/A&gt; and &lt;A href="mailto:knightsofasproundtable@yahoogroups.com" target=_blank&gt;BrainWashedGrievance Brigade&lt;/A&gt;&lt;BR&gt;&amp;nbsp;will try to pee on our parade.&amp;nbsp; I have a lot of fun WCF samles which are pretty cool.&lt;/P&gt;
&lt;P&gt;My next WCF post will be on "Doing things with Behaviors most people can only dream about..."&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=524288" 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/Service/default.aspx">Service</category><category domain="http://msmvps.com/blogs/williamryan/archive/tags/_2E00_config/default.aspx">.config</category><category domain="http://msmvps.com/blogs/williamryan/archive/tags/EndPoint/default.aspx">EndPoint</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.0+Framework/default.aspx">.NET 3.0 Framework</category><category domain="http://msmvps.com/blogs/williamryan/archive/tags/ConfigurationFile/default.aspx">ConfigurationFile</category></item></channel></rss>