Managed World

Techno-babble from yet another babbler RSS 2.0
# Saturday, June 21, 2008

As developers get up to speed with the CCR, they quickly come across the (ab)use of iterators to achieve "concurrency." Okay, "(ab)use" may have been a bit of a low-blow. I call it an abuse as it is a totally unorthodox use of what iterators are usually used for, and I've came across my fair share of developers who find this unorthodox usage highly confusing. Not only is it confusing, but it's not what I would consider true concurrent code.

In a concurrent environment, if I create twenty different tasks that need to be executed, I expect several of those tasks to be executed at the exact same time (depending on the number of processors I have on my system). As a side effect of this concurrent execution of tasks, the order in which those tasks are executed is not guaranteed. If you don't have several tasks executing concurrently, and order of processing is indeed guaranteed, that's about as close you can get to being normal sequential code.

Look at this sample (example 18) from MSDN. If you execute and step through this code, you will find that the method actually executes sequentially. The code posts a number, processes the number, posts another number, processes that number, etc. This is highly sequential. One could argue this is simply not the best sample for CCR iterators. However, after using CCR when developing robots using Robotics Studio, you will find that this "sequential but not" pattern is a very frequent pattern that is used when using CCR iterators.

There's also the impact of having a method that essentially never exits due to the "while (true)" nature of the iterator-based method that is determining what tasks need to execute (leading to a highly coupled, monolithic application). This doesn't mean that the CCR itself isn't useful though. You just need to know how to leverage the framework while avoiding some of these "rough spots".

So let's take a look at an example of how to use CCR to achieve "true" concurrency with the CCR without the use of iterators (for you VB fans, the great part of this approach is that it is entirely possible with VB like I show here).

Dim myPort As New Port(Of Integer)

At the heart of the message-based infrastructure in the CCR is a Port. A Port is where messages are posted to, and pulled from when tasks are actually executed. As seen above, Ports are strongly typed through the use of generics, and so they support posting/pulling of largely any POCO (Plain Ole CLR Object) you wish. In the case of this very simple demo we just use integers, but in a real system this might be self-defined types like StockQuoteRequestMessage, FoodOrderMessage, etc.

    Sub Main()
        Dim taskDispatcher As New Dispatcher(4, "Sample Dispatcher")
        Dim taskQueue As New DispatcherQueue("Sample Tasks", taskDispatcher)

In the CCR, a DispatcherQueue contains a list of tasks to be executed, while a Dispatcher controls the execution of those tasks. Here we force our dispatcher to run four tasks concurrently even if we are on a single processor machine just so we can see the concurrency in action. Then we simply pass our dispatcher to the queue that contains the tasks that will be managed.

        ' Create the task that will handle our work
        Dim workReceiver = Arbiter.Receive(Of Integer)(True, _
                                myPort, _
                                Function(i) ProcessValue(i))

        ' Register the task with the CCR task queue
        Arbiter.Activate(taskQueue, workReceiver)

        ' Post some work to do
        For i = 0 To 9
            myPort.Post(i)
        Next

When we create our workReceiver, we are essentially telling the CCR that we want a persistent task (one that will last across the processing lifetime of many messages, possibly until the application exits), and that when a message comes in on our Port, we will process that message with our function ProcessValue (defined below). Once the receiver is created, we simply hook it up to the task queue, and we're off to the races.

Finally, all we need to do is wait until all values have been processed and exit the application.

        ' Wait until all tasks are finished
        While myPort.ItemCount > 0
            Thread.Sleep(TimeSpan.FromMilliseconds(200))
        End While

        taskQueue.Dispose()
        taskDispatcher.Dispose()

        Console.Write("Press any key to exit...")
        Console.ReadKey(True)
    End Sub

So when a message is posted to our port, CCR will call our function ProcessValue in order to process the message (as specified when we created the task to process messages). In our process function, we are simply going to write to the console at the beginning and at the end as well as sleeping our thread in the middle to simulate some work being done in the function.

    Function ProcessValue(ByVal value As Integer)

        Console.WriteLine("Begin " + value.ToString())
        Thread.Sleep(TimeSpan.FromMilliseconds(200))
        Console.WriteLine("End " + value.ToString())

        Return Nothing
    End Function

When I actually execute this sample, you can see the parallel nature of the execution by viewing the output (your output may differ as it can differ upon every execution thanks to the non-deterministic nature of concurrency):

Begin 0
Begin 1
Begin 3
Begin 2
End 2
Begin 4
End 1
Begin 5
End 0
Begin 6
End 3
Begin 7
End 4
Begin 8
End 5
End 6
Begin 9
End 7
End 8
End 9
Press any key to exit...

 

And that's all we need to do in order to use CCR to process incoming messages in parallel (and in a "true" concurrent fashion). Just as a recap, here's the entire sample in one place:

    Dim myPort As New Port(Of Integer)

    Sub Main()
        Dim taskDispatcher As New Dispatcher(4, "Sample Dispatcher")
        Dim taskQueue As New DispatcherQueue("Sample Tasks", taskDispatcher)

        ' Create the task that will handle our work
        Dim workReceiver = Arbiter.Receive(Of Integer)(True, _
                                myPort, _
                                Function(i) ProcessValue(i))

        ' Register the task with the CCR task queue
        Arbiter.Activate(taskQueue, workReceiver)

        ' Post some work to do
        For i = 0 To 9
            myPort.Post(i)
        Next

        ' Wait until all tasks are finished
        While myPort.ItemCount > 0
            Thread.Sleep(TimeSpan.FromMilliseconds(200))
        End While

        taskQueue.Dispose()
        taskDispatcher.Dispose()

        Console.Write("Press any key to exit...")
        Console.ReadKey(True)
    End Sub

    Function ProcessValue(ByVal value As Integer)

        Console.WriteLine("Begin " + value.ToString())
        Thread.Sleep(TimeSpan.FromMilliseconds(200))
        Console.WriteLine("End " + value.ToString())

        Return Nothing
    End Function

As a "hello world" sample for using the CCR, this is a very simple demo. But it shows that it is very easy to actually achieve concurrent applications with the CCR without having to use CCR iterators. At the same time, avoiding the use of CCR iterators enable us to write a message-oriented application that can be properly modularized by "separating concerns" into independent message processors through the use of Ports.

Of course, an added benefit of taking a "non-iterator" approach when using the CCR is that languages that don't have direct support for iterators (like VB.NET) can also develop CCR-based applications to achieve highly-parallel solutions.

Posted in CCR | Concurrency | Programming | VB
 #       Comments [0]
# Saturday, June 14, 2008

One realization I have come to when talking with many other developers is that there is a good number of developers that don't realize that inheritance introduces dependencies directly into your classes. Your derived class is now dependant upon the interface and behavior of your base class. Worded another way, your derived class is now strongly coupled to your base class. I've met a number of developers that are very passionate about managing their dependencies via inversion of control, dependency injection, etc. and yet they implement solutions that have a class hierarchy 5+ layers deep.

This strong coupling can become problematic if you need to change either the interface or behavior of my base class. For instance, if I need to add another abstract method I didn't originally think of, every single class that derives from that base class now must change in order to implement that behavior. Or, if I change the behavior of one of the methods in my base class, I can find myself in a situation where one of my derived classes will break because they were relying on that base class behavior to act a given way (even more confusing when the change doesn't impact any other of the derived classes).

Over-using (read: abusing) inheritance in your code can very easily lead to brittle classes that prevent you from being as agile as you need to be. While it is easy for developers to look at dependencies as other external classes your class is dependant upon, you have to keep in mind that your class is also strongly dependant on its base class as well.

The beautiful thing is that with some of the functionality introduced into .NET in both 2.0 and 3.5, you can avoid developing these brittle classes by using Generic programming.

"Generic programming is a style of computer programming in which algorithms are written in terms of to-be-specified-later types that are then instantiated when needed for specific types provided as parameters. This permits writing common functions or types that differ only in the set of types on which they operate when used, thus reducing duplication."

I know this description can be a bit confusing at first. Let's learn about Generic programming by example. And as an example, let's take a look at possible implementations of the Command pattern.

"In object-oriented programming, the Command pattern is a design pattern in which objects are used to represent actions. A command object encapsulates an action and its parameters."

In these examples, we are going to look at a home automation system. Specifically, let's look at the code it takes to automate lights using the Command pattern. In order to do this, we of course need a Light that we are actually automating (automation code removed for readability purposes):

    class Light
    {
        public void TurnOn()
        {
            Console.WriteLine("Light Turned On");
        }

        public void TurnOff()
        {
            Console.WriteLine("Light Turned Off");
        }
    }

So, let's dive right in.

In the "typical" way of implementing the Command pattern, you have an abstract base class Command that your detailed commands inherit from, overriding a virtual method to actually execute the command (this could also be an interface ICommand as well, instead of an abstract base class).

    abstract class Command
    {
        public abstract void Execute();
    }

    class LightOnCommand : Command
    {
        private Light _light;

        public LightOnCommand(Light theLight)
        {
            _light = theLight;
        }

        public override void Execute()
        {
            _light.TurnOn();
        }
    }

    class LightOffCommand : Command
    {
        private Light _light;

        public LightOffCommand(Light theLight)
        {
            _light = theLight;
        }

        public override void Execute()
        {
            _light.TurnOff();
        }
    }

Let's take another look at that definition of the Command pattern: "the Command pattern is a design pattern in which objects are used to represent actions". In our case, each action (turning a light on, turning a light off) is represented by an object (LightOnCommand, LightOffCommand).

Now to use these classes, all we need to do is instantiate new instances of our two commands (LightOnCommand and LightOffCommand) and execute them. Pretty simple. And because of leveraging a common base class, we can use polymorphism to reuse this code even more (like having a list of commands that we can execute in a script or elsewhere).

            var livingRoomLight = new Light();
            var lightOn = new LightOnCommand(livingRoomLight);
            var lightOff = new LightOffCommand(livingRoomLight);

            lightOn.Execute();
            lightOff.Execute();

This classic approach doesn't come without it's drawbacks though. First of all, for every home device that we wish to turn on and off, we would be introducing two new classes into our code. While this may not be that bad for a couple of devices, it can quickly get out of hand when the number of devices start to grow.

Also, the "common behavior" we get out of our base class isn't very flexible. If we change our Execute() method in our base class from abstract to virtual in order to introduce common behavior, how do you guarantee that the base method is called when it should be? In a derived class, should you call the base method before your own execution code, or after? What if I want common code in my base class that will be executed both before and after the behavior in my derived classes? While .NET has ways of achieving this, it quickly becomes complex and just introduces more code that obfuscates what the true purpose of our code is.

Not as flexible as we first though, eh?

So what has .NET done lately to make this job easier? Well, with the introduction of Generics and Lambdas, we can do a form of Generic programming that helps us write "one Command class to rule them all." By writing more generic code, you get down to the essence of what your code needs to do, and allows you to write code that is more flexible and not as dependant on other classes as before (since we are not directly leveraging inheritance like we were before).

What might a generic solution to the Command pattern look like?

    class GenericCommand<TReceiver>
    {
        private TReceiver _receiver;
        private Action<TReceiver> _commandToExecute;

        public GenericCommand(TReceiver theReceiver, Action<TReceiver> theCommandToExecute)
        {
            _receiver = theReceiver;
            _commandToExecute = theCommandToExecute;
        }

        public void Execute()
        {
            _commandToExecute(_receiver);
        }
    }

Let's look back at that description for Generic programming: "This permits writing common functions or types that differ only in the set of types on which they operate when used, thus reducing duplication." That's all we are doing here. We have written a common type in which only the types on which it operates differs when used.

When we use this generic type is when we actually dictate what type it operates upon. In the case of our home automation system, we are going to create an instance of our GenericCommand that operates on a Light fixture. Then, we will specify what action needs to be taken when the command is execute by leveraging lambda expressions:

            var livingRoomLight = new Light();

            var genericLightOn = new GenericCommand<Light>(livingRoomLight, theLight => theLight.TurnOn());
            var genericLightOff = new GenericCommand<Light>(livingRoomLight, theLight => theLight.TurnOff());

Pretty simple, for our light on command we turn the light on, and for our light off command we turn the light off. And in both cases, we are using the exact same common type (GenericCommand<TReceiver>) when declaring our command.

Now let's say we want to start automating our Garage as well. The class we might be given to do this automating might look like the following (with all the automation code removed again):

    class Garage
    {
        public void TurnLightOn()
        {
            Console.WriteLine("Garage Light Turned On");
        }

        public void TurnLightOff()
        {
            Console.WriteLine("Garage Light Turned Off");
        }

        public void OpenDoor()
        {
            Console.WriteLine("Garage Door Opened");
        }

        public void CloseDoor()
        {
            Console.WriteLine("Garage Door Closed");
        }
    }

Using the prior inheritance-based way, we would need to introduce two more command classes for this new Garage automation. And as stated before, when having to introduce two more command classes for every new piece of home automation, we quickly have a blow-up in the number of classes we have to maintain. However, using the generic programming-based approach that leverages Generics and Lambdas, we actually don't have to introduce any new classes as our meta-class GenericCommand<T> can handle those situations already. 

Here's how we might consume the new Garage with our GenericCommand<T>:

            var genericOpenGarage = new GenericCommand<Garage>(myGarage, theGarage => 
            { 
                theGarage.TurnLightOn(); 
                theGarage.OpenDoor(); 
            });
            var genericCloseGarage = new GenericCommand<Garage>(myGarage, theGarage => 
            { 
                theGarage.CloseDoor(); 
                theGarage.TurnLightOff(); 
            });

            genericOpenGarage.Execute();
            genericCloseGarage.Execute();

Very simple. Once again, we are using the exact same type (GenericCommand<TReceiver>) to implement the automation commands for our Garage as we were using with our Light. So, the same common type that, when used, only differs by the types it operates on. Which is exactly the definition of Generic programming we discussed before. It's not as scary as it sounds!

Now if we need to introduce logging or any other common functionality into our command class, we can introduce it in one place and have it applied to all our consuming code. Unlike the polymorphic approach outlined above, we now have the flexibility in this approach to execute any common code in relation to our command, whenever we want, however we want. It doesn't matter if that common code is before, or after, or before and after.

If you are still reading this (in which case I thank you), you should realize that you are already familiar with a pattern used to achieve parallelism in the new Parallel Extensions to the .NET Framework CTP that has been released. The programming model used when dealing with Tasks and Futures are essentially the exact same thing as the generic command pattern used above. So if you grok the GenericCommand above, you'll settle right into using Tasks and Futures within the Parallel Extensions.

In closing, by using a Generic programming approach when implementing our Command pattern, we now have just the base functionality that is absolutely needed to implement our commands. And, we avoid the explosion in the number of classes and dependencies that taking an inheritance-based approach would introduce, all made possible by the introduction of Generics (in 2.0) and Lambdas (in 3.5) in .NET.

I hope you enjoyed this walk down the "applying generics and lambdas" road. Until next time, Happy Coding!

Posted in C# | Programming
 #       Comments [19]
# Thursday, June 12, 2008

In this post I want to discuss with you the importance of realizing how lambdas work (and why you should care). Let's dive right in with some code.

Given the following code snippet, what would you expect the output to be (no cheating :P)?

            var actions = new List<Action>();

            for (int i = 0; i < 10; i++)
            {
                actions.Add(() => Console.WriteLine(i));
            }

            foreach (var action in actions)
            {
                action();
            }

Would you believe me if I told you this is the output you get?

10
10
10
10
10
10
10
10
10
10

At first glance, one might expect this output:

0
1
2
3
4
5
6
7
8
9

But all tens are output instead. Why does this happen? Let's crank open Reflector and find out why...

 

The first thing you'll notice is that the compiler has created a helper class to enable the closure we have. This helper class created by the compiler contains a local variable that we use to iterate over and a method that our delegate is contained within. This helper class is especially interesting because it is where the magic happens.

 

[CompilerGenerated]
private sealed class <>c__DisplayClass2
{
    // Fields
    public int i;

    // Methods
    public void <Main>b__0()
    {
        Console.WriteLine(this.i);
    }
}

Rather than diving into MSIL, let's look at some pseudo-code of what the compiler _actually_ executes with the original code above (based on the generated MSIL):

 

var actions = new List<Action>();

<>c__DisplayClass2 localFrame = new <>c__DisplayClass2();
for (localFrame.i = 0; localFrame.i < 10; localFrame.i++)
{
	actions.Add(localFrame.<Main>b__0);
}

foreach (var action in actions)
{
	action();
}

 

Perhaps now you can see where the problem is. The "problem" in our original code exists because of the scope that our closures are defined. The local index from our for loop is now stored in our helper class <>c__DisplayClass2. And the code that is executed by the action is contained within the compiler generated <Main>b__0() method now. So the Console.WriteLine() method now uses the local variable from <>c__DisplayClass2 when it is executed.

 

So while we are looping through building all our actions, we are also incrementing the property i in localFrame (an instance of <>c__DisplayClass2). Then at the end when we are actually executing the actions, the <Main>b__0() is called and uses the local i property (which by this time, has already been incremented to 10 from our loop). And that's why every action we execute prints "10" instead of the 0 through 9 like we expected.

 

So, why do you need to know how these work? Take the following code that outputs items from an array of strings:

 

            var actions = new List<Action>();
            string[] urls = 
            { 
                "http://www.url.com", 
                "http://www.someurl.com", 
                "http://www.someotherurl.com", 
                "http://www.yetanotherurl.com" 
            };

            for (int i = 0; i < urls.Length; i++)
            {
                actions.Add(() => Console.WriteLine(urls[i]));
            }

            foreach (var action in actions)
            {
                action();
            }

 

This code looks pretty innocuous. Our bounds are protected, and we just index into our array to output a string. But, is that what we're really doing? Remember how closures work from above. The actual thing that happens when I run this code is this:

 

Confusing

 

Interesting. Even though our index variable should only even be less than the length of our url array, an exception is thrown because the index variable is actually equal to the length of our url array (and hence outside of the bounds thanks to 0-based indices).

 

Well, that wasn't what we were probably expecting. But now that we are having this "problem", what is the easiest way to resolve it? Remember that the problem is happening because of the scope of the variable within our closure. So to fix this, we can essentially declare a temporary variable that is unique in scope to this specific iteration through our array:

 

            for (int i = 0; i < urls.Length; i++)
            {
                string localUrl = urls[i];
                actions.Add(() => Console.WriteLine(localUrl));
            }

 

And now the code is fixed.

 

Understanding how lambdas work is especially important when you start developing with a library that leverages lambdas heavily like LINQ does, or Parallel Extensions to the .NET Framework. And don't worry, even those people that know how lambdas work occasionally get bitten by this behavior.

 

Enjoy the coding, folks!

Posted in C# | Programming
 #       Comments [6]
# Monday, June 09, 2008

This year for PDC 2008, we have decided to learn from a successful model used by various customers (like the ALT.NET crowd) in order to help ensure that PDC 2008 is the best conference ever. Our goal with these un-sessions is to really enable attendees with common interests to have some great conversations in an efficient setting.

So what is Open Space? Taken from the description we have on the PDC website (you can also refer to the Open Space Technology entry in Wikipedia):

Open Space is a way to bring together groups of people interested in a common topic to have an interactive discussion. In an Open Space session, there may be an expert who is passionate about a topic presenting to an audience or there may be a small group of people discussing an idea.

Four principles of Open Space:

  1. Whoever comes are the right people to be there
  2. Whatever happens is the only thing that could have happened
  3. Whenever it starts is the right time
  4. When it's over, it's over

All you need to do is suggest topics onsite that you wish to discuss and participate in sessions that sound interesting to you. It’s the unconference with content by attendees, for attendees.

Not only are we doing Open Space at PDC 2008, we want to make sure it is a _real_ Open Space. None of this "Microsoft doesn't understand, they don't grok it, they entirely and utterly butchered the whole Open Space concept".

 

Not only are we passionate about this topic, we are also fans of the Open Space movement. Of course there will be modifications that will have to be made to scale this to the size of a PDC as well as the fact that this is more of a "conference within a conference", but we hope those changes will keep the essence of Open Space unchanged.

 

If you have any concerns about Open Space @ PDC 2008, you can contact me directly at jason.olsonATmicrosoftDOTcom. I would love to hear from any of you regarding this topic. Otherwise, I look forward to seeing you in L.A. participating in Open Space @ PDC 2008! FOR THE DEVELOPERS!!!!

Posted in Conferences
 #       Comments [9]
# Wednesday, June 04, 2008

What a great week to be a developer. First, the latest Parallel Extensions CTP was released to the net, and now the first Managed Extensibility Framework CTP has been released onto Code Gallery.

So what is the Managed Extensibility Framework? From the announcement:

"The Managed Extensibility Framework (MEF) provides developers with a tool to easily add extensibility to their applications and with minimal impact on existing code. The application developer can define extension points according to the functionality required of an extension, while the extension developer uses those points to interact with the application.

MEF enables this extensibility to take place without creating a hard dependency in either direction. Applications can be extended at run time without recompilation, and extensions can be used by multiple applications sharing the same extension requirements. MEF also allows an application to delay the loading of an extension while still examining its metadata, enabling efficient traversal of large catalogs of extensions."

 

To make a medium-size story even shorter, the Managed Extensibility Framework (MEF) is essentially a framework for dependency inversion/inversion of control.

If you are a CTP junkie and like to play around with all the latest bits like I do, you have some downloading to do :P. Enjoy!

 #       Comments [0]
# Tuesday, June 03, 2008

In "Facet Mapping with LINQ, Part 1", we discussed how to add Facet Mapping to your .NET application using an attribute-based solution. This solution just doesn't leave me very excited. As we recounted, there are some problems with using an attribute-based approach:

  • Littering domain models with presentation layer-specific attributes 
  • Doesn't support existing POCOs (that perhaps can't change)
  • Can't support combinations of members (without create a new method property that actually does the combining (read: ugly)).

I personally only want one area of code to change if I alter my facet mapping. Having to change my POCOs when I want to change facet maps "smells" to me (and is itself a violation of the Single Responsibility Principle). Let's look at another way we can implement facet mapping in .NET via some more LINQ-goodness.

In a previous post, I talked about my new-found love for Fluent Languages in .NET (ala Moq or NInject). With attributes out of the way for facet mapping, I wanted to develop a library for facet mapping that was easy to use and could be used with existing code. Here are some of the "requirements" for the new facet mapping code (read: "requirements" means arbitrary features that I think are good and that I would like to see :P):

  • Usable with an existing set of POCOs (without having to change a single line of code in those objects)
  • Easily support combination of properties/methods or any arbitrary code that a person would want to create a facet on
  • Readable and easy to use (read: my own reason to try to a fluent language interface :P)

Let's take a look at the proposed API (taken straight from my unit tests):

            // Given our list of cars
            List<Car> cars = new List<Car>() {
                new Car { Make = "Toyota", Model = "Corola", Price = 20000, Year = 2001 },
                new Car { Make = "Toyota", Model = "Corola", Price = 30000, Year = 2002 }
            };

            // Generate a facet map (list of Facets) that we can use
            var facets = FacetMap<Car>.Create()
                .AddFacetOn(c => c.Make)
                .AddFacetOn(c => c.Model)
                .GenerateFrom(cars)
                .ToList();

We can also define an arbitrary expression that we want to generate a facet on:

            var facets = FacetMap<Car>.Create()
                .AddFacetOn("MakeAndModel", c => c.Make + " " + c.Model)
                .GenerateFrom(cars)
                .InParallel()
                .ToList();

With FacetMap being a generic class, we can use it to generate facets on any existing CLR class we wish to. And with the use of lambda expressions to specify what we are creating facets on, our code can be refactored a bunch and not break our facet mapping.

Implementing FacetMap isn't actually all that difficult. Since all our operations can chain be chained together with each other, all of them actually return the same interface (our IFacetMap that the FacetMap class implements).

The first thing you notice is that we are creating a generic class so that our facet maps can be used with any POCO that exists out there (theoretically). And, we are hiding the constructor so that we can use a factory method (I happen to think it reads better, could just be my personal opinion though).

    public class FacetMap<TResource> : IFacetMap<TResource>
    {
        /// <summary>
        /// Constructor is hidden as we are using a factory method
        /// </summary>
        private FacetMap() 
        {
            facetGenerators = new Dictionary<string, Delegate>();
        }

        /// <summary>
        /// Factory Method to create a new Facet Map
        /// </summary>
        /// <returns>New FacetMap</returns>
        public static IFacetMap<TResource> Create()
        {
            return new FacetMap<TResource>();
        }

        ...
    }

Our class implemented our IFacetMap interface so that external code using our FacetMap is relying on abstractions outside of our Factory Method. And as you can see, all our methods return this interface so that we can chain all the methods together to form the fluent language shown above (the one exception being our Generate() method where we just return our list of Facets that were generated):

    public interface IFacetMap<TResource>
    {
        IFacetMap<TResource> AddFacetOn<TResult>(Expression<Func<TResource, TResult>> facetValue);
        IFacetMap<TResource> AddFacetOn<TResult>(string facetName, Expression<Func<TResource, TResult>> facetValue);
        IEnumerable<Facet<TResource>> GenerateFrom(IEnumerable<TResource> resources);
    }

Why the "Expression<Func<X, Y>>" instead of just "Func<X, Y>". This is more a matter of convenience for the end-user. The end-user can write the code as if it was a normal Func<X, Y>, but we can do some fun things with the lambda expression like automatically generating the name of the facet based on the property or method the user passes in (notice that in the case of a more complex lambda expression, the user must specify the facet name since there is no way to generate a guaranteed user-friendly name for the lambda expression).

Internally, we are using a Dictionary<string, Delegate> to store all the passed in lambda expressions that are going to be used to generate our facets with. In the case where a facet name isn't explicitly stated, we automatically use the name of the Property or Method (depending on which type of expression was passed in):

        private Dictionary<string, Delegate> facetGenerators;

        public IFacetMap<TResource> AddFacetOn<TResult>(Expression<Func<TResource, TResult>> facetValue)
        {
            string facetName;
            if (facetValue.Body.NodeType == ExpressionType.MemberAccess)
            {
                MemberExpression expression = (MemberExpression)facetValue.Body;
                facetName = expression.Member.Name;
            }
            else if (facetValue.Body.NodeType == ExpressionType.Call)
            {
                MethodCallExpression expression = (MethodCallExpression)facetValue.Body;
                facetName = expression.Method.Name;
            }
            else
            {
                throw new InvalidHeadingExpressionException();
            }

            AddFacetOn(facetName, facetValue);
            return this;
        }

        public IFacetMap<TResource> AddFacetOn<TResult>(string facetName, Expression<Func<TResource, TResult>> facetValue)
        {
            if (!facetGenerators.ContainsKey(facetName))
            {
                facetGenerators.Add(facetName, facetValue.Compile());
            }
            else
            {
                throw new NonUniqueFacetAddedException();
            }

            return this;
        }

The last thing we need to do is implement our Generate() method. Here, we are largely going to reuse the LINQ statement from our last post (check it out), the difference being that instead of pulling facets from properties decorated with our attribute we will use out internal dictionary that is built from our AddFacetOn methods.

        public IEnumerable<Facet<TResource>> GenerateFrom(IEnumerable<TResource> resources)
        {
            return from facet in facetGenerators
                   select new Facet<TResource>
                   {
                       Name = facet.Key,
                       Headings = (from resource in resources
                                   let value = facet.Value.DynamicInvoke(resource)
                                   orderby value
                                   group resource by value into g
                                   select new Heading<TResource>
                                   {
                                       Value = g.Key.ToString(),
                                       MatchCount = g.Count(),
                                       Filter = BuildFilter(facet.Value, g.Key.ToString())
                                   }).ToList()
                   };
        }

        private Func<TResource, bool> BuildFilter(Delegate facetValue, string headingValue)
        {
            return (resource) => facetValue.DynamicInvoke(resource).ToString() == headingValue;
        }

And finally, that for every header we generate, we also generate a Filter (shown above). This Filter is of type Func<TResource, bool> so that it can be used in a Where() method to filter our existing list of resources at a later time based on the header that was chosen.

As you can see, there is some cool stuff you can do with LINQ around fluent languages very easily. And not only that, you can add some cool navigational techniques to your application using Facet Mapping that is quite easy to implement using the new features in LINQ.

Posted in LINQ | Programming
 #       Comments [2]

Contact

Email Me Send mail to the author(s)

Calendar

<June 2008>
SunMonTueWedThuFriSat
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

About this site

Jason Olson's thoughts on Programming, Games, Music and Life in General

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2008
Jason Olson

Sign In
All Content © 2008, Jason Olson
Theme based on 'Business' created by Christoph De Baene (delarou)