<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blog.magenic.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>Outsourcing to Sleestak</title><link>http://blog.magenic.com/blogs/jamesa/default.aspx</link><description>Technical Blog on ASP.NET AJAX, WCF, WPF, and any other shiny tinsel that captures a developer's short attention span, with hands on information about getting the most productivity out of your sleestak workforce.</description><dc:language>en</dc:language><generator>CommunityServer 2.1 (Build: 60809.935)</generator><item><title>Covariance and Contravariance In 5 Minutes</title><link>http://blog.magenic.com/blogs/jamesa/archive/2009/10/08/Covariance-and-Contravariance-In-5-Minutes.aspx</link><pubDate>Thu, 08 Oct 2009 16:33:40 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:12363</guid><dc:creator>Anonymous</dc:creator><slash:comments>116</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/12363.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=12363</wfw:commentRss><description>&lt;p&gt;C# 4.0 will introduce new language features to help manage covariance and contravariance.&amp;#160; While this is a a wonderful capability, it forces us to come to terms with these (to me) somewhat unfamiliar terms.&lt;/p&gt;  &lt;p&gt;As I have been working through Eric Lippert’s excellent series of &lt;a href="http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx" target="_blank"&gt;posts&lt;/a&gt; on this topic as well as the wikipedia &lt;a href="http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)" target="_blank"&gt;entry&lt;/a&gt;, it has occurred to me that the best way to come to grips with these concepts is to examine gradually more complex examples of covariance and contravariance as it currently exists in C# 3.&amp;#160; If this appears to be a rehash of Eric Lippert’s work, this is probably because it is.&amp;#160; Consequently, any mistakes are purely mine, while any virtue in this explanation is very much due to him.&lt;/p&gt;  &lt;p&gt;First, however, it is necessary to learn some vocabulary.&lt;/p&gt;  &lt;p&gt;Take the following class hierarchy:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Animal{}
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Mammal : Animal { }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Tiger : Mammal { }&lt;/pre&gt;

&lt;p&gt;We would typically say that Mammal is &lt;em&gt;more derived&lt;/em&gt; than Animal.&amp;#160; Mammal, conversely, is &lt;em&gt;less derived&lt;/em&gt; than Tiger in this inheritance chain.&lt;/p&gt;

&lt;p&gt;To understand covariance and contravariance, we need to replace &lt;em&gt;more derived&lt;/em&gt; and &lt;em&gt;less derived&lt;/em&gt; with the metaphorical terms &lt;em&gt;smaller&lt;/em&gt; and &lt;em&gt;bigger&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We do this because &lt;em&gt;more derived&lt;/em&gt; and &lt;em&gt;less derived&lt;/em&gt; are not adequate to describe the relation between objects such as arrays of types.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;        Animal[] A;
        Mammal[] M;
        Tiger[] T;&lt;/pre&gt;

&lt;p&gt;An array of Mammal does not derive from an array of Animal.&amp;#160; Both Mammal[] and Animal[] are derived from System.Array. There is no inheritance relation, however, between Mammal[] and Animal[] themselves.&amp;#160; Nevertheless there is obviously some sort of relation present.&amp;#160; By convention, we call this relation a &lt;em&gt;smaller than&lt;/em&gt; \ &lt;em&gt;greater than&lt;/em&gt; relation.&amp;#160; Mammal[] is smaller than Animal[] because Mammal is more derived than Animal.&amp;#160; It is bigger than Tiger[] because Mammal is less derived than the type Tiger.&lt;/p&gt;

&lt;p&gt;It is worth repeating that &lt;em&gt;smaller&lt;/em&gt; and &lt;em&gt;bigger&lt;/em&gt; are not the same thing as the relation between classes in an inheritance hierarchy.&amp;#160; They also do not have anything directly to do with memory management.&amp;#160; They are pure metaphors.&lt;/p&gt;

&lt;p&gt;The C# classes above model concepts.&amp;#160; When we talk about concepts such as &lt;em&gt;animal&lt;/em&gt;, &lt;em&gt;mammal&lt;/em&gt; and &lt;em&gt;tiger&lt;/em&gt;, we talk about these concepts falling under each other.&amp;#160; Socrates falls under the concept of man.&amp;#160; Man falls under the concept of an animal (traditionally, man is defined as a bipedal, hairless animal that laughs; see &lt;a href="http://www.imaginativeuniversal.com/blog/Haecceity.aspx" target="_blank"&gt;Haecceity&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Metaphorically, we can think of animal as a bigger concept than mammal because many more things fall under animal than under mammal.&amp;#160; Tiger, in turn, is a smaller concept than mammal because so few things fall under it.&lt;/p&gt;

&lt;p&gt;Once we have &lt;em&gt;smaller than&lt;/em&gt; and &lt;em&gt;bigger than&lt;/em&gt; under our belts, we can start talking about covariance and contravariance.&amp;#160; Covariance and contravariance, at the most basic level, concerns the assignment of types to variables.&lt;/p&gt;

&lt;p&gt;An assignment is &lt;strong&gt;covariant&lt;/strong&gt; if we are assigning a &lt;em&gt;smaller&lt;/em&gt; type to a &lt;em&gt;bigger&lt;/em&gt; type:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.imaginativeuniversal.com/sleestack/CovarianceandContravarianceIn5Minutes_9BBB/covariance.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="covariance" border="0" alt="covariance" src="http://www.imaginativeuniversal.com/sleestack/CovarianceandContravarianceIn5Minutes_9BBB/covariance_thumb.png" width="244" height="95" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;When we assign a &lt;em&gt;bigger&lt;/em&gt; type to a &lt;em&gt;smaller&lt;/em&gt; type, the assignment is said to be &lt;strong&gt;contravariant:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.imaginativeuniversal.com/sleestack/CovarianceandContravarianceIn5Minutes_9BBB/contravariance.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="contravariance" border="0" alt="contravariance" src="http://www.imaginativeuniversal.com/sleestack/CovarianceandContravarianceIn5Minutes_9BBB/contravariance_thumb.png" width="244" height="92" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Covariance with simple reference types&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;An example will help to illustrate this.&amp;#160; &lt;/p&gt;

&lt;pre class="csharpcode"&gt;    Mammal m = &lt;span class="kwrd"&gt;new&lt;/span&gt; Tiger();
    Animal a = m;
    //Tiger t = a;  -- will not compile&lt;/pre&gt;

&lt;p&gt;We can assign a smaller type, Tiger to a variable allocated as a Mammal.&amp;#160; Similarly we can assign our Mammal instance to a variable allocated as an Animal.&amp;#160; In other words, in the assignment of simple reference types, we can assign smaller things to bigger things.&amp;#160; This is a &lt;strong&gt;covariant&lt;/strong&gt; relation.&lt;/p&gt;

&lt;p&gt;We cannot, however, assign an Animal instance to a Tiger.&amp;#160; The C# compiler just won’t let us do it, because it will not let us assign something bigger to something smaller in this case.&amp;#160; The assignment of simple reference types is therefore &lt;em&gt;not&lt;/em&gt; covariant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Covariance with arrays&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The C# compiler also happens to allow covariant array assignments.&amp;#160; For instance:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    Mammal[] M = &lt;span class="kwrd"&gt;new&lt;/span&gt; Tiger[0];
    Animal[] A = M;
    //Tiger[] t = A;  -- will not compile&lt;/pre&gt;

&lt;p&gt;The compiler doesn’t need to allow this.&amp;#160; It just happens to.&amp;#160; What’s interesting is that the compiler will not allow us to do the same thing with generic collections.&amp;#160; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Invariance with generics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Assignment of generics is &lt;strong&gt;invariant&lt;/strong&gt; in C# 3.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    &lt;span class="rem"&gt;// List&amp;lt;Mammal&amp;gt; mammals = new List&amp;lt;Tiger&amp;gt;(); -- will not compile&lt;/span&gt;
    &lt;span class="rem"&gt;// List&amp;lt;Animal&amp;gt; animals = mammals; -- will not compile&lt;/span&gt;
    &lt;span class="rem"&gt;// List&amp;lt;Tiger&amp;gt; tigers = animals;  -- will not compile&lt;/span&gt;
    //&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;4. Covariance with method parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Parameter assignment also happens to be covariant in C#.&amp;#160; To prove it to yourself, take the following static method:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TakeMammal(Mammal m){}&lt;/pre&gt;

&lt;p&gt;Which of the following operations is permissible in C# and which is not?&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    TakeMammal(&lt;span class="kwrd"&gt;new&lt;/span&gt; Tiger());

    TakeMammal(&lt;span class="kwrd"&gt;new&lt;/span&gt; Animal());

    TakeMammal(&lt;span class="kwrd"&gt;new&lt;/span&gt; Mammal());&lt;/pre&gt;

&lt;p&gt;(Note, however, that &lt;strong&gt;ref&lt;/strong&gt; and &lt;strong&gt;out&lt;/strong&gt; parameters are &lt;em&gt;invariant: &lt;a title="http://blogs.msdn.com/ericlippert/archive/2009/09/21/why-do-ref-and-out-parameters-not-allow-type-variation.aspx" href="http://blogs.msdn.com/ericlippert/archive/2009/09/21/why-do-ref-and-out-parameters-not-allow-type-variation.aspx"&gt;http://blogs.msdn.com/ericlippert/archive/2009/09/21/why-do-ref-and-out-parameters-not-allow-type-variation.aspx&lt;/a&gt; .)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Delegate contravariance with respect to inputs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Understanding this characteristic of parameter assignments is important in order to demonstrate how contravariance occurs in C#.&amp;#160; In C#, delegate assignments are contravariant with respect to inputs.&amp;#160; Consider this code:&lt;/p&gt;

&lt;pre class="csharpcode"&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TakeAnimal(Animal a) {}
 &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TakeMammal(Mammal m){}
 &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TakeTiger(Tiger t) {}

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;delegate&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; MammalHandler(Mammal m);

MammalHandler funcA = TakeAnimal; &lt;span class="rem"&gt;//OK&lt;/span&gt;
MammalHandler funcM = TakeMammal; &lt;span class="rem"&gt;//OK&lt;/span&gt;
MammalHandler funcT = TakeTiger;  &lt;span class="rem"&gt;//No!&lt;/span&gt;

            funcA(&lt;span class="kwrd"&gt;new&lt;/span&gt; Mammal()); &lt;span class="rem"&gt;//OK&lt;/span&gt;
            funcM(&lt;span class="kwrd"&gt;new&lt;/span&gt; Mammal()); &lt;span class="rem"&gt;//OK&lt;/span&gt;
            funcT(&lt;span class="kwrd"&gt;new&lt;/span&gt; Mammal()); &lt;span class="rem"&gt;//No!&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;The delegate method MammalHandler is designed to only take the Mammal type as input.&amp;#160; Any delegate instance – funcA, funcM, funcT – in turn may be passed Mammal objects.&amp;#160; If we pass a Mammal to delegate instance funcA, it ultimately gets passed to our TakeAnimal method.&amp;#160; Since parameter assignments – as we showed above – are covariant, passing a Mammal to TakeAnimal is permissible.&amp;#160; Obviously passing a Mammal to TakeMammal is also permissible.&lt;/p&gt;

&lt;p&gt;We cannot, however, pass a Mammal to TakeTiger.&amp;#160; The C# compiler does not allow this.&lt;/p&gt;

&lt;p&gt;Consequently, we also cannot assign TakeTiger to our MammalHandler delegate.&amp;#160; Assigning TakeTiger to funcT is illegal.&lt;/p&gt;

&lt;p&gt;But in this impermissible delegate assignment, which thing is &lt;em&gt;bigger&lt;/em&gt;: MammalHandler or TakeTiger?&amp;#160; MammalHandler, right?&amp;#160; With regard to delegate assignments, then, we are saying that assigning something smaller to something bigger is not allowed.&amp;#160; Assigning something bigger to something smaller, however, &lt;em&gt;is&lt;/em&gt; permissible.&lt;/p&gt;

&lt;p&gt;Delegate assignments like those above are therefore &lt;strong&gt;contravariant&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Delegate covariance with respect to return types&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I say “like those above” because this is actually true only with respect to delegate inputs.&amp;#160; Delegates can also, of course, return objects – and when they do, this is a covariant relation.&amp;#160; &lt;strong&gt;Delegate assignments are said to be contravariant with respect to inputs, but covariant with respect to return values&lt;/strong&gt;.&amp;#160; You can prove this to yourself by looking through the following code in which the delegate signature has a return value but no parameters.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;p&gt;&lt;span class="kwrd"&gt; public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Animal GetAnimal() {}
 &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Mammal GetMammal(){}
 &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Tiger GetTiger() {}

&lt;span class="kwrd"&gt; public&lt;/span&gt; &lt;span class="kwrd"&gt;delegate&lt;/span&gt; Mammal GetMammalDelegate();

 GetMammalDelegate funcA = GetAnimal;  &lt;span class="rem"&gt;// No!&lt;/span&gt;
 GetMammalDelegate funcM = GetMammal;  &lt;span class="rem"&gt;// OK&lt;/span&gt;
 GetMammalDelegate funcT = GetTiger; &lt;span class="rem"&gt;// OK&lt;/span&gt;
&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;So why is this important for understanding C# 4.0?&amp;#160; As we briefly covered above, C# 3 has this peculiar characteristic in that the compiler treats array assignments as covariant operations, but treats the generic assignment of List&amp;lt;T&amp;gt; as an invariant operation. This is obviously a little weird.&amp;#160; In C# 4.0, there will be support for covariance and contravariance in generic interfaces which will allow us to specify how we want our generics to behave – for instance, a special kind of covariant IEnumerable&amp;lt;out T&amp;gt; could be implemented that would provide the sort of covariance now supported for arrays.&lt;/p&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=12363" width="1" height="1"&gt;</description></item><item><title>A Lazier Singleton with .NET 4.0</title><link>http://blog.magenic.com/blogs/jamesa/archive/2009/10/01/A-Lazier-Singleton-with-.NET-4.0.aspx</link><pubDate>Thu, 01 Oct 2009 23:15:00 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:11802</guid><dc:creator>Anonymous</dc:creator><slash:comments>836</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/11802.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=11802</wfw:commentRss><description>&lt;p&gt;I will ignore for the moment the common jeremiads against the Singleton pattern and the reports made by some latter-day design pattern nihilists that the Singleton is dead.&amp;nbsp;&amp;nbsp; I do not mean to imply that &lt;a href="http://steve.yegge.googlepages.com/singleton-considered-stupid" target="_blank"&gt;they&lt;/a&gt; are wrong &amp;ndash; it&amp;rsquo;s just that it galls me that the Singleton pattern should be the object of such scorn and ridicule when the Flyweight is allowed to go along its merry way.&lt;/p&gt;&lt;p&gt;Besides which, the Singleton and the Facade are the only patterns I can write from memory and without a lot of research, so I love &amp;lsquo;em.&lt;/p&gt;&lt;p&gt;The best source for design patterns in C# is probably Judith Bishop&amp;rsquo;s &lt;a href="http://www.amazon.com/3-0-Design-Patterns-Judith-Bishop/dp/059652773X/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1254433019&amp;amp;sr=8-1" target="_blank"&gt;C# 3.0 Design Patterns&lt;/a&gt; published by O&amp;rsquo;Reilly Press, which provides C# versions of all &lt;a href="http://www.imaginativeuniversal.com/blog/WhatIsServiceOrientedArchitecture.aspx" target="_blank"&gt;23&lt;/a&gt; patterns from the Gang of Four&amp;rsquo;s &lt;a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612" target="_blank"&gt;Elements of Reusable Object-Oriented Software&lt;/a&gt;.&amp;nbsp; The elegant implementation of the Singleton pattern she recommends looks like this:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;sealed&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Singleton {
   &lt;span class="rem"&gt;// Private Constructor&lt;/span&gt;
   Singleton( ) { }

   &lt;span class="rem"&gt;// Private object instantiated with private constructor&lt;/span&gt;
   &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; Singleton instance = &lt;span class="kwrd"&gt;new&lt;/span&gt; Singleton( );

   &lt;span class="rem"&gt;// Public static property to get the object&lt;/span&gt;
   &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Singleton Instance {
          get { &lt;span class="kwrd"&gt;return&lt;/span&gt; instance;}
       }
}&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;There is a problem with this, however.&amp;nbsp; Because of the way classes with static methods work in C# (or in this case, a static property), type instantiation of the private Singleton field &lt;strong&gt;instance&lt;/strong&gt; happens at an unexpected point.&amp;nbsp; For an interesting if somewhat dense read on the effect of the &lt;em&gt;beforeFieldInit&lt;/em&gt; flag, go &lt;a href="http://dotnetsolutions-technicalsolutions.blogspot.com/2008/01/c-and-beforefieldinit.html" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I will simply demonstrate the problem by adding some tracking code to Judith Bishop&amp;rsquo;s recommended implementation:&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;sealed&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Singleton
    {
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; Singleton instance = &lt;span class="kwrd"&gt;new&lt;/span&gt; Singleton();
        &lt;span class="kwrd"&gt;private&lt;/span&gt; Singleton()
        {
            &lt;span class="rem"&gt;// no default constructor&lt;/span&gt;
            Console.WriteLine(&lt;span class="str"&gt;&amp;quot; &amp;gt;&amp;gt; singleton initialized&amp;quot;&lt;/span&gt;);
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Singleton Instance
        {
            get
            {
                Console.WriteLine(&lt;span class="str"&gt;&amp;quot;before singleton retrieval&amp;quot;&lt;/span&gt;);
                &lt;span class="kwrd"&gt;return&lt;/span&gt; instance;

            }
        }
    }&lt;/pre&gt;&lt;p&gt;I will retrieve an instance of this &lt;strong&gt;Singleton&lt;/strong&gt; class from a console application like so:&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;class&lt;/span&gt; Program
    {
        &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)
        {

            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Calling Singleton instance&amp;quot;&lt;/span&gt;);
            var s = Singleton.Instance;
            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Finished calling Singleton instance&amp;quot;&lt;/span&gt;);
            Console.ReadLine();
        }
    }&lt;/pre&gt;When will the private type be initialized? When will the private constructor be called?&amp;nbsp; In what order do you think the Console.WriteLines will be invoked? &lt;p&gt;Ideally the static members of this class would be initialized only when we needed them, and the output would be:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Calling Singleton instance &lt;/li&gt;&lt;li&gt;before singleton retrieval &lt;/li&gt;&lt;li&gt;&amp;gt;&amp;gt; singleton initialized &lt;/li&gt;&lt;li&gt;Finished calling Singleton instance &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;In actuality, however, this is the result:&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.imaginativeuniversal.com/sleestack/ALazierSingletonwith.NET4.0_10599/singlton_results_1.png"&gt;&lt;img alt="singlton_results_1" border="0" height="99" src="http://www.imaginativeuniversal.com/sleestack/ALazierSingletonwith.NET4.0_10599/singlton_results_1_thumb.png" style="display:inline;border-width:0px;" title="singlton_results_1" width="320" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;em&gt;This is not so bad&lt;/em&gt;, you may be thinking.&amp;nbsp; If our singleton is a large object this creates some additional strain to the system &amp;ndash; but as long as the Singleton instance gets used fairly soon after it is instantiated it&amp;rsquo;s no big deal.&lt;/p&gt;&lt;p&gt;However, what if I come in after you have coded the singleton and decide to add another static method to your class -- not understanding the intricate details of &lt;em&gt;beforeFieldInit &amp;ndash;&lt;/em&gt; like this:&lt;/p&gt;&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Test()
        {
            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;testing singleton&amp;quot;&lt;/span&gt;);
        }&lt;/pre&gt;&lt;p&gt;and rewrote the calling code like this:&lt;/p&gt;&lt;pre class="csharpcode"&gt;            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Calling Singleton test method&amp;quot;&lt;/span&gt;);
            Singleton.Test();
            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Calling Singleton instance&amp;quot;&lt;/span&gt;);
            var s = Singleton.Instance;
            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Finished calling Singleton instance&amp;quot;&lt;/span&gt;);
            Console.ReadLine();&lt;/pre&gt;&lt;p&gt;It may not be immediately obvious but I have seriously messed up your code.&amp;nbsp; Here is the output:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.imaginativeuniversal.com/sleestack/ALazierSingletonwith.NET4.0_10599/singlton_results_2.png"&gt;&lt;img alt="singlton_results_2" border="0" height="99" src="http://www.imaginativeuniversal.com/sleestack/ALazierSingletonwith.NET4.0_10599/singlton_results_2_thumb.png" style="display:inline;border-width:0px;" title="singlton_results_2" width="313" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;Even if we never retrieve the Singleton instance, it will still be initialized when any other static method on our type is called &amp;ndash; this is commonly known as a language runtime bummer.&lt;/p&gt;&lt;p&gt;.NET 4.0 introduces a new generic type called &lt;strong&gt;Lazy&lt;/strong&gt; which helps us out of this dilemma.&amp;nbsp; &lt;strong&gt;Lazy&lt;/strong&gt; is a wrapper class that facilitates thread safe, lazy instantiation of objects.&amp;nbsp; We can use it to create a new Singleton implementation that replaces the private static &lt;strong&gt;Singleton&lt;/strong&gt; instance with a private static &lt;strong&gt;Lazy&amp;lt;Singleton&amp;gt;&lt;/strong&gt;&amp;nbsp; instance.&amp;nbsp; The Instance property will also require a small rewrite to pull our Singleton out of the Lazy wrapper.&lt;/p&gt;&lt;p&gt;The full implementation of the lazy version of the singleton looks like this:&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;sealed&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; LazySingleton
    {
        &lt;span class="rem"&gt;// Private object with lazy instantiation&lt;/span&gt;
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; Lazy&amp;lt;LazySingleton&amp;gt; instance = 
            &lt;span class="kwrd"&gt;new&lt;/span&gt; Lazy&amp;lt;LazySingleton&amp;gt;(
                &lt;span class="kwrd"&gt;delegate&lt;/span&gt; { 
                    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; LazySingleton(); 
                }
                &lt;span class="rem"&gt;//thread safety first&lt;/span&gt;
                ,LazyExecutionMode.EnsureSingleThreadSafeExecution);

        &lt;span class="kwrd"&gt;private&lt;/span&gt; LazySingleton()
        {
           &lt;span class="rem"&gt;// no public default constructor&lt;/span&gt;
        }

        &lt;span class="rem"&gt;// static instance property&lt;/span&gt;
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; LazySingleton Instance
        {
            get{ &lt;span class="kwrd"&gt;return&lt;/span&gt; instance.Value; }
        }
    }&lt;/pre&gt;&lt;p&gt;Some things of note:&lt;/p&gt;&lt;p&gt;1. I pass a delegate as the first parameter to the &lt;strong&gt;Lazy&lt;/strong&gt; constructor. There is a no parameter constructor for the generic Lazy&amp;lt;T&amp;gt; class, but it requires that type &lt;strong&gt;T&lt;/strong&gt; have a public default constructor &amp;ndash; which I obviously do not want to provide.&amp;nbsp; The delegate parameter allows me to indicate that I want to use a different constructor &amp;ndash; in order to pass a constructor parameter to Type &lt;strong&gt;T&lt;/strong&gt;, for instance, or to invoke a private constructor, in this case &amp;ndash; than the default.&amp;nbsp; &lt;/p&gt;&lt;p&gt;2. The second parameter, also optional, tells the Lazy instance that I want the lazy instantiation of type &lt;strong&gt;T&lt;/strong&gt; to be thread safe.&lt;/p&gt;&lt;p&gt;3. I retrieve the wrapped type T by asking for the Lazy type&amp;rsquo;s &lt;em&gt;Value&lt;/em&gt; property.&lt;/p&gt;&lt;p&gt;Now it&amp;rsquo;s time for a contest. I add some Console.WriteLine statements as in the original and I append the malicious static Test() method as in the original.&amp;nbsp; I rewrite my Console app code to call my original Singleton code and then the new and improved -- .NET 4.0 enhanced -- Lazy Singleton code: &lt;/p&gt;&lt;pre class="csharpcode"&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Calling Singleton test method&amp;quot;&lt;/span&gt;);
    Singleton.Test();
    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Calling Singleton instance&amp;quot;&lt;/span&gt;);
    var s = Singleton.Instance;
    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Finished calling Singleton instance&amp;quot;&lt;/span&gt;);
    Console.WriteLine();

    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Calling Lazy Singleton test method&amp;quot;&lt;/span&gt;);
    LazySingleton.Test();
    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Calling Lazy Singleton instance&amp;quot;&lt;/span&gt;);
    var lazyS = LazySingleton.Instance;
    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Finished calling Lazy Singleton instance&amp;quot;&lt;/span&gt;);
    Console.ReadLine();&lt;/pre&gt;&lt;p&gt;and get the following, very pleasing, results:&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.imaginativeuniversal.com/sleestack/ALazierSingletonwith.NET4.0_10599/singlton_results_3.png"&gt;&lt;img alt="singlton_results_3" border="0" height="165" src="http://www.imaginativeuniversal.com/sleestack/ALazierSingletonwith.NET4.0_10599/singlton_results_3_thumb.png" style="display:inline;border-width:0px;" title="singlton_results_3" width="349" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;Now that&amp;rsquo;s lazy!&lt;/p&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=11802" width="1" height="1"&gt;</description><category domain="http://blog.magenic.com/blogs/jamesa/archive/tags/.NET+4.0/default.aspx">.NET 4.0</category></item><item><title>Synchronizing Style Hierarchies with Control Hierarchies in WPF</title><link>http://blog.magenic.com/blogs/jamesa/archive/2009/07/12/Synchronizing-Style-Hierarchies-with-Control-Hierarchies-in-WPF.aspx</link><pubDate>Sun, 12 Jul 2009 22:00:15 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:10193</guid><dc:creator>Anonymous</dc:creator><slash:comments>0</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/10193.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=10193</wfw:commentRss><description>&lt;p&gt;WPF provides two ways to apply styles to control elements: by name and by type.&amp;#160; In the typical named style implementation, one declares both the name by which a style can be referenced as well as the control type to which it can be applied.&amp;#160; For instance, a style declaration for a ComboBox would look like this:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Style&lt;/span&gt; &lt;span class="attr"&gt;x:Key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;ComboBoxStyle&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;TargetType&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;ComboBox&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    ...
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Style&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

&lt;p&gt;When styles are applied in this way, the underlying WPF rendering mechanism understands type hierarchies.&amp;#160; Consequently, this style could also be written with a TargetType higher up in the Control type hierarchy and still work:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Style&lt;/span&gt; &lt;span class="attr"&gt;x:Key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;ComboBoxStyle&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;TargetType&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Control&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
   ...
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Style&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;This is a handy feature when you want to build a custom control but want to preserve your styles.&amp;#160; For instance, the ComboBox control has no built-in ability to trigger commands.&amp;#160; If you want to use MVVM, however, this is quite a shortcoming.&amp;#160; You can overcome this problem by building a custom control based on the ComboBox type and implementing the ICommandSource interface to pick up the SelectionChanged event:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; CustomComboBox: ComboBox, ICommandSource
{
     ...
}&lt;/pre&gt;

&lt;p&gt;Since my CustomComboBox inherits from the WPF ComboBox, the named style I use with a TargetType of ComboBox will automatically be applied to it and the following XAML:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Window&lt;/span&gt; &lt;span class="attr"&gt;x:Class&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;SampleWPFProject.Window1&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:x&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:sys&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;clr-namespace:System;assembly=System&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:custom&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;clr-namespace:SampleWPFProject&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;Title&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Window1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Grid&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Grid.RowDefinitions&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RowDefinition&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;25&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RowDefinition&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;25&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Grid.RowDefinitions&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt; &lt;span class="attr"&gt;Grid&lt;/span&gt;.&lt;span class="attr"&gt;Row&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;stackPanel1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Orientation&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Horizontal&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TextBlock&lt;/span&gt; &lt;span class="attr"&gt;Margin&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0,0,10,0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;60&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Employees&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;TextBlock&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ComboBox&lt;/span&gt; &lt;span class="attr"&gt;x:Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;cbEmployees&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;SelectedIndex&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;200&amp;quot;&lt;/span&gt; 
                  &lt;span class="attr"&gt;Style&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{StaticResource ComboBoxStyle}&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ComboBoxItem&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;John Adams&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ComboBoxItem&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ComboBoxItem&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Ben Franklin&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ComboBoxItem&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ComboBoxItem&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Pat Henry&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ComboBoxItem&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ComboBox&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt; &lt;span class="attr"&gt;Grid&lt;/span&gt;.&lt;span class="attr"&gt;Row&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;stackPanel2&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Orientation&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Horizontal&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TextBlock&lt;/span&gt; &lt;span class="attr"&gt;Margin&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0,0,10,0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;60&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Tasks:&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;TextBlock&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;custom:CustomComboBox&lt;/span&gt; &lt;span class="attr"&gt;x:Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;cbTasks&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;SelectedIndex&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;200&amp;quot;&lt;/span&gt; 
                   &lt;span class="attr"&gt;Style&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{StaticResource ComboBoxStyle}&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ComboBoxItem&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Write Constitution&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ComboBoxItem&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ComboBoxItem&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Write Declaration&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ComboBoxItem&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ComboBoxItem&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Go for a ride&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ComboBoxItem&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;custom:CustomComboBox&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Grid&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Window&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }will fortuitously render itself such that both the base ComboBox as well as the CustomComboBox receive the style specified in the “ComboBoxStyle” style definition.&lt;/p&gt;

&lt;p&gt;But what if I want to apply my custom style arbitrarily to all ComboBoxes in my application?&amp;#160; This is where typed styles are very handy.&lt;/p&gt;

&lt;p&gt;I can change the “key” element of the ComboBoxStyle to apply it generically to all ComboBoxes like this:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Style&lt;/span&gt; &lt;span class="attr"&gt;x:Key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{x:Type ComboBox}&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;TargetType&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;ComboBox&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
   ...
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Style&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }Inside my XAML, I would simply remove the reference to the named style:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ComboBox&lt;/span&gt; &lt;span class="attr"&gt;x:Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;cbEmployees&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;SelectedIndex&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;200&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
   ...
&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;custom:CustomComboBox&lt;/span&gt; &lt;span class="attr"&gt;x:Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;cbTasks&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;SelectedIndex&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;200&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

&lt;p&gt;Unfortunately, the typed style does not understand that my CustomComboBox inherits from the ComboBox type. While the base ComboBox is rendered with my style,&amp;#160; the appearance of the CustomComboBox reverts to the default ComboBox specified by WPF for my OS. &lt;/p&gt;

&lt;p&gt;I could simply copy the entire original style and create a new one that specifies the CustomComboBox as the key, instead.&amp;#160; There is a shorter way, however.&amp;#160; I can take advantage of the BasedOn attribute of the style resource.&amp;#160; Rather than copy the entire style, I will create a new style based the original style and set the key to our custom type:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&amp;lt;Style x:Key=&lt;span class="str"&gt;&amp;quot;{x:Type ComboBox}&amp;quot;&lt;/span&gt; TargetType=&lt;span class="str"&gt;&amp;quot;ComboBox&amp;quot;&lt;/span&gt;&amp;gt;
   ...
&amp;lt;/Style&amp;gt;

&amp;lt;Style BasedOn=&lt;span class="str"&gt;&amp;quot;{StaticResource {x:Type ComboBox}}&amp;quot;&lt;/span&gt;  
       x:Key=&lt;span class="str"&gt;&amp;quot;{x:Type custom:CustomComboBox}&amp;quot;&lt;/span&gt; 
       TargetType=&lt;span class="str"&gt;&amp;quot;ComboBox&amp;quot;&lt;/span&gt;/&amp;gt;&lt;/pre&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

&lt;p&gt;Typically the BasedOn attribute is used to extend a certain base style with certain changes: for instance, off of a base style that sets&amp;#160; Button backgrounds to blue, one might want to create another that overrides the background color and set it to orange.&lt;/p&gt;

&lt;p&gt;This example shows that it can be used in a rather different way, however, to take a pre-existing typed style and apply it to a different type.&amp;#160; In this particular case, it is being used to align custom styles that are part of an inheritance hierarchy with custom controls that are part of a related type hierarchy.&lt;/p&gt;

&lt;p&gt;Should it become necessary to extend the CustomComboBox control with a new custom control, in turn, one should be prepared to similarly extend the style hierarchy using the BasedOn attribute in order to maintain synchronization between one’s presentation and one’s functionality.&lt;/p&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=10193" width="1" height="1"&gt;</description></item><item><title>Alternatives to returning Void: Continued</title><link>http://blog.magenic.com/blogs/jamesa/archive/2009/04/19/Alternatives-to-returning-Void_3A00_-Continued.aspx</link><pubDate>Sun, 19 Apr 2009 03:40:27 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:9143</guid><dc:creator>Anonymous</dc:creator><slash:comments>3</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/9143.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=9143</wfw:commentRss><description>&lt;p&gt;&lt;em&gt;“If you look long enough into the void the void begins to look back through you.&amp;quot; – Nietzsche&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Returning types rather than void on methods that do not necessarily require a return value, as occurs in the implementation of the &lt;strong&gt;&lt;em&gt;Append&lt;/em&gt;&lt;/strong&gt; methods on the &lt;strong&gt;StringBuilder&lt;/strong&gt;, allows us to do some interesting method chaining in our code.&lt;/p&gt;  &lt;p&gt;Bill Wagner suggests doing something similar with collections in &lt;a href="http://www.amazon.com/More-Effective-Specific-Software-Development/dp/0321485890" target="_blank"&gt;More Effective C#&lt;/a&gt; .&amp;#160; My examples are a bit more contrived, however.&lt;/p&gt;  &lt;p&gt;Suppose – for the sake of the premise if for nothing else – that we have a business requirement to take a decimal collection of prices and then add 6 percent to each collection member.&amp;#160; We could write the following custom collection to do this:&lt;/p&gt;  &lt;div style="font-family:courier new;background:white;color:black;font-size:10pt;"&gt;   &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Prices&lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;decimal&lt;/span&gt;&amp;gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;decimal&lt;/span&gt;&amp;gt; _mySequence;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; Prices()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _mySequence = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;decimal&lt;/span&gt;&amp;gt;();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Prices&lt;/span&gt; Add(&lt;span style="color:blue;"&gt;decimal&lt;/span&gt; d)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _mySequence.Add(d);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;this&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IEnumerator&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;decimal&lt;/span&gt;&amp;gt; GetEnumerator()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color:blue;"&gt;decimal&lt;/span&gt; d &lt;span style="color:blue;"&gt;in&lt;/span&gt; _mySequence)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;yield&lt;/span&gt; &lt;span style="color:blue;"&gt;return&lt;/span&gt; d;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;IEnumerator&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;.GetEnumerator()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color:blue;"&gt;decimal&lt;/span&gt; d &lt;span style="color:blue;"&gt;in&lt;/span&gt; _mySequence)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;yield&lt;/span&gt; &lt;span style="color:blue;"&gt;return&lt;/span&gt; d;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Prices&lt;/span&gt; AddSixPercentAndWrite()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt;(&lt;span style="color:blue;"&gt;decimal&lt;/span&gt; d &lt;span style="color:blue;"&gt;in&lt;/span&gt; _mySequence)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:blue;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#a31515;"&gt;&amp;quot;{0:C}&amp;quot;&lt;/span&gt;,d * 1.06m));&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;this&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Which we would then call thus: &lt;/p&gt;

&lt;div style="font-family:courier new;background:white;color:black;font-size:10pt;"&gt;
  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;var&lt;/span&gt; prices = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Prices&lt;/span&gt;();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;for&lt;/span&gt;(&lt;span style="color:blue;"&gt;decimal&lt;/span&gt; d = 0; d&amp;lt; 20m;d++)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; prices.Add(d);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; prices.AddSixPercentAndWrite();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The business is initially happy with this, but then comes back a week later to say that the six percent tax is nine percent in a different store. Additionally, while sometimes the business wants to see the final price, they also sometimes want to see the original price alongside of it.&amp;#160; &lt;/p&gt;

&lt;p&gt;Besides our original output, we now also need to be able to push a list that looks something like this:&lt;/p&gt;

&lt;div style="width:600px;font-family:courier new;background:lightgray;color:black;font-size:10pt;"&gt;
  &lt;p&gt;$0.00 $0.00 
    &lt;br /&gt;$1.00 $1.06 

    &lt;br /&gt;$2.00 $2.12 

    &lt;br /&gt;$3.00 $3.18 

    &lt;br /&gt;$4.00 $4.24 

    &lt;br /&gt;$5.00 $5.30 

    &lt;br /&gt;$6.00 $6.36 

    &lt;br /&gt;$7.00 $7.42 

    &lt;br /&gt;$8.00 $8.48 

    &lt;br /&gt;$9.00 $9.54 

    &lt;br /&gt;$10.00 $10.60 

    &lt;br /&gt;$11.00 $11.66 

    &lt;br /&gt;$12.00 $12.72 

    &lt;br /&gt;. . .&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Seeing where this is headed, we realize that to handle all foreseen and unforeseen scenarios, we should come up with a way to chain up our methods in order to make the code more flexible.&lt;/p&gt;

&lt;p&gt;We could restructure the &lt;strong&gt;&lt;em&gt;AddSixPercent&lt;/em&gt;&lt;/strong&gt; method to take a parameter; we could then break out the &lt;strong&gt;&lt;em&gt;Write&lt;/em&gt;&lt;/strong&gt; method so we can call it multiple times if needed.&amp;#160; We could also change the signatures on our methods to return our Prices collection instead of &lt;strong&gt;void&lt;/strong&gt;, allowing us to chain the methods together.&lt;/p&gt;

&lt;p&gt;There’s a hitch, however.&amp;#160; While returning Prices would allow us to do some chaining, we still wouldn’t get the right results since each method would iterate through the whole collection before returning.&amp;#160; Consequently we would end up printing out all the items in the first column before getting around to printing the items in the second column (the calculated cost with tax), which isn’t what we want at all.&lt;/p&gt;

&lt;div style="width:600px;font-family:courier new;background:lightgray;color:black;font-size:10pt;"&gt;
  &lt;p&gt;. . . 
    &lt;br /&gt;$12.00 

    &lt;br /&gt;$13.00 

    &lt;br /&gt;$14.00 

    &lt;br /&gt;$15.00 

    &lt;br /&gt;$16.00 

    &lt;br /&gt;$17.00 

    &lt;br /&gt;$18.00 

    &lt;br /&gt;$19.00 

    &lt;br /&gt;$0.00 

    &lt;br /&gt;$1.06 

    &lt;br /&gt;$2.12 

    &lt;br /&gt;$3.18 

    &lt;br /&gt;$4.24 

    &lt;br /&gt;$5.30 

    &lt;br /&gt;$6.36 

    &lt;br /&gt;$7.42 

    &lt;br /&gt;$8.48 

    &lt;br /&gt;$9.54 

    &lt;br /&gt;$10.60 

    &lt;br /&gt;$11.66 

    &lt;br /&gt;$12.72 

    &lt;br /&gt;. . .&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;By using iterators, on the other hand, every method in our chain would act on a particular iteration rather than on the whole sequence.&amp;#160; Besides getting the output that we want, this would also happily give us much more efficient code since we only have to iterate through our collection once rather than once per chained method call.&lt;/p&gt;

&lt;p&gt;If we are to use iterators, however, we can’t return the &lt;strong&gt;Prices&lt;/strong&gt; type.&amp;#160; Instead we have to return an IEnumerable type.&amp;#160; Leaving the rest of our Prices custom collection class alone, here’s what that new code would look like:&lt;/p&gt;

&lt;div style="font-family:courier new;background:white;color:black;font-size:10pt;"&gt;
  &lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;decimal&lt;/span&gt;&amp;gt; AddXPercent(&lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;decimal&lt;/span&gt;&amp;gt; sequence&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; , &lt;span style="color:blue;"&gt;short&lt;/span&gt; percent)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;{&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color:blue;"&gt;decimal&lt;/span&gt; d &lt;span style="color:blue;"&gt;in&lt;/span&gt; sequence)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;yield&lt;/span&gt; &lt;span style="color:blue;"&gt;return&lt;/span&gt; d + (d * percent * .01m);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;}&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;decimal&lt;/span&gt;&amp;gt; WriteToConsole(&lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;decimal&lt;/span&gt;&amp;gt; sequence)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;{&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color:blue;"&gt;decimal&lt;/span&gt; d &lt;span style="color:blue;"&gt;in&lt;/span&gt; sequence)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.Write(&lt;span style="color:blue;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#a31515;"&gt;&amp;quot;{0:C} &amp;quot;&lt;/span&gt;, d));&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;yield&lt;/span&gt; &lt;span style="color:blue;"&gt;return&lt;/span&gt; d;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Our calling code, in turn, would look like this:&lt;/p&gt;

&lt;div style="font-family:courier new;background:white;color:black;font-size:10pt;"&gt;
  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color:blue;"&gt;decimal&lt;/span&gt; d &lt;span style="color:blue;"&gt;in&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Prices&lt;/span&gt;.WriteToConsole(&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;Prices&lt;/span&gt;.AddXPercent(&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;Prices&lt;/span&gt;.WriteToConsole(&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; prices), 6)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; )&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; )&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;We’ve managed to achieve chaining, but not so elegantly, all things considered.&amp;#160; First, we have to include the name of our Type in order to chain our methods together.&amp;#160; Second, the chaining is done with nested methods instead of the clean &lt;strong&gt;With&lt;/strong&gt;-like syntax I was extolling in the &lt;a href="http://www.imaginativeuniversal.com/blog/Default.aspx#aedaeac53-e24c-420b-9768-35597b324f01" target="_blank"&gt;previous&lt;/a&gt; post.&amp;#160; Finally, the sequence of activity isn’t particularly clear.&amp;#160; Because we are chaining our methods by using nesting, the innermost nested method occurs first, while the first shall be processed last.&lt;/p&gt;

&lt;p&gt;Fortunately extension methods allow us to alter the way our methods are called.&amp;#160; In order to get the sort of syntax we want, we just need to pull our iterator methods into an extension methods class like so:&lt;/p&gt;

&lt;div style="font-family:courier new;background:white;color:black;font-size:10pt;"&gt;
  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;PricesExtension&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;decimal&lt;/span&gt;&amp;gt; AddXPercent(&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;this&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;decimal&lt;/span&gt;&amp;gt; sequence&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; , &lt;span style="color:blue;"&gt;short&lt;/span&gt; percent&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ) &lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color:blue;"&gt;decimal&lt;/span&gt; d &lt;span style="color:blue;"&gt;in&lt;/span&gt; sequence)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;yield&lt;/span&gt; &lt;span style="color:blue;"&gt;return&lt;/span&gt; d + (d * percent * .01m);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;decimal&lt;/span&gt;&amp;gt; WriteToConsole(&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;this&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;decimal&lt;/span&gt;&amp;gt; sequence&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; )&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color:blue;"&gt;decimal&lt;/span&gt; d &lt;span style="color:blue;"&gt;in&lt;/span&gt; sequence)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.Write(&lt;span style="color:blue;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#a31515;"&gt;&amp;quot;{0:C} &amp;quot;&lt;/span&gt;, d));&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;yield&lt;/span&gt; &lt;span style="color:blue;"&gt;return&lt;/span&gt; d;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Giving us the results we were looking for:&lt;/p&gt;

&lt;div style="width:600px;font-family:courier new;background:lightgray;color:black;font-size:10pt;"&gt;
  &lt;p&gt;$0.00 $0.00 
    &lt;br /&gt;$1.00 $1.06 

    &lt;br /&gt;$2.00 $2.12 

    &lt;br /&gt;$3.00 $3.18 

    &lt;br /&gt;$4.00 $4.24 

    &lt;br /&gt;$5.00 $5.30 

    &lt;br /&gt;$6.00 $6.36 

    &lt;br /&gt;$7.00 $7.42 

    &lt;br /&gt;$8.00 $8.48 

    &lt;br /&gt;$9.00 $9.54 

    &lt;br /&gt;$10.00 $10.60 

    &lt;br /&gt;$11.00 $11.66 

    &lt;br /&gt;$12.00 $12.72 

    &lt;br /&gt;. . .&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;We can now call our code like this:&lt;/p&gt;

&lt;div style="font-family:courier new;background:white;color:black;font-size:10pt;"&gt;
  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt;(&lt;span style="color:blue;"&gt;var&lt;/span&gt; d &lt;span style="color:blue;"&gt;in&lt;/span&gt; prices&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .WriteToConsole()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .AddXPercent(6)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .WriteToConsole()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; )&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine();&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This alternative to returning void involves three tricks:&lt;/p&gt;

&lt;p&gt;1) Returning an IEnumerable type instead of void.&lt;/p&gt;

&lt;p&gt;2) Taking an IEnumerable type as a parameter.&lt;/p&gt;

&lt;p&gt;3) Using these signatures in extension methods rather than the custom collection class itself.&lt;/p&gt;

&lt;p&gt;If the syntax looks familiar, this is because this is also how LINQ to Objects is implemented.&amp;#160; For that very reason, we could have accomplished similar results by using LINQ:&lt;/p&gt;

&lt;div style="font-family:courier new;background:white;color:black;font-size:10pt;"&gt;
  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt;(&lt;span style="color:blue;"&gt;var&lt;/span&gt; d &lt;span style="color:blue;"&gt;in&lt;/span&gt; prices&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Select(d =&amp;gt; { &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.Write(&lt;span style="color:blue;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#a31515;"&gt;&amp;quot;{0:C} &amp;quot;&lt;/span&gt;, d)); &lt;span style="color:blue;"&gt;return&lt;/span&gt; d; })&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Select(d =&amp;gt; d + (d * 6 * .01m))&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Select(d =&amp;gt; { &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.Write(&lt;span style="color:blue;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#a31515;"&gt;&amp;quot;{0:C} &amp;quot;&lt;/span&gt;, d)); &lt;span style="color:blue;"&gt;return&lt;/span&gt; d; })&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; )&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;It’s funky code, no doubt, but I also find it highly compelling.&amp;#160; I know that as I loop through my prices, I am writing out the original price, I add 6 percent to it in the following line, then I write out that result in the final line.&amp;#160; Inside the foreach block, I then perform any follow-up operations: in this case, writing a new line.&lt;/p&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=9143" width="1" height="1"&gt;</description></item><item><title>Alternatives to returning Void</title><link>http://blog.magenic.com/blogs/jamesa/archive/2009/04/19/Alternatives-to-returning-Void.aspx</link><pubDate>Sun, 19 Apr 2009 03:39:58 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:9142</guid><dc:creator>Anonymous</dc:creator><slash:comments>0</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/9142.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=9142</wfw:commentRss><description>&lt;p&gt;I was playing with the Unity Framework recently when I came across the following C# &lt;a href="http://msdn.microsoft.com/en-us/library/dd203147.aspx" target="_blank"&gt;code sample&lt;/a&gt; on msdn:&lt;/p&gt;  &lt;div style="font-family:courier new;background:white;color:black;font-size:10pt;"&gt;   &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;IUnityContainer&lt;/span&gt; uContainer = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;UnityContainer&lt;/span&gt;()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .RegisterType&amp;lt;&lt;span style="color:#2b91af;"&gt;IMyInterface&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;FirstObject&lt;/span&gt;&amp;gt;()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .RegisterType&amp;lt;&lt;span style="color:#2b91af;"&gt;MyBaseClass&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;SecondObject&lt;/span&gt;&amp;gt;();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;MyObject&lt;/span&gt; myInstance = uContainer.Resolve&amp;lt;&lt;span style="color:#2b91af;"&gt;MyObject&lt;/span&gt;&amp;gt;();&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This looked so much like the VB &lt;strong&gt;&lt;em&gt;With&lt;/em&gt;&lt;/strong&gt; syntax that I uncharitably assumed that the authors at MSDN had somehow confused C# and VB.&amp;#160; After all, they had written this the standard C# syntax &lt;a href="http://msdn.microsoft.com/en-us/library/dd203172.aspx" target="_blank"&gt;elsewhere&lt;/a&gt;:&lt;/p&gt;

&lt;div style="font-family:courier new;background:white;color:black;font-size:10pt;"&gt;
  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:green;"&gt;// Create container and register types&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;IUnityContainer&lt;/span&gt; myContainer = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;UnityContainer&lt;/span&gt;();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; myContainer.RegisterType&amp;lt;&lt;span style="color:#2b91af;"&gt;IMyService&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;DataService&lt;/span&gt;&amp;gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Data&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; myContainer.RegisterType&amp;lt;&lt;span style="color:#2b91af;"&gt;IMyService&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;LoggingService&lt;/span&gt;&amp;gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Logging&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:green;"&gt;// Retrieve an instance of each type&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;IMyService&lt;/span&gt; myDataService = myContainer.Resolve&amp;lt;&lt;span style="color:#2b91af;"&gt;IMyService&lt;/span&gt;&amp;gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Data&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;IMyService&lt;/span&gt; myLoggingService = myContainer.Resolve&amp;lt;&lt;span style="color:#2b91af;"&gt;IMyService&lt;/span&gt;&amp;gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Logging&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;C# developers with more than 8 or so years of experience can generally be broken down into two types who are mutually suspicious of one another: those who came up through the VB6 programming ranks and those who came up through C++ or Java.&amp;#160; I did the former, and for the most part have never looked back.&amp;#160; I don’t even get involved in disputes between C# lovers and VB lovers.&amp;#160; They’re both nice language.&amp;#160; I just happen to use the former for most things.&lt;/p&gt;

&lt;p&gt;The one thing I do miss from VB, however, is the With command.&amp;#160; It always seemed an elegant piece of syntactic sugar and easier to read when you find code that manipulates the same object repeatedly.&amp;#160; My “you can’t do that on television” moment over the msdn sample code came out of that longing for something I thought I’d simply had to leave behind.&lt;/p&gt;

&lt;p&gt;It took me a while to realize that the sample code was taking advantage of a trick that has always been available to C# developers but just not extensively used. (I even had to show it to several colleagues just to make sure I wasn’t just being slow – everyone’s first thought, blessedly, was that it was somehow a VB-to-C# translation mistake.) The trick is that the &lt;strong&gt;&lt;em&gt;RegisterType&lt;/em&gt;&lt;/strong&gt; method is returning an &lt;strong&gt;IUnityContainer&lt;/strong&gt; object.&amp;#160; Because a C# statement, unlike a VB statement, can be spread out over multiple lines in the editor until a semicolon delimiter is encountered, the code can be made to take on this VB-ish cast.&amp;#160; In fact, the &lt;strong&gt;&lt;em&gt;Append&lt;/em&gt;&lt;/strong&gt; method of the &lt;strong&gt;StringBuilder&lt;/strong&gt; type similarly returns its own container type, making the following code blocks equivalent:&lt;/p&gt;

&lt;div style="font-family:courier new;background:white;color:black;font-size:10pt;"&gt;
  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;StringBuilder&lt;/span&gt; sb = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;StringBuilder&lt;/span&gt;();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:green;"&gt;// this code ...&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; sb.AppendLine(&lt;span style="color:#a31515;"&gt;&amp;quot;one&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; sb.AppendLine(&lt;span style="color:#a31515;"&gt;&amp;quot;two&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; sb.AppendLine(&lt;span style="color:#a31515;"&gt;&amp;quot;three&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:green;"&gt;// is equivalent to this ...&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; sb.AppendLine(&lt;span style="color:#a31515;"&gt;&amp;quot;one&amp;quot;&lt;/span&gt;).AppendLine(&lt;span style="color:#a31515;"&gt;&amp;quot;two&amp;quot;&lt;/span&gt;).AppendLine(&lt;span style="color:#a31515;"&gt;&amp;quot;three&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:green;"&gt;// is equivalent to this ...&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; sb.AppendLine(&lt;span style="color:#a31515;"&gt;&amp;quot;one&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .AppendLine(&lt;span style="color:#a31515;"&gt;&amp;quot;two&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .AppendLine(&lt;span style="color:#a31515;"&gt;&amp;quot;three&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;This trick won’t work for properties, of course, but it is still pretty fun, and I’m kicking myself for never having come across it earlier.&lt;/p&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=9142" width="1" height="1"&gt;</description></item><item><title>WCF REST Starter Kit Complete Twitter Library</title><link>http://blog.magenic.com/blogs/jamesa/archive/2009/04/17/WCF-REST-Starter-Kit-Complete-Twitter-Library.aspx</link><pubDate>Fri, 17 Apr 2009 16:24:19 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:9132</guid><dc:creator>Anonymous</dc:creator><slash:comments>5</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/9132.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=9132</wfw:commentRss><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://cid-ef92193c4471bd9e.skydrive.live.com/self.aspx/.Public/WindowsTwitterFoundation.zip" target="_blank"&gt;Source&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://cid-ef92193c4471bd9e.skydrive.live.com/self.aspx/.Public/WindowsTwitterFoundation%20Binaries.zip" target="_blank"&gt;Binaries&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Ingredients: Visual Studio 2008, .NET 3.5 sp1, &lt;a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24644" target="_blank"&gt;WCF REST Starter Kit 2&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The HttpClient type, included with the WCF REST Starter Kit 2, is intended to make it easier to consume RESTful services.&amp;#160;&amp;#160; One of the most widely used publically accessible REST API’s is the one provided by Twitter, making it an obvious target for trying out these new Microsoft bits.&lt;/p&gt;  &lt;p&gt;Retrieving statuses from Twitter, as well as sending updates, is extremely easy using the WCF REST Starter Kit, as I posted earlier.&amp;#160; This led me to want to see if I could build out a client library for the rest of the Twitter REST API.&amp;#160; &lt;/p&gt;  &lt;p&gt;This projected one night effort ended up taking about a week and a half over several evenings.&amp;#160; For the most part, this was because actually building and testing the various contract objects is remarkably labor intensive.&lt;/p&gt;  &lt;p&gt;The Windows Twitter Foundation (source code and binaries above) can be used as a reference application for anyone trying either to build a client on top of twitter or for those simply interested in seeing a relatively complicated implementation of the WCF REST Starter Kit.&lt;/p&gt;  &lt;p&gt;If you want to just consume the binaries, you will need to download the &lt;a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24644" target="_blank"&gt;WCF REST Starter Kit Preview 2&lt;/a&gt; separately, if you haven’t already done so, and include the following assemblies in your project – Microsoft.Http.dll, Microsoft.Http.Extensions.dll, and Microsoft.ServiceModel.Web.dll .&lt;/p&gt;  &lt;p&gt;The Windows Twitter Foundation library has several features I’m rather proud of:&lt;/p&gt;  &lt;p&gt;1. It reads both XML and JSON formats.&amp;#160; The client application included with the source code switches between these two API’s with either the /XML command or the /JSON command.&lt;/p&gt;  &lt;p&gt;2. The library covers the complete Twitter REST API, including direct messaging and photo uploads.&amp;#160; The photo uploads are particularly finicky and took a couple nights alone just to figure out.&lt;/p&gt;  &lt;p&gt;3. The library also consumes the Twitter Search API.&amp;#160; The data contracts for Trending was a bit too strange for me to figure out, however.&lt;/p&gt;  &lt;p&gt;4. The CLR classes used for deserializing Twitter messages is included in a separate assembly.&amp;#160; They are decorated for both XML and DataContract deserialization.&amp;#160; If you are building your own Twitter client and are running into problems figuring out how to cast the Twitter messages, then these should help you out without obliging you to sniff out all the messages coming from Twitter in order to figure out their structure.&lt;/p&gt;  &lt;p&gt;5. I built most of it in my installation of Windows 7.&amp;#160; Visual Studio worked like a charm.&lt;/p&gt;  &lt;p&gt;Things I feel bad about:&lt;/p&gt;  &lt;p&gt;1. I couldn’t figure out how to deserialize the Trends service messages.&amp;#160; &lt;/p&gt;  &lt;p&gt;2. I used waaaay too many yellows and greens in the Console Application that comes with the source.&lt;/p&gt;  &lt;p&gt;Please use this code freely and in any way you like.&amp;#160; Be sure to consult the WCF REST Starter Kit 2 &lt;a href="http://aspnet.codeplex.com/license" target="_blank"&gt;license&lt;/a&gt; on codeplex for any rights reserved by Microsoft.&lt;/p&gt;  &lt;p&gt;Future plans:&lt;/p&gt;  &lt;p&gt;I would like to expand the library with additional wrappers for tinyurl and tweetpics and all the other little services that make up the Twitter ecosystem.&lt;/p&gt;  &lt;p&gt;I also plan to add helpers to support caching downloaded tweets and manage service calls to lighten the load on the Twitter servers (as the public API documents recommend).&lt;/p&gt;  &lt;p&gt;My immediate goal, however, is to start building a nice WPF UI around the Windows Twitter Foundation library (if you haven’t gotten the joke about the name, yet, just give it a moment).&lt;/p&gt;  &lt;p&gt;I've been enjoying the TweetDeck client, but so far haven’t seen anything in it that can’t be done using WPF.&amp;#160; I should be able to make a UI that is at least as attractive (glossy black controls are pretty straightforward in PF, right?).&amp;#160; Then I want to extend that design with carousels and some of the more interesting UI concepts that are part of the WPF development world.&amp;#160; Using Prism would also be fun, but we’ll see.&lt;/p&gt;  &lt;p&gt;The big gain in building a WPF client is that it can do things with the OS which are much more difficult in Adobe Air – for instance, hooking into the speech recognition features of Vista and Windows 7.&amp;#160; Enabling users to start talking instead of typing their tweets may have interesting ramifications if it ever catches on.&amp;#160; For myself, however, it will simply give me an excuse to start digging into speech recognition in Windows 7, which I hear works extremely well.&lt;/p&gt;  &lt;p&gt;The next few posts will cover some of the more interesting things I found while digging through both the Twitter REST API as well as the WCF REST Starter Kit – for instance, that the HttpClient class isn’t actually based on WCF, but is instead a wrapper for the HttpWebRequest and HttpWebResponse objects – or that the Twitter API embodies some strange notions about what a “friend” is and what&amp;#160; a “follower” is.&lt;/p&gt;  &lt;p&gt;Again, enjoy the code.&lt;/p&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=9132" width="1" height="1"&gt;</description></item><item><title>Getting Started with the WCF REST Starter Kit Preview 2 HttpClient</title><link>http://blog.magenic.com/blogs/jamesa/archive/2009/03/18/Getting-Started-with-the-WCF-REST-Starter-Kit-Preview-2-HttpClient.aspx</link><pubDate>Wed, 18 Mar 2009 22:30:38 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:8781</guid><dc:creator>Anonymous</dc:creator><slash:comments>5</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/8781.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=8781</wfw:commentRss><description>&lt;p&gt;Ingredients: Visual Studio 2008 SP1 (C#), WCF REST Starter Kit Preview 2&lt;/p&gt; &lt;p&gt;In Preview 1 of the WCF REST Starter Kit, Microsoft provided many useful tools for building RESTful services using WCF.&amp;nbsp; Missing from those bits was a clean way to call REST services from the client.&amp;nbsp; In Preview 2, which was released on March 13th, this has been made up for with the &lt;strong&gt;HttpClient&lt;/strong&gt; class and an add-in for the Visual Studio IDE called &lt;strong&gt;Paste XML as Types&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;The following getting-started tutorial will demonstrate how to use the HttpClient class to call a simple RESTful service (in fact, we will use the default implementation generated by the POX service template).&amp;nbsp; If you haven't downloaded and installed the WCF REST Starter Kit, yet, you can get Preview 2 &lt;a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24644" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;The sample solution will include two projects, one for the client and one for the service.&amp;nbsp; &lt;/p&gt; &lt;p&gt;1. Start by creating a Console Application project and solution called &lt;strong&gt;RESTfulClient&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;2. Add a new project to the RESTfulClient solution using the &lt;strong&gt;Http Plain XML WCF Service&lt;/strong&gt; project template that was installed when you installed the Starter Kit.&amp;nbsp; Call your new project POXService.&amp;nbsp; &lt;/p&gt; &lt;p&gt;The most obvious value-added features of the WCF REST Starter Kit are the various new project templates that are installed to make writing RESTful services easier.&amp;nbsp; Besides the Http Plain XML WCF Service template, we also get the ATOM Publishing Protocol WCF Service, the ATOM Feed WCF Service, REST Collection WCF Service, REST Singleton WCF Service and good ol' WCF Service Application.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;For this recipe, we will just use the default service as it is.&amp;nbsp; &lt;/p&gt; &lt;blockquote&gt; &lt;p&gt; &lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt; &lt;p style="margin:0px;"&gt;[&lt;span style="color:#2b91af;"&gt;WebHelp&lt;/span&gt;(Comment = &lt;span style="color:#a31515;"&gt;"Sample description for GetData"&lt;/span&gt;)]&lt;/p&gt; &lt;p style="margin:0px;"&gt;[&lt;span style="color:#2b91af;"&gt;WebGet&lt;/span&gt;(UriTemplate = &lt;span style="color:#a31515;"&gt;"GetData?param1={i}&amp;amp;param2={s}"&lt;/span&gt;)]&lt;/p&gt; &lt;p style="margin:0px;"&gt;[&lt;span style="color:#2b91af;"&gt;OperationContract&lt;/span&gt;]&lt;/p&gt; &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SampleResponseBody&lt;/span&gt; GetData(&lt;span style="color:blue;"&gt;int&lt;/span&gt; i, &lt;span style="color:blue;"&gt;string&lt;/span&gt; s)&lt;/p&gt; &lt;p style="margin:0px;"&gt;{&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SampleResponseBody&lt;/span&gt;()&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Value = &lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;.Format(&lt;span style="color:#a31515;"&gt;"Sample GetData response:"&amp;nbsp;&amp;nbsp; {0}', '{1}'"&lt;/span&gt;, i, s)&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp; };&lt;/p&gt; &lt;p style="margin:0px;"&gt;}&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;For the most part, this is a pretty straightforward WCF Service Method.&amp;nbsp; There are some interesting additional elements, however, which are required to make the service REST-y.&lt;/p&gt; &lt;p&gt;(In a major break with convention, you will notice that the default service created by this template is called &lt;strong&gt;Service&lt;/strong&gt; rather than &lt;strong&gt;Service1&lt;/strong&gt;.&lt;strong&gt;&amp;nbsp; &lt;/strong&gt;I, for one, welcome this change from our new insect overlords&lt;em&gt;.&lt;/em&gt;)&lt;/p&gt; &lt;p&gt;The &lt;strong&gt;WebGet&lt;/strong&gt; attribute, for instance, allows us to turn our service method into a REST resource accessed using the GET method.&amp;nbsp; The &lt;strong&gt;UriTemplate&lt;/strong&gt; attribute parameter specifies the partial Uri for our resource, in this case GetData.&amp;nbsp; We also specify in the UriTemplate how parameters can be passed to our resource.&amp;nbsp; In this case, we will be using a query string to pass two parameters, &lt;em&gt;param1&lt;/em&gt; and &lt;em&gt;param2&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;By default, the template provides a Help resource for our service, accessed by going to &lt;em&gt;http://localhost:&amp;lt;port&amp;gt;/Service.svc/Help&lt;/em&gt; .&amp;nbsp; It will automatically include a description of the structure of our service.&amp;nbsp; The &lt;strong&gt;WebHelp&lt;/strong&gt; attribute allows us to add further notes about the &lt;strong&gt;GetData&lt;/strong&gt; resource to the Help resource.&lt;/p&gt; &lt;p&gt;You will also notice that the GetData service method returns a SampleResponseBody object.&amp;nbsp; This is intended to make it explicit in our design that we are not making RPC's.&amp;nbsp; Instead, we are receiving and returning messages (or documents, if you prefer).&amp;nbsp; In this case, the message we return is simply the serialized version of SimpleResponseBody, which is a custom type that is specified in the service.svc.cs file and which does not inherit from any other type.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt; &lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt; &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SampleResponseBody&lt;/span&gt;&lt;br&gt;{ &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; Value { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; } &lt;br&gt;}&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;3. Right click on the PoxService project and select &lt;strong&gt;Debug&lt;/strong&gt; | &lt;strong&gt;Start New Instance&lt;/strong&gt; to see what our RESTful service looks like.&amp;nbsp; To see what the service does, you can browse to &lt;em&gt;http://localhost:&amp;lt;port&amp;gt;/Service.svc/Help&lt;/em&gt; .&amp;nbsp; To see what the schema for our GetData resouce looks like, go to &lt;em&gt;http://localhost:&amp;lt;port&amp;gt;/Service.svc/help/GetData/response/schema&lt;/em&gt; .&amp;nbsp; Finally, if you want to go ahead and call the GetData service, browse to &lt;em&gt;http://localhost:&amp;lt;port&amp;gt;/Service.svc/GetData&lt;/em&gt; .&lt;/p&gt; &lt;p&gt;(In the rest of this tutorial, I will simply use&amp;nbsp; port 1300, with the understanding that you can specify your own port in the code.&amp;nbsp; By default, Visual Studio will randomly pick a port for you.&amp;nbsp; If you want to specify a particular port, however, you can go into the project properties of the PoxService project and select a specific port in the project properties &lt;em&gt;Web&lt;/em&gt; tab.)&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;blockquote&gt;&lt;pre&gt;&lt;font color="#004080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804000"&gt;SampleResponseBody&lt;/font&gt; &lt;font color="#ff0000"&gt;xmlns:i&lt;/font&gt;&lt;font color="#004080"&gt;="&lt;/font&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;http://www.w3.org/2001/XMLSchema-instance&lt;/strong&gt;&lt;/font&gt;&lt;font color="#004080"&gt;"&amp;gt;&lt;/font&gt;&lt;/pre&gt;&lt;pre&gt;&lt;font color="#004080"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#804000"&gt;Value&lt;/font&gt;&lt;font color="#004080"&gt;&amp;gt;&lt;/font&gt;Sample GetData response: '0', ''&lt;font color="#004080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804000"&gt;Value&lt;/font&gt;&lt;font color="#004080"&gt;&amp;gt;&lt;/font&gt; &lt;/pre&gt;&lt;pre&gt;&lt;font color="#004080"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#804000"&gt;SampleResponseBody&lt;/font&gt;&lt;font color="#004080"&gt;&amp;gt;&lt;/font&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;4. Go to the RESTfulClient project and add a new class called &lt;strong&gt;SampleResponseBody&lt;/strong&gt;.&amp;nbsp; We are going to create a type for deserializing our SampleResponseBody XML element.&amp;nbsp; We could write out the class by hand, and prior to Preview 2 we probably would have had to.&amp;nbsp; It is no longer necessary, however.&amp;nbsp; If you copy the XML returned from browsing our resource (you may need to use View Source in your browser to get a clean representation) at &lt;em&gt;http://localhost:1300/Service.svc/GetData&lt;/em&gt; you can simply paste this into our SampleResponseBody.cs file by going to the Visual Studio Edit menu and selecting &lt;strong&gt;Paste XML to Types&lt;/strong&gt;.&amp;nbsp; To get all the necessary types in one blow, you can also go to &lt;em&gt;http://localhost:1300/Service.svc/Help &lt;/em&gt;and use Paste XML to Types.&amp;nbsp; As a third alternative, just copy the XML above and try Paste XML to Types in your SampleResponseBody class.&amp;nbsp; However you decide to do it, you are now in a position to translate XML into CLR types.&lt;/p&gt;
&lt;p&gt;Your generated class should look like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
&lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;
&lt;p style="margin:0px;"&gt;[System.CodeDom.Compiler.&lt;span style="color:#2b91af;"&gt;GeneratedCodeAttribute&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;"System.Xml"&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;"2.0.50727.3053"&lt;/span&gt;)]&lt;/p&gt;
&lt;p style="margin:0px;"&gt;[System.Diagnostics.&lt;span style="color:#2b91af;"&gt;DebuggerStepThroughAttribute&lt;/span&gt;()]&lt;/p&gt;
&lt;p style="margin:0px;"&gt;[System.Xml.Serialization.&lt;span style="color:#2b91af;"&gt;XmlTypeAttribute&lt;/span&gt;(AnonymousType = &lt;span style="color:blue;"&gt;true&lt;/span&gt;)]&lt;/p&gt;
&lt;p style="margin:0px;"&gt;[System.Xml.Serialization.&lt;span style="color:#2b91af;"&gt;XmlRootAttribute&lt;/span&gt;(Namespace = &lt;span style="color:#a31515;"&gt;""&lt;/span&gt;, IsNullable = &lt;span style="color:blue;"&gt;false&lt;/span&gt;)]&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;partial&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SampleResponseBody&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;{&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; valueField;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;remarks/&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; Value&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;get&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&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; &lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.valueField;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;set&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&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; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.valueField = &lt;span style="color:blue;"&gt;value&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;}&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;5.&amp;nbsp; Next, we need to add the Starter Kit assemblies to our console application.&amp;nbsp; The default location for these assemblies is C:\Program Files\Microsoft WCF REST\WCF REST Starter Kit Preview 2\Assemblies .&amp;nbsp; The two assemblies we need for the client are &lt;strong&gt;Microsoft.Http.dll&lt;/strong&gt; and &lt;strong&gt;Microsoft.Http.Extensions.dll&lt;/strong&gt; .&amp;nbsp; (I happen to like to copy CodePlex bits like these into a folder in the My Documents\Visual Studio 2008 directory, to make it relatively easier to track drop versions).&lt;/p&gt;
&lt;p&gt;6. We will now finally add some code to call call our GetData resource using the HttpClient class.&amp;nbsp; The following code will simply prompt the user to hit {Enter} to call the resource.&amp;nbsp; It will then return the deserialized message from the resource and prompt the user to hit {Enter} again.&amp;nbsp; Add the following using references to your Program.cs file:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; Microsoft.Http;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; System.Xml.Serialization;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp; Now place the following code in the Main() method of Program.cs:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
&lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;
&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)&lt;/p&gt;
&lt;p style="margin:0px;"&gt;{&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;"Press {enter} to call service:"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.ReadLine();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;var&lt;/span&gt; client = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;HttpClient&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;http://localhost:1300/Service.svc/&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;HttpResponseMessage&lt;/span&gt; response = client.Get(&lt;span style="color:#a31515;"&gt;"GetData"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;var&lt;/span&gt; b = response.Content.ReadAsXmlSerializable&amp;lt;&lt;span style="color:#2b91af;"&gt;SampleResponseBody&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(b.Value);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.ReadLine();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;}&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Both the Get request and the deserialization are simple.&amp;nbsp; We pass a base address for our service to the HttpClient constructor.&amp;nbsp; We then call the HttpClient's &lt;strong&gt;Get&lt;/strong&gt; method and pass the path to the resource we want (in true REST idiom, PUT, DELETE and POST are some additional methods on HttpClient).&lt;/p&gt;
&lt;p&gt;The deserialization, in turn, only requires one line of code.&amp;nbsp; We call the Content property of the HttpResponseMessage instance returned by Get() to retrieve an HttpContent instance, then call its generic ReadAsXmlSerializable method to deserialize the XML message into our SampleResponseBody type.&lt;/p&gt;
&lt;p&gt;While you could previously do this using WCF and deserialization, or even the HttpWebRequest and HttpWebResponse types and an XML parser, this is significantly easier.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;7. If you recall, the signature of the GetData service method actually takes two parameters, an integer and a string.&amp;nbsp; When translated into a REST resource, the parameters are passed in a query string.&amp;nbsp; To complete this example, we might want to go ahead and pass these parameters to our GetData resource.&amp;nbsp; To do so, replace the code above with the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
&lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;
&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)&lt;/p&gt;
&lt;p style="margin:0px;"&gt;{&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;"Enter a number:"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;int&lt;/span&gt; myInt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Int32&lt;/span&gt;.TryParse(&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.ReadLine(), &lt;span style="color:blue;"&gt;out&lt;/span&gt; myInt);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;"Enter a string:"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;var&lt;/span&gt; myString = &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.ReadLine();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;var&lt;/span&gt; q = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;HttpQueryString&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; q.Add(&lt;span style="color:#a31515;"&gt;"param1"&lt;/span&gt;, myInt.ToString());&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; q.Add(&lt;span style="color:#a31515;"&gt;"param2"&lt;/span&gt;, myString);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;var&lt;/span&gt; client = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;HttpClient&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;"http://localhost:1300/Service.svc/"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;HttpResponseMessage&lt;/span&gt; response = client.Get(&lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Uri&lt;/span&gt;(client.BaseAddress + &lt;span style="color:#a31515;"&gt;"GetData"&lt;/span&gt;), q);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;var&lt;/span&gt; b = response.Content.ReadAsXmlSerializable&amp;lt;&lt;span style="color:#2b91af;"&gt;SampleResponseBody&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(b.Value);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;"Press {enter} to end."&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.ReadLine();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;}&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The first block asks for a number and we verify that a number was indeed submitted.&amp;nbsp; The next block requests a string.&lt;/p&gt;
&lt;p&gt;The third block creates an &lt;strong&gt;HttpQueryString&lt;/strong&gt; instance using our console inputs.&lt;/p&gt;
&lt;p&gt;The important code is in the fourth block.&amp;nbsp; You will notice that we use a different overload for the Get method this time.&amp;nbsp; It turns out that the only overload that accepts a query string requires a Uri for its first parameter rather than a partial Uri string.&amp;nbsp; To keep things simple, I've simply concatenated "GetData" with the BaseAddress we previously passed in the constructor (this does not overwrite the BaseAddress, in case you were wondering).&amp;nbsp; We could have also simply performed a string concatenation like this, of course:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
&lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;
&lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;HttpResponseMessage&lt;/span&gt; response = &lt;/p&gt;
&lt;p style="margin:0px;"&gt;client.Get(&lt;span style="color:blue;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#a31515;"&gt;"GetData?param1={0}&amp;amp;param2={1}"&lt;/span&gt;,myInt.ToString(), myString));&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;but using the HttpQueryString type strikes me as being somewhat cleaner.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;And that's how we do RESTful WCF as of Friday, March 13th, 2009.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;To see how we used to do it prior to March 13th, please see &lt;a href="http://blogs.msdn.com/pedram/archive/2008/04/21/how-to-consume-rest-services-with-wcf.aspx" target="_blank"&gt;this&lt;/a&gt; excellent blog post by Pedram Rezai from April of last year.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;/pre&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=8781" width="1" height="1"&gt;</description></item><item><title>RESTful WCF at Atlanta Code Camp</title><link>http://blog.magenic.com/blogs/jamesa/archive/2009/03/15/RESTful-WCF-at-Atlanta-Code-Camp.aspx</link><pubDate>Sun, 15 Mar 2009 21:11:44 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:8747</guid><dc:creator>Anonymous</dc:creator><slash:comments>3</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/8747.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=8747</wfw:commentRss><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;This past Saturday was the Atlanta Code Camp.&amp;#160; I want to be make a point of thanking Cliff Jacobson, Dan Attis, Doug Ware, Glen Gordon, Jeff Ammons and all the other organizers who made this a brilliant event.&lt;/p&gt;  &lt;p&gt;My company, Magenic Technologies, presented at seven of the sessions this year.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://sergeybarskiy.spaces.live.com/default.aspx" target="_blank"&gt;Sergey Barskiy&lt;/a&gt;, who was a developer on the CSLA-Lite team, presented on &lt;em&gt;Building Silverlight Business Applications using CSLA.NET for Silverlight.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.magenic.com/blogs/whitneyw/" target="_blank"&gt;Whitney Weaver&lt;/a&gt;, another of our principal consultants and a master of all things data, spoke on &lt;em&gt;What&amp;#8217;s my data doing while I sleep? Tracking data changes in SQL Server 2008&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.codesprouts.com/" target="_blank"&gt;Colin Whitlatch&lt;/a&gt; presented an &lt;em&gt;Introduction to ASP.NET MVC&lt;/em&gt;, and is planning to extend his presentation over the next few weeks on his blog, where he will be digging deep into ASP.NET MVC and helping others to do the same.&lt;/p&gt;  &lt;p&gt;Jason Rainwater needs a blog, because he is currently one of the best WPF experts in Atlanta and there aren't enough venues at this point for him to show off everything he knows.&amp;#160; He did two presentations this year: &lt;em&gt;WPF Custom Controls&lt;/em&gt; and &lt;em&gt;WPF DataBinding&lt;/em&gt;. &lt;/p&gt;  &lt;p&gt;I presented on &lt;em&gt;REST-ful WCF&lt;/em&gt; (the hyphen is a personal grammatical quirk rather than any attempt to make a philosophical point) and &lt;em&gt;Mocking with Rhino Mocks and TypeMock: A Head-to-head Comparison.&amp;#160; &lt;/em&gt;I also got to make a short app-dev appearance in Tejas Patel's &lt;em&gt;Use of data mining controls with ASP.NET&lt;/em&gt; presentation.&lt;/p&gt;  &lt;p&gt;As promised to the attendees, I'm making the code samples and slide-decks available.&amp;#160; Please excuse the lack of organization in the code -- it's pretty much just what I was writing while I was on-stage, but should be helpful if anyone is looking for samples.&amp;#160; All the code uses Visual Studio 2008.&amp;#160; The mocking samples will require that you have the appropriate dll's for &lt;a href="http://ayende.com/projects/rhino-mocks/downloads.aspx" target="_blank"&gt;Rhino Mocks&lt;/a&gt;, which is free,&amp;#160; and &lt;a href="http://www.typemock.com/Downloads.php" target="_blank"&gt;TypeMock&lt;/a&gt; Isolator, which has a 30-day trial.&lt;/p&gt;  &lt;p&gt;I am indebted for &lt;a href="http://blogs.msdn.com/pedram/archive/2008/04/21/how-to-consume-rest-services-with-wcf.aspx" target="_blank"&gt;Pedram Rezaei&lt;/a&gt; for getting me started on the WCF-to-Flikr sample.&lt;/p&gt;  &lt;p&gt;The Rest-ful WCF slide-deck and code can be downloaded &lt;a href="http://www.imaginativeuniversal.com/codesamples/REST-fulWCF.zip" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The Mocking powerpoint and samples are available &lt;a href="http://www.imaginativeuniversal.com/codesamples/mocking.zip" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=8747" width="1" height="1"&gt;</description></item><item><title>The problem with computer literacy</title><link>http://blog.magenic.com/blogs/jamesa/archive/2008/10/06/The-problem-with-computer-literacy.aspx</link><pubDate>Mon, 06 Oct 2008 18:08:00 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:6504</guid><dc:creator>Anonymous</dc:creator><slash:comments>43</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/6504.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=6504</wfw:commentRss><description>&lt;p&gt;A recent post on &lt;a href="http://www.boingboing.net/" target="_blank"&gt;Boing Boing&lt;/a&gt; is titled &lt;a href="http://www.boingboing.net/2008/10/06/paper-and-pencil-bet.html" target="_blank"&gt;Paper and pencil better for the brain than software&lt;/a&gt;?&amp;nbsp; The gist of the article and its associated links is that software, in guiding us through common tasks, actually makes us dumber.&amp;nbsp; The Dutch psychologist Christof van Nimwegen has performed studies demonstrating the deleterious effects of being plugged-in.&amp;nbsp; From the post:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;quot;Van Nimwegen says much software turns us into passive beings, subjected to the whims of computers, randomly clicking on icons and menu options. In the long run, this hinders our creativity and memory, he says.&amp;quot;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;This certainly sounds right to me, from personal experience.&amp;nbsp; About a year ago, my company gave away GPS navigation devices as Christmas gifts to all the consultants.&amp;nbsp; The results are twofold.&amp;nbsp; On the one hand, we all make our appointments on time now, because we don&amp;#39;t get lost anymore.&amp;nbsp; On the other, we have all lost our innate sense of direction -- that essential skill that got the species through the hunter-gatherer phase of our development.&amp;nbsp; Without my GPS, I am effectively as blind as a bat without echolocation.&lt;/p&gt;&lt;p&gt;In Charles Stross&amp;#39;s novel about the near future, &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0441014151/charlieswebsi-20" target="_blank"&gt;Accelerando&lt;/a&gt;, this experience is taken a step further.&amp;nbsp; The protagonist Manfred Macx is at one point mugged on the street, and his connection to the Internet, which he carries around with him hooked up to his glasses, is taken away.&amp;nbsp; As a man of the pre-singularity, however, his personality has become so distributed over search engines and data portals that without this connection he is no longer able to even identify himself.&amp;nbsp; This is the nightmare of the technologically dependent.&lt;/p&gt;&lt;p&gt;Doctor van Nimwegen&amp;#39;s study recalls Plato&amp;#39;s ambivalence about the art of writing.&amp;nbsp; His mentor Socrates, it may be remembered, never put anything to writing, which he found inherently untrustworthy. Consequently all we know of Socrates comes by way of his disciple Plato.&amp;nbsp; Plato, in turn, was a poet who ultimately became distrustful of his own skills, and railed against it in his philosophical writings.&amp;nbsp; From the modern viewpoint, however, whatever it is that we lose when we put &amp;quot;living&amp;quot; thoughts down to writing, surely it is only through poetry that we are able to recover and sustain it.&lt;/p&gt;&lt;p&gt;It is through poetic imagery that Plato explains Socrates&amp;#39;s misgivings about letters in the &lt;a href="http://www9.georgetown.edu/faculty/jod/texts/phaedrus.html" target="_blank"&gt;Phaedrus&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;At the Egyptian city of Naucratis, there was a famous old god, whose name was Theuth; the bird which is called the Ibis is sacred to him, and he was the inventor of many arts, such as arithmetic and calculation and geometry and astronomy and draughts and dice, but his great discovery was the use of letters. Now in those days the god Thamus was the king of the whole country of Egypt; and he dwelt in that great city of Upper Egypt which the Hellenes call Egyptian Thebes, and the god himself is called by them Ammon. To him came Theuth and showed his inventions, desiring that the other Egyptians might be allowed to have the benefit of them; he enumerated them, and Thamus enquired about their several uses, and praised some of them and censured others, as he approved or disapproved of them. It would take a long time to repeat all that Thamus said to Theuth in praise or blame of the various arts. But when they came to letters, This, said Theuth, will make the Egyptians wiser and give them better memories; it is a specific both for the memory and for the wit. Thamus replied: O most ingenious Theuth, the parent or inventor of an art is not always the best judge of the utility or inutility of his own inventions to the users of them. And in this instance, you who are the father of letters, from a paternal love of your own children have been led to attribute to them a quality which they cannot have; for this discovery of yours will create forgetfulness in the learners&amp;#39; souls, because they will not use their memories; they will trust to the external written characters and not remember of themselves. &lt;strong&gt;The specific which you have discovered is an aid not to memory, but to reminiscence, and you give your disciples not truth, but only the semblance of truth; they will be hearers of many things and will have learned nothing; they will appear to be omniscient and will generally know nothing&lt;/strong&gt;; &lt;strong&gt;they will be tiresome company, having the show of wisdom without the reality.&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;We can certainly see aspects of Manfred Macx&amp;#39;s experience of disorientation in our dependence on tools like Google and Wikipedia, which provide us all with the same degree of wisdom, or at least the same show of wisdom.&amp;nbsp; In tracking down the above quote about Theuth, I had to rely on a vague reminiscence that this memory passage occurred in either the Timaeus or the Phaedrus, and then used my browser search functionality to track down the specific paragraph.&amp;nbsp; Very handy, that search feature.&amp;nbsp; But how much more wonderful it would have been had I been able to call that up from my own theater of memory.&lt;/p&gt;&lt;p&gt;My only stand against the steady march of progress (from which I make my living, it should be remembered) is that I turn my spell-checker off when I write emails and articles.&amp;nbsp; A consulting manager recently chastised me for this practice, which he found error prone and somewhat irresponsible.&amp;nbsp; To this I could only reply, &amp;quot;but I already know how to spell.&amp;quot;&amp;nbsp;&amp;nbsp; &lt;/p&gt;&lt;p&gt;I should have added, &amp;quot;...for now.&amp;quot;&lt;/p&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=6504" width="1" height="1"&gt;</description><category domain="http://blog.magenic.com/blogs/jamesa/archive/tags/Sleestak+Management/default.aspx">Sleestak Management</category></item><item><title>Visual Studio 2008 SP1 Toolbox Crash</title><link>http://blog.magenic.com/blogs/jamesa/archive/2008/10/04/Visual-Studio-2008-SP1-Toolbox-Crash.aspx</link><pubDate>Sat, 04 Oct 2008 17:18:27 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:6486</guid><dc:creator>Anonymous</dc:creator><slash:comments>986</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/6486.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=6486</wfw:commentRss><description>&lt;p&gt;For the past month or so, whenever I tried to add a control to my Visual Studio Toolbox, the IDE would shut itself down.&amp;#160; My solution, of course, was to avoid adding tools to my Toolbox.&lt;/p&gt;  &lt;p&gt;Finally I decided that I needed to do something, ahem, a little smarter.&amp;#160; The specific problem occurred when I tried to use the Context Menu's &amp;quot;Choose Items...&amp;quot; option on my toolbox.&amp;#160;&amp;#160; It turns out that the &lt;a href="http://code.msdn.microsoft.com/PowerCommands" target="_blank"&gt;Power Commands&lt;/a&gt; (when did I install that?) has a conflict with VS 2008.&amp;#160; This apparently can also mess up the class viewer in Visual Studio 2008.&amp;#160; There are two work-arounds for this.&amp;#160;&amp;#160; The first is to hack a config file for your IDE settings.&amp;#160;&amp;#160; That solution can be found here: &lt;a title="http://social.msdn.microsoft.com/Forums/en-US/vssetup/thread/e2434065-9921-4861-b914-9cc9d6c55553/" href="http://social.msdn.microsoft.com/Forums/en-US/vssetup/thread/e2434065-9921-4861-b914-9cc9d6c55553/"&gt;http://social.msdn.microsoft.com/Forums/en-US/vssetup/thread/e2434065-9921-4861-b914-9cc9d6c55553/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Unfortunately this didn't work for me.&amp;#160; The second work-around is simply to uninstall the Power Commands.&amp;#160; If you go into Add/Remove Programs, it is listed as PowerCommands for Visual Studio 2008.&lt;/p&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=6486" width="1" height="1"&gt;</description></item><item><title>Reflection</title><link>http://blog.magenic.com/blogs/jamesa/archive/2008/09/08/Reflection.aspx</link><pubDate>Mon, 08 Sep 2008 18:55:00 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:6058</guid><dc:creator>Anonymous</dc:creator><slash:comments>5</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/6058.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=6058</wfw:commentRss><description>&lt;p&gt;Like may others, I recently received the fateful email notifying me that Lutz &lt;a href="http://blog.lutzroeder.com/" target="_blank"&gt;Roeder&lt;/a&gt; will be giving up his work on .NET Reflector, the brilliant and essential tool he developed to peer into the internal implementation of .NET assemblies.&amp;nbsp; Of course the whole idea of reflecting into an assembly is cheating a bit, since one of the principles of OO design is that we don&amp;#39;t care about implementations, only about contracts.&amp;nbsp; It gets worse, since one of the main reasons for using .NET Reflector is to reverse engineer someone else&amp;#39;s (particularly Microsoft&amp;#39;s) code.&amp;nbsp; Yet it is the perfect tool when one is good at reading code and simply needs to know how to do something special -- something that cannot be explained, but must be seen.&lt;/p&gt;&lt;p&gt;While many terms in computer science are drawn from other scientific fields, &lt;em&gt;reflection&lt;/em&gt; appears not to be.&amp;nbsp; Instead, it is derived from the philosophical &amp;quot;reflective&amp;quot; tradition, and is a synonym for looking inward: &lt;em&gt;introspection&lt;/em&gt;.&amp;nbsp; Reflection and introspection are not exactly the same thing, however.&amp;nbsp; This is a bit of subjective interpretation, of course, but it seems to me that unlike introspection, which is merely a turning inward, reflection tends to involve a stepping outside of oneself and peering at oneself.&amp;nbsp; In reflection, there is a moment of stopping and stepping back; the &amp;quot;I&amp;quot; who looks back on oneself is a cold and appraising self, cool and objective as a mirror.&lt;/p&gt;&lt;p&gt;Metaphors pass oddly between the world of philosophy and the world of computer science, often giving rise to peculiar reversals.&amp;nbsp; When concepts such as memory and CPU&amp;#39;s were being developed, the developers of these concepts drew their metaphors from the workings of the human mind.&amp;nbsp; The persistent storage of a computer is like the human faculty of memory, and so it was called &amp;quot;memory&amp;quot;.&amp;nbsp; The CPU works like the processing of the mind, and so we called it the central processing unit, sitting in the shell of the computer like a homunculus viewing a theater across which data is streamed.&amp;nbsp; Originally it was the mind that was the given, while the computer was modeled upon it.&amp;nbsp; Within a generation, the flow of metaphors has been reversed, and it is not uncommon find arguments about the computational nature of the brain based on analogies with the workings of computers.&amp;nbsp; Isn&amp;#39;t it odd that we remember things, just like computers remember things?&lt;/p&gt;&lt;p&gt;The ancient Skeptics had the concept of &lt;em&gt;epoche&lt;/em&gt; to describe this peculiar attitude of stepping back from the world, but it wasn&amp;#39;t until Descartes that this philosophical notion became associated with the metaphor of optics.&amp;nbsp; In a letter to Arnauld from 1648, Descartes writes:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;quot;We make a distinction between direct and reflective thoughts corresponding to the distinction we make between direct and reflective vision, one depending on the first impact of the rays and the other on the second.&amp;quot;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;This form of reflective thought, in turn, also turns up in at an essential turning point in Descartes&amp;#39; discussion of his Method, when he realizes that his moment of self-awareness is logically dependent on something higher:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;quot;In the next place, from reflecting on the circumstance that I doubted, and that consequently my being was not wholly perfect, (for I clearly saw that it was a greater perfection to know than to doubt,) I was led to inquire whence I had learned to think of something more perfect than myself;&amp;quot;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Descartes uses the metaphor in several places in the &lt;em&gt;Discourse on Method&lt;/em&gt;.&amp;nbsp; In each case, it is as if, after doing something, for instance doubting, he is looking out the corner of his eye at a mirror to see what he looks like when he is doing it, like an angler trying to perfect his cast or an orator attempting to improve his hand gestures.&amp;nbsp; In each case, what one sees is not quite what one expects to see; what one does is not quite what one thought one was doing.&amp;nbsp; The act of reflection provides a different view of ourselves from what we might observe from introspection alone.&amp;nbsp; For Descartes, it is always a matter of finding out what one is &amp;quot;really&amp;quot; doing, rather than what one thinks one is doing.&lt;/p&gt;&lt;p&gt;This notion of philosophical &amp;quot;true sight&amp;quot; through reflection is carried forward, on the other side of the channel, by Locke.&amp;nbsp; In his &lt;em&gt;Essay Concerning Human Understanding&lt;/em&gt;, Locke writes:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;quot;This source of ideas every man has wholly in himself; and though it be not sense, as having nothing to do with external objects, yet it is very like it, and might properly enough be called &lt;em&gt;internal sense&lt;/em&gt;. But as I call the other Sensation, so I call this REFLECTION, the ideas it affords being such only as the mind gets by reflecting on its own operations within itself. By reflection then, in the following part of this discourse, I would be understood to mean, that notice which the mind takes of its own operations, and the manner of them, by reason whereof there come to be ideas of these operations in the understanding.&amp;quot;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Within a century, &lt;em&gt;reflection&lt;/em&gt; becomes so ingrained in philosophical thought, if not identified with it, that Kant is able to talk of &amp;quot;transcendental reflection&amp;quot;: &lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;quot;Reflection (reflexio) is not occupied about objects themselves, for the purpose of directly obtaining conceptions of them, but is that state of the mind in which we set ourselves to discover the subjective conditions under which we obtain conceptions.&lt;/p&gt;&lt;p&gt;...&lt;/p&gt;&lt;p&gt;&amp;quot;The act whereby I compare my representations with the faculty of cognition which originates them, and whereby I distinguish whether they are compared with each other as belonging to the pure understanding or to sensuous intuition, I term transcendental reflection.&amp;quot;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;In the 20th century, the reflective tradition takes a peculiar turn.&amp;nbsp; While the phenomenologists continued to use it as the central engine of their philosophizing, Wilfred Sellars began his attack on &amp;quot;the myth of the given&amp;quot; upon which phenomenological reflection depended.&amp;nbsp; From an epistemological viewpoint, Sellars questions the implicit assumption that we, as thinking individuals, have any privileged access to our own mental states. Instead, Sellars posits that what we actually have is not clear vision of our internal mental states, but rather a culturally mediated &amp;quot;folk psychology&amp;quot; of mind that we use to describe those mental states.&amp;nbsp; In one fell swoop, Sellars sweeps away the Cartesian tradition of self-understanding that informs the &lt;em&gt;cogito ergo sum&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;In a sense, however, this isn&amp;#39;t truly a reversal of the reflective tradition but merely a refinement.&amp;nbsp; Sellars and his contemporary heirs, such as the Churchlands and Daniel Dennett, certainly provided a devastating blow to the reliability of philosophical introspection.&amp;nbsp; The Cartesian project, however, was not one of introspection, nor is the later phenomenological project.&amp;nbsp; The &amp;quot;given&amp;quot; was always assumed to be unreliable in some way, which is why philosophical &amp;quot;reflection&amp;quot; is required to analyze and correct the &amp;quot;given.&amp;quot;&amp;nbsp; All that Sellars does is to move the venue of philosophical reflection from the armchair to the laboratory, where it no doubt belongs.&lt;/p&gt;&lt;p&gt;A more fundamental attack on the reflective tradition came from Italy approximately 200 hundred years before Sellars.&amp;nbsp; Giambattista Vico saw the danger of the Cartesian tradition of philosophical reflection as lying in its undermining of the given of cultural institutions.&amp;nbsp; A professor of oratory and law, Vico believed that common understanding held a society together, and that the dissolution of civilizations occurred not when those institutions no longer held, but rather when we begin to doubt that they even exist.&amp;nbsp; On the face of it, it sounds like the rather annoying contemporary arguments against &amp;quot;cultural relativism&amp;quot;, but is actually a bit different.&amp;nbsp; Vico&amp;#39;s argument is rather that we all live in a world of myths and metaphors that help us to regulate our lives, and in fact contribute to what makes us human, and able to communicate with one another.&amp;nbsp; In the 1730 edition of the &lt;u&gt;New Science&lt;/u&gt;, Vico writes:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;quot;Because, unlike in the time of the barbarism of sense, the barbarism of reflection pays attention only to the words and not to the spirit of the laws and regulations; even worse, whatever might have been claimed in these empty sounds of words is believed to be just.&amp;nbsp; In this way the barbarism of reflection claims to recognize and know the just, what the regulations and laws intend, and endeavors to defraud them through the superstition of words.&amp;quot;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;For Vico, the reflective tradition breaks down those civil bonds by presenting man as a rational man who can navigate the world of social institutions as an individual, the solitary &lt;em&gt;cogito&lt;/em&gt; who sees clearly, and cooly, the world as it is.&lt;/p&gt;&lt;p&gt;This begets the natural question, does &lt;em&gt;reflection&lt;/em&gt; really provide us with true sight, or does it merely dissociate ourselves from our inner lives in such a way that we only see what we want to see?&amp;nbsp; In computer science of course (not that this should be any guide to philosophy) the latter is the case.&amp;nbsp; Reflection is accomplished by publishing metadata about a code library which may or may not be true.&amp;nbsp; It does not allow us to view the code as it really is, but rather provides us a mediated view of the code, which is then associated with the code.&amp;nbsp; We assume it is reliable, but there is no way of really knowing until something goes wrong.&lt;/p&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=6058" width="1" height="1"&gt;</description><category domain="http://blog.magenic.com/blogs/jamesa/archive/tags/Sleestak+Management/default.aspx">Sleestak Management</category></item><item><title>AJAX Control Toolkit: Script Only</title><link>http://blog.magenic.com/blogs/jamesa/archive/2008/08/26/AJAX-Control-Toolkit_3A00_-Script-Only.aspx</link><pubDate>Tue, 26 Aug 2008 16:15:04 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:5819</guid><dc:creator>Anonymous</dc:creator><slash:comments>0</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/5819.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=5819</wfw:commentRss><description>&lt;p&gt;I previously posted about how to use the Microsoft Ajax Library in order to provide Globalization script functionality without using the ScriptManager control.&amp;#160; Why would you want to do this?&lt;/p&gt;  &lt;p&gt;One issue is that Microsoft is currently working on the ASP.NET MVC framework, which will provide a way of doing web applications that is more familiar to PHP and JSP programmers.&amp;#160; In other words, it doesn't use the WebForms infrastructure that has underpinned Microsoft's whole approach to web development for the past six years.&amp;#160; The original promise of WebForms was to abstract web development so it looks more like traditional Windows Forms development.&amp;#160; In order to accomplish this, the developers at Microsoft have worked hard to abstract the underlying web technology using windows components that render html and emit client script for the developer.&lt;/p&gt;  &lt;p&gt;But now the tide is turning, and with WPF and XAML, Microsoft's newest technology for building desktop applications, we are seeing a transition to the development metaphors that we have become accustomed to in web development.&lt;/p&gt;  &lt;p&gt;ASP.NET AJAX was originally developed following the WebForms paradigm.&amp;#160; While other AJAX frameworks provided script libraries that you needed to manipulate using client script (typically javascript), Microsoft provided their framework wrapped in controls like the ScriptManager and the UpdatePanel.&amp;#160; Even the Ajax Control Toolkit, the Microsoft backed opensource project that extends ASP.NET AJAX with additional controls, follows this model.&lt;/p&gt;  &lt;p&gt;But the MVC model doesn't follow this model.&amp;#160; It follows the model followed by every other vendor of web technology.&lt;/p&gt;  &lt;p&gt;So how do ASP.NET MVC and ASP.NET AJAX come together if they follow these radically different models?&amp;#160; Well ... the Microsoft AJAX team also provides the underlying scripts for their framework in the &lt;a href="http://www.asp.net/ajax/downloads/library/default.aspx?wwwaspnetrdirset=1" target="_blank"&gt;Microsoft Ajax Library&lt;/a&gt;, which can be used in JSP, PHP, or even your traditional HTML page if you are willing to do the muscle work required to hook into them.&amp;#160; They can also, of course, be used with the MVC framework.&lt;/p&gt;  &lt;p&gt;The Ajax Control Toolkit now also exposes its underlying script files for general use, allowing use to get all the great ACT functionality with WebForms or a ScriptManager.&amp;#160; The only problem is that learning to use the library without controls to manage our state and emit our code is difficult, and there is very little online help to get you started.&lt;/p&gt;  &lt;p&gt;Stephen Walther is now helping people through this difficulty on his &lt;a href="http://weblogs.asp.net/stephenwalther/" target="_blank"&gt;blog&lt;/a&gt;, and it is a wonderful thing.&amp;#160; He has already tackled the &lt;a href="http://weblogs.asp.net/stephenwalther/archive/2008/08/22/asp-net-mvc-tip-36-create-a-popup-calendar-helper.aspx" target="_blank"&gt;Popup Calendar&lt;/a&gt; and &lt;a href="http://weblogs.asp.net/stephenwalther/archive/2008/08/23/asp-net-mvc-tip-37-create-an-auto-complete-text-field.aspx" target="_blank"&gt;Autocomplete&lt;/a&gt;.&amp;#160; Expect to hear more from him in the near future.&amp;#160; I can't wait to see what he does next.&lt;/p&gt;  &lt;p&gt;h/t to Bertrand Leroy's &lt;a href="http://weblogs.asp.net/bleroy/" target="_blank"&gt;Tales From the Evil Empire&lt;/a&gt; for highlighting this.&lt;/p&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=5819" width="1" height="1"&gt;</description><category domain="http://blog.magenic.com/blogs/jamesa/archive/tags/Ajax/default.aspx">Ajax</category></item><item><title>Recipe: Session Expired Monitor with ASP.NET AJAX</title><link>http://blog.magenic.com/blogs/jamesa/archive/2008/08/25/Recipe_3A00_-Session-Expired-Monitor-with-ASP.NET-AJAX.aspx</link><pubDate>Mon, 25 Aug 2008 19:19:00 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:5808</guid><dc:creator>Anonymous</dc:creator><slash:comments>3</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/5808.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=5808</wfw:commentRss><description>&lt;div id="container"&gt;&lt;div id="centrecontent"&gt;&lt;div class="dayItems"&gt;&lt;div class="items"&gt;&lt;div class="item"&gt;&lt;div class="itemContents"&gt;&lt;div class="itemBody"&gt;&lt;p&gt;&lt;a href="http://www.imaginativeuniversal.com/ct.ashx?id=b5fda1b7-c69a-4d0c-ba47-c8fb2a1f113b&amp;amp;url=http%3a%2f%2fwww.imaginativeuniversal.com%2fcodesamples%2fSessionTimeout.zip" target="_blank"&gt;code download&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Sessions are a way of preserving information on a web site between page hits, allowing the programmer to emulate a stateful application when, in fact, web pages are not really stateful.&amp;nbsp; They are also among the banes of web development, since sessions eventually timeout when there is no interaction between the user and the web app for a prolonged period of time.&amp;nbsp; In ASP.NET, this period has a default of 20 minutes, which is really hardly enough time to pick up a donut, refill one&amp;#39;s coffee, and chat with fellow workers before returning to one&amp;#39;s computer.&amp;nbsp; What this often means is that the user, upon returning to their computer and continuing work after a 20 minute break will find that all of the data entry they have been doing has been lost.&amp;nbsp; Worse, strange errors will begin to appear in his web browser if the loss of a session is not handled gracefully.&amp;nbsp; &lt;/p&gt;&lt;p&gt;The most common workaround is to increase the session grace period, called the session timeout.&amp;nbsp; This is set in your web.config file, and typically looks like this (the timeout period is measured in minutes):&lt;/p&gt;&lt;pre class="csharpcode"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;system.web&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;sessionState&lt;/span&gt;
      &lt;span class="attr"&gt;mode&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;InProc&amp;quot;&lt;/span&gt;
      &lt;span class="attr"&gt;cookieless&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt;
      &lt;span class="attr"&gt;timeout&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;20&amp;quot;&lt;/span&gt;
     &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;system.web&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;A second way of handling this is to add extra code to an app that keeps the session state alive even if the user isn&amp;#39;t doing anything.&lt;/p&gt;&lt;p&gt;A third, and the most common, way is to provide code that redirects a user to a &amp;quot;session expired&amp;quot; page if they try to interact with a web page for which the session has timed-out.&amp;nbsp; This can be a bit awkward, however, since it is a passive solution that can cause the user some dismay as they hit a submit key only to be taken to a completely unexpected page.&lt;/p&gt;&lt;p&gt;This post deals with an active approach to the same problem.&amp;nbsp; When the user&amp;#39;s session has expired, it will generate a popup message in the user&amp;#39;s browser window letting him know that he has been inactive for too long.&amp;nbsp; Additionally it can redirect the browser to a new page with a warning message letting him know what happened.&amp;nbsp; The user still loses all of his work, of course, but at least this way he knows what happened when he returns to his desk following his coffee break.&lt;/p&gt;&lt;p&gt;This solution uses three tricks.&amp;nbsp; One is the event model for Master Pages in ASP.NET:&amp;nbsp; whenever a Content Page is refreshed, its OnLoad event is called,&amp;nbsp; along with the OnLoad events of the Master Page and any user controls hosted by either the Content Page or the Master Page (the actual order of these events is 1. controls on the Master Page, 2. controls in the Content Page, 3. the Master Page and finally 4. the Content Page).&lt;/p&gt;&lt;p&gt;The second trick is the way ASP.NET Extensions Timer control gets reset.&amp;nbsp; This is done simply by setting the interval to a new value.&amp;nbsp; Every time the interval is set to a new value, or even the same value, the countdown on the timer begins again.&lt;/p&gt;&lt;p&gt;The third trick is that the session timeout one sets in the web.config file can be read programmatically simply by querying a property of the Session object.&lt;/p&gt;&lt;p&gt;Putting all of this together, one can build a web user control that simply sits on a Master Page and knows when the user session is ready to expire.&amp;nbsp; It resets itself to the full timeout period any time a Content Page is refreshed.&amp;nbsp; when the session expires, the user control can raise an informative message, redirect to another page, or, potentially, simply extend the session timeout (not covered here, but easy to do if you are interested).&lt;/p&gt;&lt;p&gt;A user control to monitor the session timeout is included in the code sample linked at the top of this post.&amp;nbsp; Here is how you can build your own.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h2&gt;Session Timeout Monitor Recipe:&lt;/h2&gt;&lt;p&gt;Ingredients:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;One Master Page &lt;/li&gt;&lt;li&gt;One User Control &lt;/li&gt;&lt;li&gt;An Update Panel &lt;/li&gt;&lt;li&gt;An ASP.NET Ajax Extensions Timer &lt;/li&gt;&lt;li&gt;A Panel control &lt;/li&gt;&lt;li&gt;A Button control&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;1. Create a new User Control in your project.&amp;nbsp; &lt;/p&gt;&lt;p&gt;2. Drop an Update Panel on the User Control and set its mode property to &amp;quot;Always&amp;quot;.&lt;/p&gt;&lt;p&gt;3. Add an Extensions Timer (not to be confused with the Futures TimerControl) to your project, dropping it in the Update Panel.&amp;nbsp; Name it &lt;em&gt;TimerTimeout&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Normally, this configuration of the timer control and a conditional update panel is used to refresh a portion of a web page on a regular schedule, for instance in order to create a self-updating clock display.&amp;nbsp; In this case, however, the timer and update panel are used simply to trigger a notification that the session has expired. &lt;/p&gt;&lt;p&gt;4. In the User Control&amp;#39;s code behind, add the following lines to the OnLoad event:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Page_Load(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)
        {
            &lt;span class="kwrd"&gt;int&lt;/span&gt; milliseconds = 60000;
            TimerTimeout.Interval = Session.Timeout * milliseconds;
        }&lt;/pre&gt;&lt;p&gt;This event will be called any time a content page is refreshed.&amp;nbsp; Whenever this happens, the code inside the event handler resets the AJAX Extensions Timer control to the full session lifespan as set in the web config file, in effect making the timeout for the Timer match the timeout for the session.&lt;/p&gt;&lt;p&gt;Since the Timer control&amp;#39;s Interval property is measured in milliseconds, while the session.Timeout is measured in minutes, a conversion factor of sixty thousand must be used to translate one time period into the other.&lt;/p&gt;&lt;p&gt;To finish this notifier, the Timer&amp;#39;s Tick event needs to be handled.&amp;nbsp; The Tick event gets called when the Timer&amp;#39;s Interval finally runs out.&amp;nbsp; In this implementation, the Tick event can either generate a popup message or cause a page redirect.&lt;/p&gt;&lt;p&gt;5. Place a Panel inside the Update Panel.&amp;nbsp; Set its Visible property to false.&lt;/p&gt;&lt;p&gt;6. Write a simple message inside the Update Panel, such as &amp;quot;Your session has expired.&amp;quot;&lt;/p&gt;&lt;p&gt;7. Drop a Button inside the Panel.&amp;nbsp; This Button will be used to allow the user to hide the popup message.&lt;/p&gt;&lt;p&gt;8. Add a public property to the User Control called &lt;em&gt;SessionExpiredRedirect&lt;/em&gt;:&lt;/p&gt;&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; _sessionExpiredRedirect;

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; SessionExpiredRedirect
        {
            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _sessionExpiredRedirect; }
            set { _sessionExpiredRedirect = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }
        }&lt;/pre&gt;&lt;p&gt;This will be used to set the web page to which the Timer will redirect the user upon session timeout.&amp;nbsp; If no value is set, a popup message will appear, instead.&lt;/p&gt;&lt;p&gt;9. Handle the Timer&amp;#39;s Tick event:&lt;/p&gt;&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TimerTimout_Tick(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)
        {

            &lt;span class="kwrd"&gt;if&lt;/span&gt; (!&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(SessionExpiredRedirect))
            {
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (SessionExpiredRedirect.IndexOf(&lt;span class="str"&gt;&amp;quot;~&amp;quot;&lt;/span&gt;)==0)
                    Response.Redirect(
                        VirtualPathUtility.ToAppRelative(
                        SessionExpiredRedirect));
                &lt;span class="kwrd"&gt;else&lt;/span&gt;
                    Response.Redirect(SessionExpiredRedirect);
            }
            &lt;span class="kwrd"&gt;else&lt;/span&gt;
                &lt;span class="kwrd"&gt;this&lt;/span&gt;.PanelTimeout.Visible = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
        }&lt;/pre&gt;&lt;p&gt;This handler checks to see if a value has been set for the SessionExpiredRedirect property.&amp;nbsp; If not, it makes the Panel control inside the Update Panel visible.&lt;/p&gt;&lt;p&gt;10. To make the Panel control truly popup, set its CssClass property to &amp;quot;timeoutMessage&amp;quot;.&amp;nbsp; Add the following css style to the page.&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;style&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text/css&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
.timoutMessage
{
    position:absolute;
    top:100px;
    left:200px;
    background-color:#F5F7F8;
    border-style:groove;
    border-color:Navy;
    padding:15px;
}
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;style&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;11. Finally, compile this User Control and drag it on to the Master Page.&amp;nbsp; In design mode, the user control will display a misleading exception message.&amp;nbsp; Just ignore it.&lt;/p&gt;&lt;p&gt;12. Make sure the Master Page includes an ASP.NET AJAX Script Manager component.&lt;/p&gt;&lt;p&gt;This completes the recipe.&amp;nbsp; Any Content Page in this project will now automatically include the timeout monitor you have built.&amp;nbsp; Cookies are optional: this recipe will work with a session managed either with cookies or in &lt;em&gt;cookieless&lt;/em&gt; mode.&amp;nbsp; It will only work if the session mode is &lt;em&gt;InProc&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Garnish with buttered radishes.&amp;nbsp; Serve at room temperature.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=5808" width="1" height="1"&gt;</description><category domain="http://blog.magenic.com/blogs/jamesa/archive/tags/Ajax/default.aspx">Ajax</category></item><item><title>Extending the Ajax Control Toolkit Tab Container with Lazy Loading</title><link>http://blog.magenic.com/blogs/jamesa/archive/2008/08/25/Extending-the-Ajax-Control-Toolkit-Tab-Container-with-Lazy-Loading.aspx</link><pubDate>Mon, 25 Aug 2008 15:06:00 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:5807</guid><dc:creator>Anonymous</dc:creator><slash:comments>717</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/5807.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=5807</wfw:commentRss><description>&lt;p&gt;&lt;a href="http://www.imaginativeuniversal.com/codesamples/imaginativeuniversalextenders.zip" target="_blank"&gt;download source code&lt;/a&gt;&lt;/p&gt;&lt;p&gt;ASP.NET has been missing a good, free tab control for a long time.&amp;nbsp; With the ACT Tab Container, we were finally given one.&amp;nbsp; It typically runs in client-side only mode, but can interact with server-code if we set its &lt;strong&gt;AutoPostback&lt;/strong&gt; property to true.&lt;/p&gt;&lt;p&gt;Compared to what we had before, it is a huge improvement.&amp;nbsp; The peculiar thing about it, however, is that it isn&amp;#39;t actually an Ajax control.&amp;nbsp; It doesn&amp;#39;t use asynchronous postbacks or web service calls to talk to the server -- instead you just have these two mode: run it using client script only, or run it using server-side events and code-behind only.&lt;/p&gt;&lt;p&gt;So a few months ago I rectified this for a project, and only found out afterwards that Matt Berseth had already outlined the technique on his &lt;a href="http://mattberseth.com/blog/2007/07/how_to_lazyload_tabpanels_with.html" target="_blank"&gt;blog&lt;/a&gt;.&amp;nbsp; You basically run the tab container in client-side mode, and add update panels to the tab panels that you want to be ajaxy.&amp;nbsp; You then hook up the client-side ActivePageChanged event in such a way that it spoofs the Update Panel contained in the tab, causing an asynchronous (or partial) postback.&lt;/p&gt;&lt;p&gt;Matt also gave this technique a cool name.&amp;nbsp; He called it &amp;#39;lazy loading the tab panel&amp;#39;.&amp;nbsp; Like lazy loading in OOP, using this technique the update panels inside each tab panel only do something when its tab is selected.&amp;nbsp; Information is loaded only when its needed, and not before.&lt;/p&gt;&lt;p&gt;I must admit that I hold some resentment against Matt for coming up with this first, and for coming up with the cool moniker for it.&amp;nbsp; On the other hand, the solution I came up with encapsulates all of the javascript needed for this into a nice simple extender control that you can drop on your page, which his does not, and I&amp;#39;m rather proud of this.&lt;/p&gt;&lt;p&gt;The VS 2008 project for this extender is linked at the top of this post.&amp;nbsp; To use it, you need to compile the project and add the compiled assembly to your project, or else just add the project to your solution and add a project reference.&lt;/p&gt;&lt;p&gt;1. Drop the TabContainerExtender control into your page.&lt;/p&gt;&lt;p&gt;2. Set the Extender&amp;#39;s &lt;strong&gt;TargetControlID&lt;/strong&gt; property to your TabContainer&amp;#39;s ID.&lt;/p&gt;&lt;p&gt;3. In the RegisterUpdatePanels element of the Extender, map your tabs to your update panels.&amp;nbsp; This mapping tells the extender which Update Panels to activate when each tab is selected.&lt;/p&gt;&lt;p&gt;Your markup will look something like this:&lt;/p&gt;&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc2:TabContainerExtender&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;TabContainerExtender1&amp;quot;&lt;/span&gt; 
    &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; 
    &lt;span class="attr"&gt;TargetControlID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;TabContainer1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;OnActiveTabChanged&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;ActiveTabChanged&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RegisterUpdatePanels&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc2:UpdatePanelInfo&lt;/span&gt; &lt;span class="attr"&gt;TabIndex&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;UpdatePanelID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdatePanel1&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc2:UpdatePanelInfo&lt;/span&gt; &lt;span class="attr"&gt;TabIndex&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;UpdatePanelID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdatePanel2&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc2:UpdatePanelInfo&lt;/span&gt; &lt;span class="attr"&gt;TabIndex&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;2&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;UpdatePanelID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdatePanel3&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;RegisterUpdatePanels&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;cc2:TabContainerExtender&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;4. If you want to add some code-behind to your active tab changed event, add set the OnActiveTabChanged property of the Extender to the name of your handler.&amp;nbsp; The thrown event will pass the correct Index number for the active Tab, as well as the ID of the mapped Update Panel.&amp;nbsp; The handler&amp;#39;s signature looks like this:&lt;/p&gt;&lt;blockquote&gt;&lt;div style="font-family:courier new;background:#f5f5f5;color:black;font-size:10pt;border:#000000 1px groove;padding:4px;"&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;protected&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; ActiveTabChanged(&lt;span style="color:blue;"&gt;int&lt;/span&gt; index, &lt;span style="color:blue;"&gt;string&lt;/span&gt; panelID)&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;I highly encourage you to read Matt Berseth&amp;#39;s blog entry (which I have to admit is pretty good) to get a clear idea of the techniques being applied in this ajax extender.&amp;nbsp; If you just need a quick solution, however, feel free to download this code from the link at the top and use it any way you like with no strings attached.&amp;nbsp; There is a sample project attached to the solution that will demonstrate how to use the Tab Container Extender, in case you run into any problems with lazy loading your panels.&lt;/p&gt;&lt;p&gt;For reference, here is the code for the sample implementation, which loads controls on the fly based on the tab selected:&lt;/p&gt;&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc1:TabContainer&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;TabContainer1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc1:TabPanel&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;TabPanel1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;HeaderText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Tab Panel 1&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:UpdatePanel&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdatePanel1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        Content 1 ...
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;br&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:PlaceHolder&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;PlaceHolder1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:PlaceHolder&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;      
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:UpdatePanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;    
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;cc1:TabPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc1:TabPanel&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;TabPanel2&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;HeaderText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Tab Panel 2&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:UpdatePanel&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdatePanel2&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        Content 2 ...
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;br&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:PlaceHolder&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;PlaceHolder2&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:PlaceHolder&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;      
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:UpdatePanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;    
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;cc1:TabPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc1:TabPanel&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;TabPanel3&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;HeaderText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Tab Panel 3&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:UpdatePanel&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdatePanel3&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        Content 3 ...
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;br&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:PlaceHolder&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;PlaceHolder3&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:PlaceHolder&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;      
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:UpdatePanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;    
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;cc1:TabPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;cc1:TabContainer&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc2:TabContainerExtender&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;TabContainerExtender1&amp;quot;&lt;/span&gt; 
    &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; 
    &lt;span class="attr"&gt;TargetControlID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;TabContainer1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;OnActiveTabChanged&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;ActiveTabChanged&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RegisterUpdatePanels&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc2:UpdatePanelInfo&lt;/span&gt; &lt;span class="attr"&gt;TabIndex&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;UpdatePanelID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdatePanel1&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc2:UpdatePanelInfo&lt;/span&gt; &lt;span class="attr"&gt;TabIndex&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;UpdatePanelID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdatePanel2&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc2:UpdatePanelInfo&lt;/span&gt; &lt;span class="attr"&gt;TabIndex&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;2&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;UpdatePanelID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdatePanel3&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;RegisterUpdatePanels&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;cc2:TabContainerExtender&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/blockquote&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=5807" width="1" height="1"&gt;</description><category domain="http://blog.magenic.com/blogs/jamesa/archive/tags/Ajax/default.aspx">Ajax</category></item><item><title>Ajax AutoComplete Extender with WCF</title><link>http://blog.magenic.com/blogs/jamesa/archive/2008/08/22/Ajax-AutoComplete-Extender-with-WCF.aspx</link><pubDate>Fri, 22 Aug 2008 14:41:00 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:5780</guid><dc:creator>Anonymous</dc:creator><slash:comments>651</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/5780.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=5780</wfw:commentRss><description>&lt;p&gt;The problem with conjuring tricks is that they lose practically all their glamour once you find out how they are done.&amp;nbsp; It&amp;#39;s very cool to see David Blaine walk down the street, do a few passes over his hand, and resurrect a fly which proceeds to flee.&amp;nbsp; It&amp;#39;s rather disappointing to do a google search and discover that in order to prepare for this trick, the first requirement is that you freeze a fly.&lt;/p&gt;&lt;p&gt;My trick is to make an &lt;a href="http://www.asp.net/AJAX/AjaxControlToolkit/Samples/AutoComplete/AutoComplete.aspx" target="_blank"&gt;autocomplete&lt;/a&gt; extender from the Ajax Control Toolkit call a WCF service instead of an asmx service.&amp;nbsp; For this recipe, I assume that you are already familiar with the autocomplete extender, and that you are using Visual Studio 2008.&amp;nbsp; I warn you in advance -- my trick disappoints.&amp;nbsp; It is so trivially easy that, once the technique spreads, it is very unlikely to impress your colleagues at work, much less get you a date with a &lt;a href="http://search.live.com/images/results.aspx?q=david+copperfield+claudia+schiffer&amp;amp;form=QBIR" target="_blank"&gt;supermodel&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Start by creating a new web project called AutocompleteWCF.&amp;nbsp; Add a reference to the &lt;em&gt;AjaxControlToolkit.dll&lt;/em&gt;.&amp;nbsp; Open up the default aspx page that is generated with your project, and add the following code to:&lt;/p&gt;&lt;p&gt;&lt;span class="kwrd"&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;form1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:ScriptManager&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;ScriptManager1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:ScriptManager&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:TextBox&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;myTextBox&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;autocomplete&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;off&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ajaxToolkit:AutoCompleteExtender&lt;/span&gt;
                &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; 
                &lt;span class="attr"&gt;BehaviorID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;AutoCompleteEx&amp;quot;&lt;/span&gt;
                &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;autoComplete1&amp;quot;&lt;/span&gt; 
                &lt;span class="attr"&gt;TargetControlID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;myTextBox&amp;quot;&lt;/span&gt;
                &lt;span class="attr"&gt;ServicePath&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Autocomplete.svc&amp;quot;&lt;/span&gt; 
                &lt;span class="attr"&gt;ServiceMethod&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;GetCompletionList&amp;quot;&lt;/span&gt;
                &lt;span class="attr"&gt;MinimumPrefixLength&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt; 
                &lt;span class="attr"&gt;CompletionInterval&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1000&amp;quot;&lt;/span&gt;
                &lt;span class="attr"&gt;EnableCaching&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ajaxToolkit:AutoCompleteExtender&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;This is the standard demo code that is shipped with the Ajax Control Toolkit Sample Website.&amp;nbsp; I&amp;#39;ve simplified it a bit by removing the animations.&amp;nbsp; The only significant change I&amp;#39;ve made is to change the ServicePath from &lt;em&gt;Autocomplete.asmx&lt;/em&gt; to &lt;em&gt;Autocomplete.svc&lt;/em&gt;, the latter being the extension for a WCF service.&lt;/p&gt;&lt;p&gt;The next step is to create our service and add a GetCompletionList operation to it.&amp;nbsp; The easiest way to do this is to go to Add | New Item and just select the &lt;em&gt;Ajax-enabled WCF Service&lt;/em&gt; item template, but this would be so easy that it is hardly worth doing.&lt;/p&gt;&lt;p&gt;Instead, create a new WCF Service using the &lt;em&gt;WCF Service &lt;/em&gt;Item Template and call it Autocomplete.svc.&amp;nbsp; Visual Studio will automatically generate a service interface for you.&amp;nbsp; Delete the interface.&amp;nbsp; We don&amp;#39;t need it.&amp;nbsp; (To be more specific, I don&amp;#39;t know how to get this to work with an interface, so I&amp;#39;m just going to ignore that it is possible.)&lt;/p&gt;&lt;p&gt;Again, I am going to rip off the ACT sample app and just borrow the code from their webservice and place it in our WCF service.&amp;nbsp; The WCF service class (&lt;em&gt;Autocomplete.svc.cs&lt;/em&gt;) will look like this:&lt;/p&gt;&lt;div style="font-family:courier new;background:#f5f5f5;color:black;font-size:10pt;border:#000000 1px groove;padding:4px;"&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color:#2b91af;"&gt;ServiceContract&lt;/span&gt;(Namespace = &lt;span style="color:#a31515;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)]&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color:#2b91af;"&gt;AspNetCompatibilityRequirements&lt;/span&gt;(RequirementsMode = &lt;span style="color:#2b91af;"&gt;AspNetCompatibilityRequirementsMode&lt;/span&gt;.Allowed)]&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Autocomplete&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color:#2b91af;"&gt;OperationContract&lt;/span&gt;]&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt;[] GetCompletionList(&lt;span style="color:blue;"&gt;string&lt;/span&gt; prefixText, &lt;span style="color:blue;"&gt;int&lt;/span&gt; count)&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (count == 0)&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&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; count = 10;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (prefixText.Equals(&lt;span style="color:#a31515;"&gt;&amp;quot;xyz&amp;quot;&lt;/span&gt;))&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&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; &lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt;[0];&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Random&lt;/span&gt; random = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Random&lt;/span&gt;();&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;string&lt;/span&gt;&amp;gt; items = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;string&lt;/span&gt;&amp;gt;(count);&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;for&lt;/span&gt; (&lt;span style="color:blue;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; count; i++)&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&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; &lt;span style="color:blue;"&gt;char&lt;/span&gt; c1 = (&lt;span style="color:blue;"&gt;char&lt;/span&gt;)random.Next(65, 90);&lt;/p&gt;&lt;p style="margin:0px;"&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; &lt;span style="color:blue;"&gt;char&lt;/span&gt; c2 = (&lt;span style="color:blue;"&gt;char&lt;/span&gt;)random.Next(97, 122);&lt;/p&gt;&lt;p style="margin:0px;"&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; &lt;span style="color:blue;"&gt;char&lt;/span&gt; c3 = (&lt;span style="color:blue;"&gt;char&lt;/span&gt;)random.Next(97, 122);&lt;/p&gt;&lt;p style="margin:0px;"&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; items.Add(prefixText + c1 + c2 + c3);&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; items.ToArray();&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;&lt;p&gt;A few things worth noting:&lt;/p&gt;&lt;p&gt;1. Autocomplete does not implement the IAutocomplete Interface.&amp;nbsp; Even though this is generated automatically, with the WCF Service item template, you should remove it.&lt;/p&gt;&lt;p&gt;2. The service contract has a blank Namespace explicitly declared.&amp;nbsp; &lt;/p&gt;&lt;p&gt;3. The &lt;em&gt;ASPNetCompatibilityRequirements&lt;/em&gt; attribute must be added to our class.&lt;/p&gt;&lt;p&gt;This takes care of the code that calls the WCF service, as well as the service itself.&amp;nbsp; We now have rig up the web.config file.&amp;nbsp; If you&amp;#39;ve been working with WCF for any length of time, then you know that this is where the problems usually occur.&amp;nbsp; Fortunately, the configuration is fairly simple.&amp;nbsp; You need to set up an endpoint behavior for your service that enables web scripting (much the way asmx web services must be decorated with the &lt;em&gt;ScriptService&lt;/em&gt; attribute in order to be called from client-script).&amp;nbsp; You also will need to turn AspNetCompatibilityEanbled on for the hosting environment.&lt;/p&gt;&lt;div style="font-family:courier new;background:#f5f5f5;color:black;font-size:10pt;border:#000000 1px groove;padding:4px;"&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;behaviors&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;endpointBehaviors&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&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;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;behavior&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;AjaxBehavior&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&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;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;enableWebScript&lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&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;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;behavior&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;endpointBehaviors&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;behaviors&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;serviceHostingEnvironment&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;aspNetCompatibilityEnabled&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;true&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;services&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;service&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;AutocompleteWCF.Autocomplete&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&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;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;endpoint&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;address&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;behaviorConfiguration&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;AjaxBehavior&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;binding&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;webHttpBinding&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;contract&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;AutocompleteWCF.Autocomplete&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;service&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;services&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;And that is all you need to do make the AutoComplete Extender work with a WCF service instead of an asmx web service.&amp;nbsp; I told you it would be unimpressive.&lt;/p&gt;&lt;p&gt;Of course, using a WCF service for Ajax has all the limitations that using an asmx file for Ajax did.&amp;nbsp; First of all, you can&amp;#39;t call a service that is in a different domain than the page which hosts your client-code.&amp;nbsp; This is a security feature, to prevent malicious code from redirecting your harmless javascript to something nasty on the world wide web.&lt;/p&gt;&lt;p&gt;Second, you can&amp;#39;t call just any service from your client-side code.&amp;nbsp; The service must be explicitly marked as something that can be called from client code.&amp;nbsp; In asmx web services, we used ScriptService for this.&amp;nbsp; In WCF services, we similarly use EnableWebScript binding property. &lt;/p&gt;&lt;p&gt;Now I feel like I&amp;#39;ve wasted your time, so here&amp;#39;s a YouTube &lt;a href="http://www.youtube.com/watch?v=s7Wvk-CVN-Y" target="_blank"&gt;video&lt;/a&gt; of David Blaine to make up for it.&amp;nbsp; And remember, David Blaine is to Chris Angel what Daisy Duke was to Alexis Carrington.&amp;nbsp; It&amp;#39;s an existential thing, and at some point, you&amp;#39;ve just got to pick sides and stay put in a way that will determine who you are for the rest of your life.&lt;/p&gt;&lt;p&gt;Are you a David Blaine/Daisy Duke kind of person or are you a Chris Angel/Alexis Carrington sort?&amp;nbsp; Do some soul searching and please let me know what you learn about yourself.&lt;/p&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=5780" width="1" height="1"&gt;</description><category domain="http://blog.magenic.com/blogs/jamesa/archive/tags/Ajax/default.aspx">Ajax</category></item></channel></rss>