Friday, September 24, 2010

Microsoft Light Switch - a New LOB Development Tool

I've been looking into LightSwitch from Microsoft.  Its Microsoft's newest foray into what I like to call Hyper-RAD.  It actually looks kind of interesting and brings a lot of tools originally developed as part of Microsoft's .NET tools arsenal.  I first heard of it from a .NET Rocks! pod cast.  See show #583 Jay Schmelzer unveils Microsoft LightSwitch.  Take a listen.

I'll be trying it out over the next few weeks.  Lets all hope its not another Access!

Fun With Reflection (and Generics).

On a recent project I had to hand write a lot of CRUD and I used SQL Views and Stored Procedures to isolate the MS-SQL database I was using. 

I found myself coding up a bunch of methods that made calls to those stored procedures and then populated objects in a generic List<> from the returned data set. After my Nth method I figured there had to be a better way, so I came up with the following:

public static List<T> SprocToList<T>(String SprocName, String Connection)
{
   List data = new List();
   Type c = typeof(T);
   T instanceOf;
   try
   {
     using (SqlConnection conn = new SqlConnection(Connection))
     {
      try
         {
            SqlCommand cmd = conn.CreateCommand();
            cmd.CommandText = SprocName;
            cmd.CommandType = CommandType.StoredProcedure;
            conn.Open();
            SqlDataReader reader = cmd.ExecuteReader();
            while (reader.Read())
            {
               instanceOf = (T)Activator.CreateInstance(
                            Type.GetType(c.AssemblyQualifiedName));
               foreach (var propInfo in c.GetProperties())
               {
                  try
                  {
                     if (reader[propInfo.Name] != DBNull.Value)
                        try
                        {
                           propInfo.SetValue(instanceOf, 
                                    reader[propInfo.Name], null);
                        }
                        catch (Exception oEx)
                        {
                           Console.WriteLine(oEx.Message);
                        }
                     else
                     {
                        Console.WriteLine("Value is null!!");
                     }
                  }
                  catch (Exception oEx)
                  {
                      Console.WriteLine(oEx.Message);
                  }
               }
               data.Add(instanceOf);
            }
         }
         catch (Exception oEx)
         {
            Console.WriteLine(oEx.Message);
            return null;
         }
     }
   }
   catch (Exception oEx)
   {
      Console.WriteLine(oEx.Message);
      return null;
   }
   return data;
}

This Generic method takes a stored procedure name and a SQL connection and returns a List<> of type T. It traverses the returned data set by getting the property names in the Object of type T and using those property names as the data set's field names. The Object of type T is instanced using reflection (see Activator.CreateInstance statement).

One caveat: Object of type T must have properties of the exact same name as the fields returned by the stored procedure.

This can be used for ObservableCollections as well. I hope this helps someone, although if you're considering using something like this you might consider Entity Framework 4.0 instead.

Sunday, September 12, 2010

Event Delegates – For The Object Challenged.

I remember when I first read about delegated events in .net. My first thought was “cool”. My second thought was “How does that work”?

It sounds neat. You have an event that will fire from a class when that class does something that some other class in your system may want to know about. Easy, right?

Well I'm not afraid to admit it wasn't easy for me. I was trained procedurally, objects were just abstract concepts when I was in collage. In procedural code your entire code base knows about public subroutines and functions contained with in it. My first thought was how does another class know that the delegated event fires? For that matter, how does one fire the event in the first place? Because of this procedural point of view, I thought that delegated events were just magically “out there” and once fired the event was there for anyone to use.

Well to understand delegates then consider the following rules:
  1. In order for a class to “listen” (subscribe) to a delegated event the subscribing class needs to know about the class that fires the delegate. This can be done by instantiating the class that fires the delegate directly, or by being passed to the listening class though a constructor for example.
  2. Delegated events must be “fired” in code. This for me was, for some reason, the hardest thing to understand at first, I thought that you just set up the event it it fired magically.

Consider the following screen snap from WPF user control I did for a project. It is a search term entry control. It does some input validation and then sends the search criteria entered to a class that listens to a few events the control fires. In the project this is for I have a number of grid based forms that communicate a lot of data in each grid. Because of the amount of data it became a requirement to allow filtering.


When the user presses either the Search or Reset buttons, the control does some input verification and then fires a “search” event that another class can subscribe to. The subscribing class then gets notice of the event and a set of arguments passed that it can then decide to act on or not. Now let me state here that I could have done this by putting a unique Search Bar and code on each form that required this ability, but I had 10 forms to provide this functionally for and the "copy/paste" approach (a typical one for procedural developers) would mean a LOT of copy and past code. NOT cool.

Lets look at the code behind that sets up the events:

public event EventHandler<SearchArgs> SearchPressed;
public event EventHandler<SearchArgs> SearchReset;

protected virtual void OnSearchPressed(ISearchItem SearchItem)
{
      if (SearchPressed != null)
      {
            SearchArgs args = new SearchArgs();
            args.SearchItem = GetSearchItem();
            SearchPressed(this, args);
      }
}
protected virtual void OnSearchReset()
{
      if (SearchReset != null)
      {
            SearchArgs args = new SearchArgs();
            SearchReset(this, args);
      }
}

The first two lines set up the event delegate declarations. Read line one as “I want a public event called SearchPressed that will pass along event arguments named SearchArgs”. SearchArgs inherits from System.EventsArgs – the base class for all event arguments.

This basic code sets up the declares for the delegated event. Note that delegates are MUCH easier in the 3.0 framework because of generics.

Ok – how do we fire the event? Consider the following code:

private void SearchBox_KeyDown(object sender, KeyEventArgs e)
{
      if (e.Key == Key.Enter)
      {
            OnSearchPressed(GetSearchItem());
      }
}
private void Search_Click(object sender, RoutedEventArgs e)
{
      OnSearchPressed(GetSearchItem());
}

The first event method handles an KeyDown event for the enter key on the text box where you enter your search criteria. The second event method handles the Search button click event. When each is activated then the OnSearchPressed() method is called. The act of call this event actually fires the event.

OK – we've fired the event, but now we have to have something listen to it. Who listens?

Remember this is a user control that takes input by a user and fires an event when the user presses the search button, or hits the enter key. To catch this event we need something to “listen to” or subscribe to the event.

This particular control is designed to be used on a containing UI control. To use the searchBar control I've will create a WPF form and place the search control on the form under the name searchBar1. See the code behind below:

public partial class MainWindow : Window
{
      public MainWindow()
      {
            InitializeComponent();
            this.searchBar1.SearchPressed += 
                         new EventHandlerSearchArgs>(searchBar1_SearchPressed);
            this.searchBar1.SearchReset += 
                         new EventHandlerSearchArgs>(searchBar1_SearchReset);
      }
      void searchBar1_SearchPressed(object sender, SearchControl.SearchArgs e)
      {
            if (e.SearchItem != null)
            {
                  MessageBox.Show("Search Event fired on containing form from 
                           Search User Control", "Delegate Example", MessageBoxButton.OK);
                  this.textBox1.Text = e.SearchItem.SearchTerm;
            }
      }
      void searchBar1_SearchReset(object sender, SearchControl.SearchArgs e)
      {
            MessageBox.Show("Reset Event fired on containing form from 
                            Search User Control" "Delegate Example", MessageBoxButton.OK);
            this.textBox1.Text = "";
      }
}

The above is the code behind of the WPF form. Now note the MainWindow constructor:

public MainWindow()
{
      InitializeComponent();
      this.searchBar1.SearchPressed += 
              new EventHandlerSearchArgs>(searchBar1_SearchPressed);
      this.searchBar1.SearchReset += 
             new EventHandlerSearchArgs>(searchBar1_SearchReset);
}
void searchBar1_SearchPressed(object sender, SearchControl.SearchArgs e)
{
      if (e.SearchItem != null)
      {
            MessageBox.Show("Search Event fired on containing form from Search 
                                    User Control", "Delegate Example", MessageBoxButton.OK);
            this.textBox1.Text = e.SearchItem.SearchTerm;
      }
}
void searchBar1_SearchReset(object sender, SearchControl.SearchArgs e)
{
       MessageBox.Show("Reset Event fired on containing form from Search User Control",
                                    "Delegate Example", MessageBoxButton.OK);
      this.textBox1.Text = "";
}

We initialize the form components on the first line. The second and third lines actually sets up the subscription to the events we want to listen to. Read the first line as “for the SearchPressed event I will instance a new event handler with the event arguments SearchControl.SearchArgs. This event will be handled by a method called serachBar1_SearchPressed method”. The second line does the same for the SearchReset event.

So, how does this work? See below:


This screen shot shows the results of entering the text “This is a test in the search box” and pressing the Search button. The event fires ON the serachBar control and sends the event arguments SearchControl.SearchArgs to the subscriber, in this case the WPF form that contains the user control. The next example shows the results of pressing the Reset button:


I hope this example shows you the basics of delegated events. Keep in mind that although this example uses UI components, you can do delegates for any sort of interaction you want.

I've included a zip of the example project here.

My thanks to Chris Dillon for conversations about this post.