Hello World - CLINQ Style

Before rigging CLINQ queries up to a data bound GUI such as WPF, it is often helpful to write a very simple use case tester just to see the technology in action.
To start, create a new Console application and reference the ContinuousLinq Assembly that you downloaded from the latest release or that you built on your own using Visual Studio 2008.
In this sample, build a Customer class that looks like the one below:

public class Customer : INotifyPropertyChanged
{
    private int _age;
    private string _name;

    public int Age
    {
      get { return _age; }
      set
      {
        _age = value;
        NotifyChanged("Age");
      }
    }

    public string Name
    {
      get { return _name; }
      set
      {
        _name = value;
        NotifyChanged("Name");
      }
    }

    private void NotifyChanged(string propName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}



Once you have your customer class built, you can create a ContinuousCollection to hold the source list and you can then create a query to hold all Customers of legal drinking age (for this sample, that's 21):

    ContinuousCollection<Customer> _source = new ContinuousCollection<Customer>();
    ContinuousCollection<Customer> _legalDrinkers = from cust in _source
                                                                              where cust.Age >= 21
                                                                              select cust;


Note that defining the second query didn't require any items to be in the source collection, which is part of the benefit of using CLINQ. Now you can attach to the CollectionChanged event handler of the _legalDrinkers collection so you can watch when items are added:

    _legalDrinkers.CollectionChanged += 
         new System.Collections.Specialized.NotifyCollectionChangedEventHandler(legalDrinkers_CollectionChanged);


And your event handler:

static void legalDrinkers_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    if (e.Action == NotifyCollectionChangedAction.Add)
    {
        Console.WriteLine("Item Added.");
    }            
}


At this point you have a source collection and you also have a ContinuousCollection result set that will continuously update itself when items are added to the source.
To see this in action, add the following few lines of code to the end of your Main method:

    _source.Add( new Customer() { Name = "Bob", Age = 20 });
    _source.Add( new Customer() { Name = "Al", Age = 23 });


When you run this application, _legalDrinkers will receive a collection changed event fire notification when Al is added to the source but not when Bob is added. This illustrates the continuous nature of CLINQ and how you can declaratively define dynamic, streaming views of data.

The last test that you want to do in order to make sure that CLINQ is functioning properly is to increase someone's age and make sure that the modified
customer is then added to the output collection automatically. To do this, add the following line of code to your project:

    _source[0].Age = 35; // Bob grew up!


Now you should receive two collection changed event firings for the output collection.
The first one for when Al is added to the source with a sufficient age to qualify for membership in the output collection,
and the second for when Bob is modified to subsequently pass the predicate condition on the output collection.

More detailed samples are available in the downloads section for each release.

For more information on how CLINQ works, check out this Wiki page: How CLINQ Works

Last edited Feb 13, 2008 at 1:49 PM by DotNetAddict, version 8

Comments

Nick60 Nov 28, 2008 at 1:41 PM 
First of all, tks for this great project!
I'd like to add some info on this demo, hoping it would help others to avoid some difficulties I've had realizing this simple "Hello world" app:

1. Add reference to ContinuousLinq.dll and to WindowsBase.dll

2. Add "using ContinuousLinq;" to c# source files "Program.cs" and "Customer.cs"

3. When copying _source and _LegalDrinkers definitions, remember to prefix with private static:

private static ContinuousCollection<Customer> _source = new ContinuousCollection<Customer>();

private static ContinuousCollection<Customer> _legalDrinkers =
from cust in _source
where cust.Age >= 21
select cust;

4. I've changed the event handler to show the name of the added item (and prefixed "NotifyCollectionChangedAction" with "System.Collections.Specialized." to avoid a otherwise needed using statement).

5. Here is the source:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ContinuousLinq;

namespace CLinq.HelloWorld
{
class Program
{
private static ContinuousCollection<Customer> _source = new ContinuousCollection<Customer>();
private static ContinuousCollection<Customer> _legalDrinkers = from cust in _source
where cust.Age >= 21
select cust;

static void Main(string[] args)
{
_legalDrinkers.CollectionChanged +=
new System.Collections.Specialized.
NotifyCollectionChangedEventHandler(legalDrinkers_CollectionChanged);

Console.WriteLine("Application started...");

_source.Add(new Customer() { Name = "Bob", Age = 20 });
_source.Add(new Customer() { Name = "Al", Age = 23 });
_source.Add(new Customer() { Name = "Elvis", Age = 25 });

Console.WriteLine("Hit a key to grow Bob's age to 21...");
Console.ReadKey();

_source[0].Age = 21; // Bob grew up!

Console.WriteLine("Hit a key to close application...");
Console.ReadKey();
}

static void legalDrinkers_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
{
Console.WriteLine("Item Added: {0}",((Customer)e.NewItems[0]).Name);
}
}
}
}


Have fun!