Welcome to

Magenic Technologies Community Blog

Sign in | Join | Help

Outsourcing to Sleestak

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.

Covariance and Contravariance In 5 Minutes

C# 4.0 will introduce new language features to help manage covariance and contravariance.  While this is a a wonderful capability, it forces us to come to terms with these (to me) somewhat unfamiliar terms.

As I have been working through Eric Lippert’s excellent series of posts on this topic as well as the wikipedia entry, 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.  If this appears to be a rehash of Eric Lippert’s work, this is probably because it is.  Consequently, any mistakes are purely mine, while any virtue in this explanation is very much due to him.

First, however, it is necessary to learn some vocabulary.

Take the following class hierarchy:

        public class Animal{}
        public class Mammal : Animal { }
        public class Tiger : Mammal { }

We would typically say that Mammal is more derived than Animal.  Mammal, conversely, is less derived than Tiger in this inheritance chain.

To understand covariance and contravariance, we need to replace more derived and less derived with the metaphorical terms smaller and bigger.

We do this because more derived and less derived are not adequate to describe the relation between objects such as arrays of types.

        Animal[] A;
        Mammal[] M;
        Tiger[] T;

An array of Mammal does not derive from an array of Animal.  Both Mammal[] and Animal[] are derived from System.Array. There is no inheritance relation, however, between Mammal[] and Animal[] themselves.  Nevertheless there is obviously some sort of relation present.  By convention, we call this relation a smaller than \ greater than relation.  Mammal[] is smaller than Animal[] because Mammal is more derived than Animal.  It is bigger than Tiger[] because Mammal is less derived than the type Tiger.

It is worth repeating that smaller and bigger are not the same thing as the relation between classes in an inheritance hierarchy.  They also do not have anything directly to do with memory management.  They are pure metaphors.

The C# classes above model concepts.  When we talk about concepts such as animal, mammal and tiger, we talk about these concepts falling under each other.  Socrates falls under the concept of man.  Man falls under the concept of an animal (traditionally, man is defined as a bipedal, hairless animal that laughs; see Haecceity).

Metaphorically, we can think of animal as a bigger concept than mammal because many more things fall under animal than under mammal.  Tiger, in turn, is a smaller concept than mammal because so few things fall under it.

Once we have smaller than and bigger than under our belts, we can start talking about covariance and contravariance.  Covariance and contravariance, at the most basic level, concerns the assignment of types to variables.

An assignment is covariant if we are assigning a smaller type to a bigger type:

covariance

When we assign a bigger type to a smaller type, the assignment is said to be contravariant:

contravariance

1. Covariance with simple reference types

An example will help to illustrate this. 

    Mammal m = new Tiger();
    Animal a = m;
    //Tiger t = a;  -- will not compile

We can assign a smaller type, Tiger to a variable allocated as a Mammal.  Similarly we can assign our Mammal instance to a variable allocated as an Animal.  In other words, in the assignment of simple reference types, we can assign smaller things to bigger things.  This is a covariant relation.

We cannot, however, assign an Animal instance to a Tiger.  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.  The assignment of simple reference types is therefore not covariant.

2. Covariance with arrays

The C# compiler also happens to allow covariant array assignments.  For instance:

    Mammal[] M = new Tiger[0];
    Animal[] A = M;
    //Tiger[] t = A;  -- will not compile

The compiler doesn’t need to allow this.  It just happens to.  What’s interesting is that the compiler will not allow us to do the same thing with generic collections. 

3. Invariance with generics

Assignment of generics is invariant in C# 3.

    // List<Mammal> mammals = new List<Tiger>(); -- will not compile
    // List<Animal> animals = mammals; -- will not compile
    // List<Tiger> tigers = animals;  -- will not compile
    //

4. Covariance with method parameters

Parameter assignment also happens to be covariant in C#.  To prove it to yourself, take the following static method:

     public static void TakeMammal(Mammal m){}

Which of the following operations is permissible in C# and which is not?

    TakeMammal(new Tiger());

    TakeMammal(new Animal());

    TakeMammal(new Mammal());

(Note, however, that ref and out parameters are invariant: http://blogs.msdn.com/ericlippert/archive/2009/09/21/why-do-ref-and-out-parameters-not-allow-type-variation.aspx .)

5. Delegate contravariance with respect to inputs

Understanding this characteristic of parameter assignments is important in order to demonstrate how contravariance occurs in C#.  In C#, delegate assignments are contravariant with respect to inputs.  Consider this code:

 public static void TakeAnimal(Animal a) {}
 public static void TakeMammal(Mammal m){}
 public static void TakeTiger(Tiger t) {}

public delegate void MammalHandler(Mammal m);

MammalHandler funcA = TakeAnimal; //OK
MammalHandler funcM = TakeMammal; //OK
MammalHandler funcT = TakeTiger;  //No!

            funcA(new Mammal()); //OK
            funcM(new Mammal()); //OK
            funcT(new Mammal()); //No!

The delegate method MammalHandler is designed to only take the Mammal type as input.  Any delegate instance – funcA, funcM, funcT – in turn may be passed Mammal objects.  If we pass a Mammal to delegate instance funcA, it ultimately gets passed to our TakeAnimal method.  Since parameter assignments – as we showed above – are covariant, passing a Mammal to TakeAnimal is permissible.  Obviously passing a Mammal to TakeMammal is also permissible.

We cannot, however, pass a Mammal to TakeTiger.  The C# compiler does not allow this.

Consequently, we also cannot assign TakeTiger to our MammalHandler delegate.  Assigning TakeTiger to funcT is illegal.

But in this impermissible delegate assignment, which thing is bigger: MammalHandler or TakeTiger?  MammalHandler, right?  With regard to delegate assignments, then, we are saying that assigning something smaller to something bigger is not allowed.  Assigning something bigger to something smaller, however, is permissible.

Delegate assignments like those above are therefore contravariant.

6. Delegate covariance with respect to return types

I say “like those above” because this is actually true only with respect to delegate inputs.  Delegates can also, of course, return objects – and when they do, this is a covariant relation.  Delegate assignments are said to be contravariant with respect to inputs, but covariant with respect to return values.  You can prove this to yourself by looking through the following code in which the delegate signature has a return value but no parameters.

 

public static Animal GetAnimal() {} public static Mammal GetMammal(){} public static Tiger GetTiger() {} public delegate Mammal GetMammalDelegate(); GetMammalDelegate funcA = GetAnimal; // No! GetMammalDelegate funcM = GetMammal; // OK GetMammalDelegate funcT = GetTiger; // OK

 

 

 

So why is this important for understanding C# 4.0?  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<T> as an invariant operation. This is obviously a little weird.  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<out T> could be implemented that would provide the sort of covariance now supported for arrays.

by Anonymous | 116 Comments

A Lazier Singleton with .NET 4.0

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.   I do not mean to imply that they are wrong – it’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.

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 ‘em.

The best source for design patterns in C# is probably Judith Bishop’s C# 3.0 Design Patterns published by O’Reilly Press, which provides C# versions of all 23 patterns from the Gang of Four’s Elements of Reusable Object-Oriented Software.  The elegant implementation of the Singleton pattern she recommends looks like this:

public sealed class Singleton {
   // Private Constructor
   Singleton( ) { }

   // Private object instantiated with private constructor
   static readonly Singleton instance = new Singleton( );

   // Public static property to get the object
   public static Singleton Instance {
          get { return instance;}
       }
}

 

There is a problem with this, however.  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 instance happens at an unexpected point.  For an interesting if somewhat dense read on the effect of the beforeFieldInit flag, go here.

I will simply demonstrate the problem by adding some tracking code to Judith Bishop’s recommended implementation:

    public sealed class Singleton
    {
        private static readonly Singleton instance = new Singleton();
        private Singleton()
        {
            // no default constructor
            Console.WriteLine(" >> singleton initialized");
        }

        public static Singleton Instance
        {
            get
            {
                Console.WriteLine("before singleton retrieval");
                return instance;

            }
        }
    }

I will retrieve an instance of this Singleton class from a console application like so:

    class Program
    {
        static void Main(string[] args)
        {

            Console.WriteLine("Calling Singleton instance");
            var s = Singleton.Instance;
            Console.WriteLine("Finished calling Singleton instance");
            Console.ReadLine();
        }
    }
When will the private type be initialized? When will the private constructor be called?  In what order do you think the Console.WriteLines will be invoked?

Ideally the static members of this class would be initialized only when we needed them, and the output would be:

  1. Calling Singleton instance
  2. before singleton retrieval
  3. >> singleton initialized
  4. Finished calling Singleton instance

In actuality, however, this is the result:

singlton_results_1

This is not so bad, you may be thinking.  If our singleton is a large object this creates some additional strain to the system – but as long as the Singleton instance gets used fairly soon after it is instantiated it’s no big deal.

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 beforeFieldInit – like this:

        public static void Test()
        {
            Console.WriteLine("testing singleton");
        }

and rewrote the calling code like this:

            Console.WriteLine("Calling Singleton test method");
            Singleton.Test();
            Console.WriteLine("Calling Singleton instance");
            var s = Singleton.Instance;
            Console.WriteLine("Finished calling Singleton instance");
            Console.ReadLine();

It may not be immediately obvious but I have seriously messed up your code.  Here is the output:

 

singlton_results_2

Even if we never retrieve the Singleton instance, it will still be initialized when any other static method on our type is called – this is commonly known as a language runtime bummer.

.NET 4.0 introduces a new generic type called Lazy which helps us out of this dilemma.  Lazy is a wrapper class that facilitates thread safe, lazy instantiation of objects.  We can use it to create a new Singleton implementation that replaces the private static Singleton instance with a private static Lazy<Singleton>  instance.  The Instance property will also require a small rewrite to pull our Singleton out of the Lazy wrapper.

The full implementation of the lazy version of the singleton looks like this:

    public sealed class LazySingleton
    {
        // Private object with lazy instantiation
        private static readonly Lazy<LazySingleton> instance = 
            new Lazy<LazySingleton>(
                delegate { 
                    return new LazySingleton(); 
                }
                //thread safety first
                ,LazyExecutionMode.EnsureSingleThreadSafeExecution);

        private LazySingleton()
        {
           // no public default constructor
        }

        // static instance property
        public static LazySingleton Instance
        {
            get{ return instance.Value; }
        }
    }

Some things of note:

1. I pass a delegate as the first parameter to the Lazy constructor. There is a no parameter constructor for the generic Lazy<T> class, but it requires that type T have a public default constructor – which I obviously do not want to provide.  The delegate parameter allows me to indicate that I want to use a different constructor – in order to pass a constructor parameter to Type T, for instance, or to invoke a private constructor, in this case – than the default. 

2. The second parameter, also optional, tells the Lazy instance that I want the lazy instantiation of type T to be thread safe.

3. I retrieve the wrapped type T by asking for the Lazy type’s Value property.

Now it’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.  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:

    Console.WriteLine("Calling Singleton test method");
    Singleton.Test();
    Console.WriteLine("Calling Singleton instance");
    var s = Singleton.Instance;
    Console.WriteLine("Finished calling Singleton instance");
    Console.WriteLine();

    Console.WriteLine("Calling Lazy Singleton test method");
    LazySingleton.Test();
    Console.WriteLine("Calling Lazy Singleton instance");
    var lazyS = LazySingleton.Instance;
    Console.WriteLine("Finished calling Lazy Singleton instance");
    Console.ReadLine();

and get the following, very pleasing, results:

singlton_results_3

Now that’s lazy!

by Anonymous | 836 Comments

Filed under:

Synchronizing Style Hierarchies with Control Hierarchies in WPF

WPF provides two ways to apply styles to control elements: by name and by type.  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.  For instance, a style declaration for a ComboBox would look like this:

<Style x:Key="ComboBoxStyle" TargetType="ComboBox">
    ...
</Style>
.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; }

When styles are applied in this way, the underlying WPF rendering mechanism understands type hierarchies.  Consequently, this style could also be written with a TargetType higher up in the Control type hierarchy and still work:

<Style x:Key="ComboBoxStyle" TargetType="Control">
   ...
</Style>

This is a handy feature when you want to build a custom control but want to preserve your styles.  For instance, the ComboBox control has no built-in ability to trigger commands.  If you want to use MVVM, however, this is quite a shortcoming.  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:

class CustomComboBox: ComboBox, ICommandSource
{
     ...
}

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:

<Window x:Class="SampleWPFProject.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sys="clr-namespace:System;assembly=System"
    xmlns:custom="clr-namespace:SampleWPFProject"
    Title="Window1" Height="300" Width="300">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="25"/>
        <RowDefinition Height="25"/>
    </Grid.RowDefinitions>
    <StackPanel Grid.Row="0" Name="stackPanel1" Orientation="Horizontal">
        <TextBlock Margin="0,0,10,0" Width="60">Employees</TextBlock>
        <ComboBox x:Name="cbEmployees" SelectedIndex="0" Width="200" 
                  Style="{StaticResource ComboBoxStyle}">
            <ComboBoxItem>John Adams</ComboBoxItem>
            <ComboBoxItem>Ben Franklin</ComboBoxItem>
            <ComboBoxItem>Pat Henry</ComboBoxItem>
        </ComboBox>
    </StackPanel>
    <StackPanel Grid.Row="1" Name="stackPanel2" Orientation="Horizontal">
        <TextBlock Margin="0,0,10,0" Width="60">Tasks:</TextBlock>
        <custom:CustomComboBox x:Name="cbTasks" SelectedIndex="0" Width="200" 
                   Style="{StaticResource ComboBoxStyle}">
            <ComboBoxItem>Write Constitution</ComboBoxItem>
            <ComboBoxItem>Write Declaration</ComboBoxItem>
            <ComboBoxItem>Go for a ride</ComboBoxItem>
        </custom:CustomComboBox>
    </StackPanel>
</Grid>
</Window>

.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.

But what if I want to apply my custom style arbitrarily to all ComboBoxes in my application?  This is where typed styles are very handy.

I can change the “key” element of the ComboBoxStyle to apply it generically to all ComboBoxes like this:

<Style x:Key="{x:Type ComboBox}" TargetType="ComboBox">
   ...
</Style>

.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:

<ComboBox x:Name="cbEmployees" SelectedIndex="0" Width="200">
   ...
<custom:CustomComboBox x:Name="cbTasks" SelectedIndex="0" Width="200">
.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; }

Unfortunately, the typed style does not understand that my CustomComboBox inherits from the ComboBox type. While the base ComboBox is rendered with my style,  the appearance of the CustomComboBox reverts to the default ComboBox specified by WPF for my OS.

I could simply copy the entire original style and create a new one that specifies the CustomComboBox as the key, instead.  There is a shorter way, however.  I can take advantage of the BasedOn attribute of the style resource.  Rather than copy the entire style, I will create a new style based the original style and set the key to our custom type:

<Style x:Key="{x:Type ComboBox}" TargetType="ComboBox">
   ...
</Style>

<Style BasedOn="{StaticResource {x:Type ComboBox}}"  
       x:Key="{x:Type custom:CustomComboBox}" 
       TargetType="ComboBox"/>
.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; }

Typically the BasedOn attribute is used to extend a certain base style with certain changes: for instance, off of a base style that sets  Button backgrounds to blue, one might want to create another that overrides the background color and set it to orange.

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.  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.

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.

by Anonymous | 0 Comments

Alternatives to returning Void: Continued

“If you look long enough into the void the void begins to look back through you." – Nietzsche

Returning types rather than void on methods that do not necessarily require a return value, as occurs in the implementation of the Append methods on the StringBuilder, allows us to do some interesting method chaining in our code.

Bill Wagner suggests doing something similar with collections in More Effective C# .  My examples are a bit more contrived, however.

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.  We could write the following custom collection to do this:

    public class Prices: IEnumerable<decimal>
    {
        private List<decimal> _mySequence;
        public Prices()
        {
            _mySequence = new List<decimal>();
        }
        public Prices Add(decimal d)
        {
            _mySequence.Add(d);
            return this;
        }
        public IEnumerator<decimal> GetEnumerator()
        {
            foreach (decimal d in _mySequence)
                yield return d;
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            foreach (decimal d in _mySequence)
                yield return d;
        }
        public Prices AddSixPercentAndWrite()
        {
            foreach(decimal d in _mySequence)
                Console.WriteLine(string.Format("{0:C}",d * 1.06m));
            return this;
        }
    }

Which we would then call thus:

        var prices = new Prices();
        for(decimal d = 0; d< 20m;d++)
        {
            prices.Add(d);
        }
        prices.AddSixPercentAndWrite();
 

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. 

Besides our original output, we now also need to be able to push a list that looks something like this:

$0.00 $0.00
$1.00 $1.06
$2.00 $2.12
$3.00 $3.18
$4.00 $4.24
$5.00 $5.30
$6.00 $6.36
$7.00 $7.42
$8.00 $8.48
$9.00 $9.54
$10.00 $10.60
$11.00 $11.66
$12.00 $12.72
. . .

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.

We could restructure the AddSixPercent method to take a parameter; we could then break out the Write method so we can call it multiple times if needed.  We could also change the signatures on our methods to return our Prices collection instead of void, allowing us to chain the methods together.

There’s a hitch, however.  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.  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.

. . .
$12.00
$13.00
$14.00
$15.00
$16.00
$17.00
$18.00
$19.00
$0.00
$1.06
$2.12
$3.18
$4.24
$5.30
$6.36
$7.42
$8.48
$9.54
$10.60
$11.66
$12.72
. . .

By using iterators, on the other hand, every method in our chain would act on a particular iteration rather than on the whole sequence.  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.

If we are to use iterators, however, we can’t return the Prices type.  Instead we have to return an IEnumerable type.  Leaving the rest of our Prices custom collection class alone, here’s what that new code would look like:

public static IEnumerable<decimal> AddXPercent(IEnumerable<decimal> sequence
    , short percent)
{
    foreach (decimal d in sequence)
        yield return d + (d * percent * .01m);
}
 
public static IEnumerable<decimal> WriteToConsole(IEnumerable<decimal> sequence)
{
    foreach (decimal d in sequence)
    {
        Console.Write(string.Format("{0:C} ", d));
        yield return d;
    }
}

Our calling code, in turn, would look like this:

    foreach (decimal d in Prices.WriteToConsole(
        Prices.AddXPercent(
        Prices.WriteToConsole(
        prices), 6)
            )
        )
        Console.WriteLine();
 

We’ve managed to achieve chaining, but not so elegantly, all things considered.  First, we have to include the name of our Type in order to chain our methods together.  Second, the chaining is done with nested methods instead of the clean With-like syntax I was extolling in the previous post.  Finally, the sequence of activity isn’t particularly clear.  Because we are chaining our methods by using nesting, the innermost nested method occurs first, while the first shall be processed last.

Fortunately extension methods allow us to alter the way our methods are called.  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:

    public static class PricesExtension
   {
        public static IEnumerable<decimal> AddXPercent(
            this IEnumerable<decimal> sequence
            , short percent
            ) 
        {
            foreach (decimal d in sequence)
                yield return d + (d * percent * .01m);
        }
 
        public static IEnumerable<decimal> WriteToConsole(
            this IEnumerable<decimal> sequence
            )
        {
            foreach (decimal d in sequence)
            {
                Console.Write(string.Format("{0:C} ", d));
                yield return d;
            }
        }
    }

Giving us the results we were looking for:

$0.00 $0.00
$1.00 $1.06
$2.00 $2.12
$3.00 $3.18
$4.00 $4.24
$5.00 $5.30
$6.00 $6.36
$7.00 $7.42
$8.00 $8.48
$9.00 $9.54
$10.00 $10.60
$11.00 $11.66
$12.00 $12.72
. . .

 

We can now call our code like this:

    foreach(var d in prices
            .WriteToConsole()
            .AddXPercent(6)
            .WriteToConsole()
            )
            Console.WriteLine();

This alternative to returning void involves three tricks:

1) Returning an IEnumerable type instead of void.

2) Taking an IEnumerable type as a parameter.

3) Using these signatures in extension methods rather than the custom collection class itself.

If the syntax looks familiar, this is because this is also how LINQ to Objects is implemented.  For that very reason, we could have accomplished similar results by using LINQ:

    foreach(var d in prices
        .Select(d => { Console.Write(string.Format("{0:C} ", d)); return d; })
        .Select(d => d + (d * 6 * .01m))
        .Select(d => { Console.Write(string.Format("{0:C} ", d)); return d; })
        )
    {
        Console.WriteLine();
    }

It’s funky code, no doubt, but I also find it highly compelling.  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.  Inside the foreach block, I then perform any follow-up operations: in this case, writing a new line.

by Anonymous | 3 Comments

Alternatives to returning Void

I was playing with the Unity Framework recently when I came across the following C# code sample on msdn:

    IUnityContainer uContainer = new UnityContainer()
        .RegisterType<IMyInterface, FirstObject>()
        .RegisterType<MyBaseClass, SecondObject>();
    MyObject myInstance = uContainer.Resolve<MyObject>();

This looked so much like the VB With syntax that I uncharitably assumed that the authors at MSDN had somehow confused C# and VB.  After all, they had written this the standard C# syntax elsewhere:

    // Create container and register types
    IUnityContainer myContainer = new UnityContainer();
    myContainer.RegisterType<IMyService, DataService>("Data");
    myContainer.RegisterType<IMyService, LoggingService>("Logging");
 
    // Retrieve an instance of each type
    IMyService myDataService = myContainer.Resolve<IMyService>("Data");
    IMyService myLoggingService = myContainer.Resolve<IMyService>("Logging");

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.  I did the former, and for the most part have never looked back.  I don’t even get involved in disputes between C# lovers and VB lovers.  They’re both nice language.  I just happen to use the former for most things.

The one thing I do miss from VB, however, is the With command.  It always seemed an elegant piece of syntactic sugar and easier to read when you find code that manipulates the same object repeatedly.  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.

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 RegisterType method is returning an IUnityContainer object.  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.  In fact, the Append method of the StringBuilder type similarly returns its own container type, making the following code blocks equivalent:

    StringBuilder sb = new StringBuilder();
 
    // this code ...
    sb.AppendLine("one");
    sb.AppendLine("two");
    sb.AppendLine("three");
 
    // is equivalent to this ...
    sb.AppendLine("one").AppendLine("two").AppendLine("three");
 
    // is equivalent to this ...
    sb.AppendLine("one")
      .AppendLine("two")
      .AppendLine("three");

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.

by Anonymous | 0 Comments

WCF REST Starter Kit Complete Twitter Library

 

Source

Binaries

Ingredients: Visual Studio 2008, .NET 3.5 sp1, WCF REST Starter Kit 2

The HttpClient type, included with the WCF REST Starter Kit 2, is intended to make it easier to consume RESTful services.   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.

Retrieving statuses from Twitter, as well as sending updates, is extremely easy using the WCF REST Starter Kit, as I posted earlier.  This led me to want to see if I could build out a client library for the rest of the Twitter REST API. 

This projected one night effort ended up taking about a week and a half over several evenings.  For the most part, this was because actually building and testing the various contract objects is remarkably labor intensive.

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.

If you want to just consume the binaries, you will need to download the WCF REST Starter Kit Preview 2 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 .

The Windows Twitter Foundation library has several features I’m rather proud of:

1. It reads both XML and JSON formats.  The client application included with the source code switches between these two API’s with either the /XML command or the /JSON command.

2. The library covers the complete Twitter REST API, including direct messaging and photo uploads.  The photo uploads are particularly finicky and took a couple nights alone just to figure out.

3. The library also consumes the Twitter Search API.  The data contracts for Trending was a bit too strange for me to figure out, however.

4. The CLR classes used for deserializing Twitter messages is included in a separate assembly.  They are decorated for both XML and DataContract deserialization.  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.

5. I built most of it in my installation of Windows 7.  Visual Studio worked like a charm.

Things I feel bad about:

1. I couldn’t figure out how to deserialize the Trends service messages. 

2. I used waaaay too many yellows and greens in the Console Application that comes with the source.

Please use this code freely and in any way you like.  Be sure to consult the WCF REST Starter Kit 2 license on codeplex for any rights reserved by Microsoft.

Future plans:

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.

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).

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).

I've been enjoying the TweetDeck client, but so far haven’t seen anything in it that can’t be done using WPF.  I should be able to make a UI that is at least as attractive (glossy black controls are pretty straightforward in PF, right?).  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.  Using Prism would also be fun, but we’ll see.

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.  Enabling users to start talking instead of typing their tweets may have interesting ramifications if it ever catches on.  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.

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  a “follower” is.

Again, enjoy the code.

by Anonymous | 5 Comments

Getting Started with the WCF REST Starter Kit Preview 2 HttpClient

Ingredients: Visual Studio 2008 SP1 (C#), WCF REST Starter Kit Preview 2

In Preview 1 of the WCF REST Starter Kit, Microsoft provided many useful tools for building RESTful services using WCF.  Missing from those bits was a clean way to call REST services from the client.  In Preview 2, which was released on March 13th, this has been made up for with the HttpClient class and an add-in for the Visual Studio IDE called Paste XML as Types.

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).  If you haven't downloaded and installed the WCF REST Starter Kit, yet, you can get Preview 2 here.

The sample solution will include two projects, one for the client and one for the service. 

1. Start by creating a Console Application project and solution called RESTfulClient.

2. Add a new project to the RESTfulClient solution using the Http Plain XML WCF Service project template that was installed when you installed the Starter Kit.  Call your new project POXService. 

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.  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.

 

For this recipe, we will just use the default service as it is. 

[WebHelp(Comment = "Sample description for GetData")]

[WebGet(UriTemplate = "GetData?param1={i}&param2={s}")]

[OperationContract]

public SampleResponseBody GetData(int i, string s)

{

 

   return new SampleResponseBody()

   {

     Value = String.Format("Sample GetData response:"   {0}', '{1}'", i, s)

   };

}

For the most part, this is a pretty straightforward WCF Service Method.  There are some interesting additional elements, however, which are required to make the service REST-y.

(In a major break with convention, you will notice that the default service created by this template is called Service rather than Service1.  I, for one, welcome this change from our new insect overlords.)

The WebGet attribute, for instance, allows us to turn our service method into a REST resource accessed using the GET method.  The UriTemplate attribute parameter specifies the partial Uri for our resource, in this case GetData.  We also specify in the UriTemplate how parameters can be passed to our resource.  In this case, we will be using a query string to pass two parameters, param1 and param2.

By default, the template provides a Help resource for our service, accessed by going to http://localhost:<port>/Service.svc/Help .  It will automatically include a description of the structure of our service.  The WebHelp attribute allows us to add further notes about the GetData resource to the Help resource.

You will also notice that the GetData service method returns a SampleResponseBody object.  This is intended to make it explicit in our design that we are not making RPC's.  Instead, we are receiving and returning messages (or documents, if you prefer).  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.

public class SampleResponseBody
{
    public string Value { get; set; }
}

3. Right click on the PoxService project and select Debug | Start New Instance to see what our RESTful service looks like.  To see what the service does, you can browse to http://localhost:<port>/Service.svc/Help .  To see what the schema for our GetData resouce looks like, go to http://localhost:<port>/Service.svc/help/GetData/response/schema .  Finally, if you want to go ahead and call the GetData service, browse to http://localhost:<port>/Service.svc/GetData .

(In the rest of this tutorial, I will simply use  port 1300, with the understanding that you can specify your own port in the code.  By default, Visual Studio will randomly pick a port for you.  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 Web tab.)

<SampleResponseBody xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Value>Sample GetData response: '0', ''</Value> 
</SampleResponseBody>

4. Go to the RESTfulClient project and add a new class called SampleResponseBody.  We are going to create a type for deserializing our SampleResponseBody XML element.  We could write out the class by hand, and prior to Preview 2 we probably would have had to.  It is no longer necessary, however.  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 http://localhost:1300/Service.svc/GetData you can simply paste this into our SampleResponseBody.cs file by going to the Visual Studio Edit menu and selecting Paste XML to Types.  To get all the necessary types in one blow, you can also go to http://localhost:1300/Service.svc/Help and use Paste XML to Types.  As a third alternative, just copy the XML above and try Paste XML to Types in your SampleResponseBody class.  However you decide to do it, you are now in a position to translate XML into CLR types.

Your generated class should look like this:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.3053")]

[System.Diagnostics.DebuggerStepThroughAttribute()]

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]

[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]

public partial class SampleResponseBody

{

 

        private string valueField;

 

        /// <remarks/>

        public string Value

        {

            get

            {

                return this.valueField;

            }

            set

            {

                this.valueField = value;

            }

        }

}

 

5.  Next, we need to add the Starter Kit assemblies to our console application.  The default location for these assemblies is C:\Program Files\Microsoft WCF REST\WCF REST Starter Kit Preview 2\Assemblies .  The two assemblies we need for the client are Microsoft.Http.dll and Microsoft.Http.Extensions.dll .  (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).

6. We will now finally add some code to call call our GetData resource using the HttpClient class.  The following code will simply prompt the user to hit {Enter} to call the resource.  It will then return the deserialized message from the resource and prompt the user to hit {Enter} again.  Add the following using references to your Program.cs file:

using Microsoft.Http;

using System.Xml.Serialization;

  Now place the following code in the Main() method of Program.cs:

static void Main(string[] args)

{

    Console.WriteLine("Press {enter} to call service:");

    Console.ReadLine();

 

    var client = new HttpClient(http://localhost:1300/Service.svc/);

    HttpResponseMessage response = client.Get("GetData");

 

    var b = response.Content.ReadAsXmlSerializable<SampleResponseBody>();

 

    Console.WriteLine(b.Value);

    Console.ReadLine();

}

Both the Get request and the deserialization are simple.  We pass a base address for our service to the HttpClient constructor.  We then call the HttpClient's Get method and pass the path to the resource we want (in true REST idiom, PUT, DELETE and POST are some additional methods on HttpClient).

The deserialization, in turn, only requires one line of code.  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.

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.

 

7. If you recall, the signature of the GetData service method actually takes two parameters, an integer and a string.  When translated into a REST resource, the parameters are passed in a query string.  To complete this example, we might want to go ahead and pass these parameters to our GetData resource.  To do so, replace the code above with the following:

static void Main(string[] args)

{

    Console.WriteLine("Enter a number:");

    int myInt;

    Int32.TryParse(Console.ReadLine(), out myInt);

 

    Console.WriteLine("Enter a string:");

    var myString = Console.ReadLine();

 

    var q = new HttpQueryString();

    q.Add("param1", myInt.ToString());

    q.Add("param2", myString);

 

    var client = new HttpClient("http://localhost:1300/Service.svc/");

    HttpResponseMessage response = client.Get(new Uri(client.BaseAddress + "GetData"), q);

    var b = response.Content.ReadAsXmlSerializable<SampleResponseBody>();

 

    Console.WriteLine(b.Value);

    Console.WriteLine("Press {enter} to end.");

    Console.ReadLine();

}

The first block asks for a number and we verify that a number was indeed submitted.  The next block requests a string.

The third block creates an HttpQueryString instance using our console inputs.

The important code is in the fourth block.  You will notice that we use a different overload for the Get method this time.  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.  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).  We could have also simply performed a string concatenation like this, of course:

HttpResponseMessage response =

client.Get(string.Format("GetData?param1={0}&param2={1}",myInt.ToString(), myString));

but using the HttpQueryString type strikes me as being somewhat cleaner. 

And that's how we do RESTful WCF as of Friday, March 13th, 2009. 

To see how we used to do it prior to March 13th, please see this excellent blog post by Pedram Rezai from April of last year.

 

 

 
                
                    

by Anonymous | 5 Comments

RESTful WCF at Atlanta Code Camp

 

This past Saturday was the Atlanta Code Camp.  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.

My company, Magenic Technologies, presented at seven of the sessions this year. 

Sergey Barskiy, who was a developer on the CSLA-Lite team, presented on Building Silverlight Business Applications using CSLA.NET for Silverlight.

Whitney Weaver, another of our principal consultants and a master of all things data, spoke on What’s my data doing while I sleep? Tracking data changes in SQL Server 2008.

Colin Whitlatch presented an Introduction to ASP.NET MVC, 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.

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.  He did two presentations this year: WPF Custom Controls and WPF DataBinding.

I presented on REST-ful WCF (the hyphen is a personal grammatical quirk rather than any attempt to make a philosophical point) and Mocking with Rhino Mocks and TypeMock: A Head-to-head Comparison.  I also got to make a short app-dev appearance in Tejas Patel's Use of data mining controls with ASP.NET presentation.

As promised to the attendees, I'm making the code samples and slide-decks available.  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.  All the code uses Visual Studio 2008.  The mocking samples will require that you have the appropriate dll's for Rhino Mocks, which is free,  and TypeMock Isolator, which has a 30-day trial.

I am indebted for Pedram Rezaei for getting me started on the WCF-to-Flikr sample.

The Rest-ful WCF slide-deck and code can be downloaded here.

The Mocking powerpoint and samples are available here.

by Anonymous | 3 Comments

The problem with computer literacy

A recent post on Boing Boing is titled Paper and pencil better for the brain than software?  The gist of the article and its associated links is that software, in guiding us through common tasks, actually makes us dumber.  The Dutch psychologist Christof van Nimwegen has performed studies demonstrating the deleterious effects of being plugged-in.  From the post:

"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."

This certainly sounds right to me, from personal experience.  About a year ago, my company gave away GPS navigation devices as Christmas gifts to all the consultants.  The results are twofold.  On the one hand, we all make our appointments on time now, because we don't get lost anymore.  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.  Without my GPS, I am effectively as blind as a bat without echolocation.

In Charles Stross's novel about the near future, Accelerando, this experience is taken a step further.  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.  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.  This is the nightmare of the technologically dependent.

Doctor van Nimwegen's study recalls Plato's ambivalence about the art of writing.  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.  Plato, in turn, was a poet who ultimately became distrustful of his own skills, and railed against it in his philosophical writings.  From the modern viewpoint, however, whatever it is that we lose when we put "living" thoughts down to writing, surely it is only through poetry that we are able to recover and sustain it.

It is through poetic imagery that Plato explains Socrates's misgivings about letters in the Phaedrus:

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' souls, because they will not use their memories; they will trust to the external written characters and not remember of themselves. 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; they will be tiresome company, having the show of wisdom without the reality.

We can certainly see aspects of Manfred Macx'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.  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.  Very handy, that search feature.  But how much more wonderful it would have been had I been able to call that up from my own theater of memory.

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.  A consulting manager recently chastised me for this practice, which he found error prone and somewhat irresponsible.  To this I could only reply, "but I already know how to spell."  

I should have added, "...for now."

by Anonymous | 43 Comments

Filed under:

Visual Studio 2008 SP1 Toolbox Crash

For the past month or so, whenever I tried to add a control to my Visual Studio Toolbox, the IDE would shut itself down.  My solution, of course, was to avoid adding tools to my Toolbox.

Finally I decided that I needed to do something, ahem, a little smarter.  The specific problem occurred when I tried to use the Context Menu's "Choose Items..." option on my toolbox.   It turns out that the Power Commands (when did I install that?) has a conflict with VS 2008.  This apparently can also mess up the class viewer in Visual Studio 2008.  There are two work-arounds for this.   The first is to hack a config file for your IDE settings.   That solution can be found here: http://social.msdn.microsoft.com/Forums/en-US/vssetup/thread/e2434065-9921-4861-b914-9cc9d6c55553/

 

Unfortunately this didn't work for me.  The second work-around is simply to uninstall the Power Commands.  If you go into Add/Remove Programs, it is listed as PowerCommands for Visual Studio 2008.

by Anonymous | 986 Comments

Reflection

Like may others, I recently received the fateful email notifying me that Lutz Roeder 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.  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't care about implementations, only about contracts.  It gets worse, since one of the main reasons for using .NET Reflector is to reverse engineer someone else's (particularly Microsoft's) code.  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.

While many terms in computer science are drawn from other scientific fields, reflection appears not to be.  Instead, it is derived from the philosophical "reflective" tradition, and is a synonym for looking inward: introspection.  Reflection and introspection are not exactly the same thing, however.  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.  In reflection, there is a moment of stopping and stepping back; the "I" who looks back on oneself is a cold and appraising self, cool and objective as a mirror.

Metaphors pass oddly between the world of philosophy and the world of computer science, often giving rise to peculiar reversals.  When concepts such as memory and CPU's were being developed, the developers of these concepts drew their metaphors from the workings of the human mind.  The persistent storage of a computer is like the human faculty of memory, and so it was called "memory".  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.  Originally it was the mind that was the given, while the computer was modeled upon it.  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.  Isn't it odd that we remember things, just like computers remember things?

The ancient Skeptics had the concept of epoche to describe this peculiar attitude of stepping back from the world, but it wasn't until Descartes that this philosophical notion became associated with the metaphor of optics.  In a letter to Arnauld from 1648, Descartes writes:

"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."

This form of reflective thought, in turn, also turns up in at an essential turning point in Descartes' discussion of his Method, when he realizes that his moment of self-awareness is logically dependent on something higher:

"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;"

Descartes uses the metaphor in several places in the Discourse on Method.  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.  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.  The act of reflection provides a different view of ourselves from what we might observe from introspection alone.  For Descartes, it is always a matter of finding out what one is "really" doing, rather than what one thinks one is doing.

This notion of philosophical "true sight" through reflection is carried forward, on the other side of the channel, by Locke.  In his Essay Concerning Human Understanding, Locke writes:

"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 internal sense. 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."

Within a century, reflection becomes so ingrained in philosophical thought, if not identified with it, that Kant is able to talk of "transcendental reflection":

"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.

...

"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."

In the 20th century, the reflective tradition takes a peculiar turn.  While the phenomenologists continued to use it as the central engine of their philosophizing, Wilfred Sellars began his attack on "the myth of the given" upon which phenomenological reflection depended.  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 "folk psychology" of mind that we use to describe those mental states.  In one fell swoop, Sellars sweeps away the Cartesian tradition of self-understanding that informs the cogito ergo sum.

In a sense, however, this isn't truly a reversal of the reflective tradition but merely a refinement.  Sellars and his contemporary heirs, such as the Churchlands and Daniel Dennett, certainly provided a devastating blow to the reliability of philosophical introspection.  The Cartesian project, however, was not one of introspection, nor is the later phenomenological project.  The "given" was always assumed to be unreliable in some way, which is why philosophical "reflection" is required to analyze and correct the "given."  All that Sellars does is to move the venue of philosophical reflection from the armchair to the laboratory, where it no doubt belongs.

A more fundamental attack on the reflective tradition came from Italy approximately 200 hundred years before Sellars.  Giambattista Vico saw the danger of the Cartesian tradition of philosophical reflection as lying in its undermining of the given of cultural institutions.  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.  On the face of it, it sounds like the rather annoying contemporary arguments against "cultural relativism", but is actually a bit different.  Vico'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.  In the 1730 edition of the New Science, Vico writes:

"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.  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."

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 cogito who sees clearly, and cooly, the world as it is.

This begets the natural question, does reflection 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?  In computer science of course (not that this should be any guide to philosophy) the latter is the case.  Reflection is accomplished by publishing metadata about a code library which may or may not be true.  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.  We assume it is reliable, but there is no way of really knowing until something goes wrong.

by Anonymous | 5 Comments

Filed under:

AJAX Control Toolkit: Script Only

I previously posted about how to use the Microsoft Ajax Library in order to provide Globalization script functionality without using the ScriptManager control.  Why would you want to do this?

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.  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.  The original promise of WebForms was to abstract web development so it looks more like traditional Windows Forms development.  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.

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.

ASP.NET AJAX was originally developed following the WebForms paradigm.  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.  Even the Ajax Control Toolkit, the Microsoft backed opensource project that extends ASP.NET AJAX with additional controls, follows this model.

But the MVC model doesn't follow this model.  It follows the model followed by every other vendor of web technology.

So how do ASP.NET MVC and ASP.NET AJAX come together if they follow these radically different models?  Well ... the Microsoft AJAX team also provides the underlying scripts for their framework in the Microsoft Ajax Library, 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.  They can also, of course, be used with the MVC framework.

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.  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.

Stephen Walther is now helping people through this difficulty on his blog, and it is a wonderful thing.  He has already tackled the Popup Calendar and Autocomplete.  Expect to hear more from him in the near future.  I can't wait to see what he does next.

h/t to Bertrand Leroy's Tales From the Evil Empire for highlighting this.

by Anonymous | 0 Comments

Filed under:

Recipe: Session Expired Monitor with ASP.NET AJAX

code download

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.  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.  In ASP.NET, this period has a default of 20 minutes, which is really hardly enough time to pick up a donut, refill one's coffee, and chat with fellow workers before returning to one's computer.  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.  Worse, strange errors will begin to appear in his web browser if the loss of a session is not handled gracefully. 

The most common workaround is to increase the session grace period, called the session timeout.  This is set in your web.config file, and typically looks like this (the timeout period is measured in minutes):

  <system.web>
    <sessionState
      mode="InProc"
      cookieless="false"
      timeout="20"
     />
  </system.web>

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't doing anything.

A third, and the most common, way is to provide code that redirects a user to a "session expired" page if they try to interact with a web page for which the session has timed-out.  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.

This post deals with an active approach to the same problem.  When the user's session has expired, it will generate a popup message in the user's browser window letting him know that he has been inactive for too long.  Additionally it can redirect the browser to a new page with a warning message letting him know what happened.  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.

This solution uses three tricks.  One is the event model for Master Pages in ASP.NET:  whenever a Content Page is refreshed, its OnLoad event is called,  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).

The second trick is the way ASP.NET Extensions Timer control gets reset.  This is done simply by setting the interval to a new value.  Every time the interval is set to a new value, or even the same value, the countdown on the timer begins again.

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.

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.  It resets itself to the full timeout period any time a Content Page is refreshed.  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).

A user control to monitor the session timeout is included in the code sample linked at the top of this post.  Here is how you can build your own.

 

Session Timeout Monitor Recipe:

Ingredients:

  • One Master Page
  • One User Control
  • An Update Panel
  • An ASP.NET Ajax Extensions Timer
  • A Panel control
  • A Button control

 

1. Create a new User Control in your project. 

2. Drop an Update Panel on the User Control and set its mode property to "Always".

3. Add an Extensions Timer (not to be confused with the Futures TimerControl) to your project, dropping it in the Update Panel.  Name it TimerTimeout.

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.  In this case, however, the timer and update panel are used simply to trigger a notification that the session has expired.

4. In the User Control's code behind, add the following lines to the OnLoad event:

 

        protected void Page_Load(object sender, EventArgs e)
        {
            int milliseconds = 60000;
            TimerTimeout.Interval = Session.Timeout * milliseconds;
        }

This event will be called any time a content page is refreshed.  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.

Since the Timer control'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.

To finish this notifier, the Timer's Tick event needs to be handled.  The Tick event gets called when the Timer's Interval finally runs out.  In this implementation, the Tick event can either generate a popup message or cause a page redirect.

5. Place a Panel inside the Update Panel.  Set its Visible property to false.

6. Write a simple message inside the Update Panel, such as "Your session has expired."

7. Drop a Button inside the Panel.  This Button will be used to allow the user to hide the popup message.

8. Add a public property to the User Control called SessionExpiredRedirect:

        private string _sessionExpiredRedirect;

        public string SessionExpiredRedirect
        {
            get { return _sessionExpiredRedirect; }
            set { _sessionExpiredRedirect = value; }
        }

This will be used to set the web page to which the Timer will redirect the user upon session timeout.  If no value is set, a popup message will appear, instead.

9. Handle the Timer's Tick event:

        protected void TimerTimout_Tick(object sender, EventArgs e)
        {

            if (!string.IsNullOrEmpty(SessionExpiredRedirect))
            {
                if (SessionExpiredRedirect.IndexOf("~")==0)
                    Response.Redirect(
                        VirtualPathUtility.ToAppRelative(
                        SessionExpiredRedirect));
                else
                    Response.Redirect(SessionExpiredRedirect);
            }
            else
                this.PanelTimeout.Visible = true;
        }

This handler checks to see if a value has been set for the SessionExpiredRedirect property.  If not, it makes the Panel control inside the Update Panel visible.

10. To make the Panel control truly popup, set its CssClass property to "timeoutMessage".  Add the following css style to the page.

<style type="text/css">
.timoutMessage
{
    position:absolute;
    top:100px;
    left:200px;
    background-color:#F5F7F8;
    border-style:groove;
    border-color:Navy;
    padding:15px;
}
</style>

11. Finally, compile this User Control and drag it on to the Master Page.  In design mode, the user control will display a misleading exception message.  Just ignore it.

12. Make sure the Master Page includes an ASP.NET AJAX Script Manager component.

This completes the recipe.  Any Content Page in this project will now automatically include the timeout monitor you have built.  Cookies are optional: this recipe will work with a session managed either with cookies or in cookieless mode.  It will only work if the session mode is InProc.

Garnish with buttered radishes.  Serve at room temperature.

 

 

by Anonymous | 3 Comments

Filed under:

Extending the Ajax Control Toolkit Tab Container with Lazy Loading

download source code

ASP.NET has been missing a good, free tab control for a long time.  With the ACT Tab Container, we were finally given one.  It typically runs in client-side only mode, but can interact with server-code if we set its AutoPostback property to true.

Compared to what we had before, it is a huge improvement.  The peculiar thing about it, however, is that it isn't actually an Ajax control.  It doesn'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.

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 blog.  You basically run the tab container in client-side mode, and add update panels to the tab panels that you want to be ajaxy.  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.

Matt also gave this technique a cool name.  He called it 'lazy loading the tab panel'.  Like lazy loading in OOP, using this technique the update panels inside each tab panel only do something when its tab is selected.  Information is loaded only when its needed, and not before.

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.  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'm rather proud of this.

The VS 2008 project for this extender is linked at the top of this post.  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.

1. Drop the TabContainerExtender control into your page.

2. Set the Extender's TargetControlID property to your TabContainer's ID.

3. In the RegisterUpdatePanels element of the Extender, map your tabs to your update panels.  This mapping tells the extender which Update Panels to activate when each tab is selected.

Your markup will look something like this:

    <cc2:TabContainerExtender ID="TabContainerExtender1" 
    runat="server" 
    TargetControlID="TabContainer1" OnActiveTabChanged="ActiveTabChanged">
    <RegisterUpdatePanels>
    <cc2:UpdatePanelInfo TabIndex="0" UpdatePanelID="UpdatePanel1" />
    <cc2:UpdatePanelInfo TabIndex="1" UpdatePanelID="UpdatePanel2" />
    <cc2:UpdatePanelInfo TabIndex="2" UpdatePanelID="UpdatePanel3" />
    </RegisterUpdatePanels>
    </cc2:TabContainerExtender> 

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.  The thrown event will pass the correct Index number for the active Tab, as well as the ID of the mapped Update Panel.  The handler's signature looks like this:

        protected void ActiveTabChanged(int index, string panelID)

        {

            ...

        }

I highly encourage you to read Matt Berseth'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.  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.  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.

For reference, here is the code for the sample implementation, which loads controls on the fly based on the tab selected:

    <cc1:TabContainer ID="TabContainer1" runat="server">
    <cc1:TabPanel ID="TabPanel1" runat="server" HeaderText="Tab Panel 1">
    <ContentTemplate>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
        Content 1 ...
        <br />
            <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>      
        </ContentTemplate>
        </asp:UpdatePanel>    
    </ContentTemplate>
    </cc1:TabPanel>
        <cc1:TabPanel ID="TabPanel2" runat="server" HeaderText="Tab Panel 2">
    <ContentTemplate>
        <asp:UpdatePanel ID="UpdatePanel2" runat="server">
        <ContentTemplate>
        Content 2 ...
        <br />
            <asp:PlaceHolder ID="PlaceHolder2" runat="server"></asp:PlaceHolder>      
        </ContentTemplate>
        </asp:UpdatePanel>    
    </ContentTemplate>
    </cc1:TabPanel>
        <cc1:TabPanel ID="TabPanel3" runat="server" HeaderText="Tab Panel 3">
    <ContentTemplate>
        <asp:UpdatePanel ID="UpdatePanel3" runat="server">
        <ContentTemplate>
        Content 3 ...
        <br />
            <asp:PlaceHolder ID="PlaceHolder3" runat="server"></asp:PlaceHolder>      
        </ContentTemplate>
        </asp:UpdatePanel>    
    </ContentTemplate>
    </cc1:TabPanel>
    </cc1:TabContainer>
    <cc2:TabContainerExtender ID="TabContainerExtender1" 
    runat="server" 
    TargetControlID="TabContainer1" OnActiveTabChanged="ActiveTabChanged">
    <RegisterUpdatePanels>
    <cc2:UpdatePanelInfo TabIndex="0" UpdatePanelID="UpdatePanel1" />
    <cc2:UpdatePanelInfo TabIndex="1" UpdatePanelID="UpdatePanel2" />
    <cc2:UpdatePanelInfo TabIndex="2" UpdatePanelID="UpdatePanel3" />
    </RegisterUpdatePanels>
    </cc2:TabContainerExtender> 

by Anonymous | 717 Comments

Filed under:

Ajax AutoComplete Extender with WCF

The problem with conjuring tricks is that they lose practically all their glamour once you find out how they are done.  It'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.  It'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.

My trick is to make an autocomplete extender from the Ajax Control Toolkit call a WCF service instead of an asmx service.  For this recipe, I assume that you are already familiar with the autocomplete extender, and that you are using Visual Studio 2008.  I warn you in advance -- my trick disappoints.  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 supermodel.

Start by creating a new web project called AutocompleteWCF.  Add a reference to the AjaxControlToolkit.dll.  Open up the default aspx page that is generated with your project, and add the following code to:

    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <div>
            <asp:TextBox runat="server" ID="myTextBox" Width="300" autocomplete="off" />
            <ajaxToolkit:AutoCompleteExtender
                runat="server" 
                BehaviorID="AutoCompleteEx"
                ID="autoComplete1" 
                TargetControlID="myTextBox"
                ServicePath="Autocomplete.svc" 
                ServiceMethod="GetCompletionList"
                MinimumPrefixLength="0" 
                CompletionInterval="1000"
                EnableCaching="true">
            </ajaxToolkit:AutoCompleteExtender>
    </div>
    </form>

This is the standard demo code that is shipped with the Ajax Control Toolkit Sample Website.  I've simplified it a bit by removing the animations.  The only significant change I've made is to change the ServicePath from Autocomplete.asmx to Autocomplete.svc, the latter being the extension for a WCF service.

The next step is to create our service and add a GetCompletionList operation to it.  The easiest way to do this is to go to Add | New Item and just select the Ajax-enabled WCF Service item template, but this would be so easy that it is hardly worth doing.

Instead, create a new WCF Service using the WCF Service Item Template and call it Autocomplete.svc.  Visual Studio will automatically generate a service interface for you.  Delete the interface.  We don't need it.  (To be more specific, I don't know how to get this to work with an interface, so I'm just going to ignore that it is possible.)

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.  The WCF service class (Autocomplete.svc.cs) will look like this:

    [ServiceContract(Namespace = "")]

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

    public class Autocomplete

    {

        [OperationContract]

        public string[] GetCompletionList(string prefixText, int count)

        {

            if (count == 0)

            {

                count = 10;

            }

            if (prefixText.Equals("xyz"))

            {

                return new string[0];

            }

            Random random = new Random();

            List<string> items = new List<string>(count);

            for (int i = 0; i < count; i++)

            {

                char c1 = (char)random.Next(65, 90);

                char c2 = (char)random.Next(97, 122);

                char c3 = (char)random.Next(97, 122);

                items.Add(prefixText + c1 + c2 + c3);

            }

            return items.ToArray();

        }

A few things worth noting:

1. Autocomplete does not implement the IAutocomplete Interface.  Even though this is generated automatically, with the WCF Service item template, you should remove it.

2. The service contract has a blank Namespace explicitly declared. 

3. The ASPNetCompatibilityRequirements attribute must be added to our class.

This takes care of the code that calls the WCF service, as well as the service itself.  We now have rig up the web.config file.  If you've been working with WCF for any length of time, then you know that this is where the problems usually occur.  Fortunately, the configuration is fairly simple.  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 ScriptService attribute in order to be called from client-script).  You also will need to turn AspNetCompatibilityEanbled on for the hosting environment.

    <system.serviceModel>

        <behaviors>

            <endpointBehaviors>

                <behavior name="AjaxBehavior">

                    <enableWebScript/>

                </behavior>

            </endpointBehaviors>

        </behaviors>

        <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>

        <services>

            <service name="AutocompleteWCF.Autocomplete">

                <endpoint address="" behaviorConfiguration="AjaxBehavior" binding="webHttpBinding" contract="AutocompleteWCF.Autocomplete"/>

            </service>

        </services>

    </system.serviceModel>

And that is all you need to do make the AutoComplete Extender work with a WCF service instead of an asmx web service.  I told you it would be unimpressive.

Of course, using a WCF service for Ajax has all the limitations that using an asmx file for Ajax did.  First of all, you can't call a service that is in a different domain than the page which hosts your client-code.  This is a security feature, to prevent malicious code from redirecting your harmless javascript to something nasty on the world wide web.

Second, you can't call just any service from your client-side code.  The service must be explicitly marked as something that can be called from client code.  In asmx web services, we used ScriptService for this.  In WCF services, we similarly use EnableWebScript binding property.

Now I feel like I've wasted your time, so here's a YouTube video of David Blaine to make up for it.  And remember, David Blaine is to Chris Angel what Daisy Duke was to Alexis Carrington.  It's an existential thing, and at some point, you've just got to pick sides and stay put in a way that will determine who you are for the rest of your life.

Are you a David Blaine/Daisy Duke kind of person or are you a Chris Angel/Alexis Carrington sort?  Do some soul searching and please let me know what you learn about yourself.

by Anonymous | 651 Comments

Filed under:

More Posts Next page »
Powered by Community Server, by Telligent Systems