Lansing Day of .NET Recap

I had a great time at the Lansing Day of .NET on Saturday!  Not only are people blogging about it, but it made the news too!  Awesome job guys.  You packed a lot of great stuff in one day.  As someone who helped plan the Ann Arbor Day of .NET last year, I know that it takes a lot of time and legwork to put one of those together.

I didn't get there in time to see Michael Eaton's ActiveRecord talk.  But I did catch Jay's Windsor talk.  After lunch, I did my Monorail presentation.  This was an expanded version of my 30-minute Monorail "overview" I gave during a vendor session at CodeMash this past January.  I took out a couple of the "flashy demos" of scaffolding and AJAX and got a bit more into the details of Monorail.  It went pretty well, but after doing a post-mortem (I always jot down notes on how I feel I did), I think I'd do this talk a little differently in the future.  Probably a bit more of me actually coding a few controllers and less viewing code "concepts" in Powerpoint.

But the best part was my speaker badge signed by The Elder himself!  I will cherish it for years to come.

ElderSig

Posted by PSteele | with no comments

Speaking at Lansing Day of .NET

I got an email last week informing me that my Monorail talk has been accepted for Lansing's Day of .NET on June 21st.  Woo Hoo!!  If you check out the session list, you'll see that Michael Eaton will be presenting an ActiveRecord session and Jay Wren will be using Windsor Container for is IoC talk.  We've got just about the whole Castle Project stack covered -- in one day!  And the event is totally free!  Don't miss it!

Lansing Day of .Net, 21 June 2008 - I'll be there!

Posted by PSteele | with no comments

Ann Arbor GiveCamp

I'm proud to announce that we've now got a website for the Ann Arbor Give Camp.  This is a great opportunity for local developers to give back to the local community.  The website has all the details but here it is in a nutshell: Local charities gives us a brief overview of some development-related task they need help with (building a new website, updating an existing website, a small data collection app, etc...).  We take a bunch of local developers that have volunteered their time for a weekend and we get stuff done!

Dallas and Kansas City have recently done Give Camps and they've gone over very well.  We've got a great set of folks to help organize this event: Microsoft's Jennifer Marsman, Bill Wagner, myself, John Hopkins and many others.  Our timeframe is pretty short, but we've already gotten a ton of interest from local developers when we've mentioned this at user group meetings.

If you want to help out as a developer, go register at the site.  We're looking for all types of people -- PHP, Ruby, MySql, .NET, Sql Server, Web -- not just .NET developers.  We'll be holding the event at Washtenaw Community College on July 11th, 12th and 13th.  WCC is a great venue.  We've held a number of Day of .NET events there in the past and have been very happy with them.  And to show just how great WCC, they've donated the space and internet access for this event!  Awesome!

If you know of any charities that need help, send them over to the site.  Verio has already committed to providing free webhosting for two (2) years to any charity that we help out during the Give Camp!

If you have any questions, drop me an email or check out the website.

Posted by PSteele | with no comments

Come to GANG next week!

Next week, our local user group (GANG) is having Jason Beres -- INETA Speaker and Director of Product Management for Infragistics -- come and talk about building applications with Silverlight 2.0.  I'm really looking forward to this one since I haven't had time to dive into Silverlight myself.  Come on down to Microsoft's Southfield, Michigan offices on Wednesday, May 21st at 6:30pm.

PS: Sorry about the GANG website -- it's a little plain right now.  We're in the middle of re-working the website and should have the new one up before next weeks meeting.

Posted by PSteele | with no comments

The Elder will be back!

Keith Elder will be back in Michigan next month for the Lansing Day of .NET!  This is great news.  Keith is a great presenter and is always entertaining and informative.  I've submitted a couple of abstracts myself.  Even if I don't present, I'll still be there.

Keep watching the site to see what other great speaker speakers will be sharing their expertise at this FREE all-day event.

Posted by PSteele | 1 comment(s)

Lazy Loading/Eager Loading

The NHibernate FAQ has a new post about complex object graphs and lazy loading.  If you use NHibernate (or, ActiveRecord -- which makes NHibernate a whole lot easier), it's worth a look.  The technique described can greatly improve the way your app interacts with the database.  OR mappers are nice, but you need to make sure you understand what is happening with the database calls that are made automatically by your OR framework.

If you're using ActiveRecord, here's a few more items regarding lazy loading:

Enabling Lazy Loading in ActiveRecord

Tuning ActiveRecord

Combating the Select N + 1 Problem In NHibernate

Posted by PSteele | with no comments

Navigating around in the VS.NET IDE

Last week, Bill Wagner and I were providing some C# training for one of our clients.  Bill showed the class how to use F12 to jump to the definition of a method.  One of the students asked how to go back to your previous position and Bill didn't know the key binding off hand.

As someone who comes from a VB6 background, I've maintained my VB6 keyboard mappings since I moved to C# in 2003.  Navigating around inside the VS.NET IDE has been a no-brainer for me since all of the keystrokes I used for the 7 or 8 years of VB development are the same in VS.NET -- assuming you use the VB6 keyboard layout.

I decided to see if C# has a default key binding to jump back to your previous positions after jumping to a method definition using F12.  First off, I wanted to see what IDE command is mapped to my "go back" function.  I pulled up the VS.NET IDE keyboard options, clicked on the "Press shortcut keys" texbox and hit the keyboard keystroke I use for jumping back to my previous position (Ctrl+Shift+F2):

 image

Looking in the "Shortcut currently used by" field, I see "View.NavigateBackward" is the command used in the IDE to navigate back to your previous position.  Now I changed my keyboard mapping scheme to C# and entered "View.NavigateBackward" into the "Show commands containing" field:

image

So I see control and "-" (minus) is the keystroke to jump back in C#.  I changed my IDE settings to use C# and tested this out.  Sure enough, I can use F12 to jump to a method definition and then ctrl+- to return to my previous position -- sort of like having my own little callstack within the IDE.  :)

And now I've changed my settings back to VB6 mapping scheme since I'm a creature of habit!

Posted by PSteele | 1 comment(s)

LINQ: Deferred Execution

Another interesting tidbit I learned about at the summit was deferred execution of LINQ queries.

Here's an example that highlights what deferred execution means to you.   Let's create a Customer class and then build up a list of customers:

   1: public class Customer
   2: {
   3:     public int ID { get; set; }
   4:     public string Name { get; set; }
   5:     public double Balance { get; set; }
   6: }
   1: static List<Customer> GetCustomers()
   2: {
   3:     return new List<Customer>()
   4:     {
   5:         new Customer {ID = 1, Name="Bill", Balance = 22.50},
   6:         new Customer {ID = 2, Name="Bob", Balance = 0.00},
   7:         new Customer {ID = 3, Name="Joe", Balance = -5.00}
   8:     };
   9: }

Now assume we're going to run a query to find all Customers whose first name begins with a particular letter (supplied in a variable):

   1: var customers = GetCustomers();
   2:  
   3: string firstLetter = "B";
   4: var query = from c in customers
   5:             where c.Name.StartsWith(firstLetter)
   6:             select c;
   7:  
   8: firstLetter = "J";
   9: foreach (Customer c in query)
  10: {
  11:     Console.WriteLine(c.Name);
  12: }

What do you think prints out?  Due to deferred execution, the application will only print "Joe", not "Bill" and "Bob" as you might expect.

The code executed in line 4 only builds the query into a query expression tree.  And that expression tree includes a reference to the "firstLetter" variable, not its contents.  The expression tree is not executed until line 9 when a foreach loop is used.  As a result, the value of the "firstLetter" variable is not obtained until line 9.

So be careful how you use locally-scoped variables in your LINQ queries and be aware of deferred execution in LINQ queries.

Posted by PSteele | 1 comment(s)

Extension Methods: Behind the scenes

One of the sessions I was able to attend (and talk about) at the MVP Summit involved some of the new features of C# 3.0.  My day job still has me doing a lot of C# 2.0 stuff so I haven't dived in too deeply to the new 3.0 stuff.  This was my opportunity to get the information directly from the C# language PM Mads Torgersen.  One thing I found interesting was how extension methods were implemented.

If you're not familiar with extension methods, here they are in a nutshell (and simplified): Extension methods allow you to add new methods to existing classes -- classes that you don't have source code access to and can't recompile with the new method.  In reality, you're not truly adding new methods, but the IDE experience makes it look that way so it flows very nicely.

First, let's look at how we'd tackle a problem without extension methods.  We have a simple Customer class.  I've used C# 3.0's auto-properties to allow me to quickly define the class:

   1: public class Customer
   2: {
   3:     public int ID { get; set; }
   4:     public string Name { get; set; }
   5:     public double Balance { get; set; }
   6: }

Now let's create a list of customers since we're going to iterate over them later:

   1: static List<Customer> GetCustomers()
   2: {
   3:     return new List<Customer>()
   4:     {
   5:         new Customer {ID = 1, Name="Bill", Balance = 22.50},
   6:         new Customer {ID = 2, Name="Bob", Balance = 0.00},
   7:         new Customer {ID = 3, Name="Joe", Balance = -5.00}
   8:     };
   9: }

Note that in the GetCustomers code above I'm utilizing C# 3.0 property initializers too to make this demo simple and concise.

Now we get to the meat of the problem.  First off, we're assuming that the Customer class is in another DLL that we don't have source code for it.  We'd like to know which customer's are delinquent, i.e. a balance less than zero.  It would be easy to simply loop through and check the Balance property, but we'd need that check everywhere we look for a delinquent customer (reports, inquiries, lookups, etc...).  And what if our client decided to change the definition of "delinquent" (for example "a balance less than -10.00)?  We'd have to change that balance check everywhere.  Instead, we'll create a utility method for this (since we can't simply add it to the Customer class):

   1: public static class MyExtensions
   2: {
   3:     public static bool IsDelinquent1(Customer c)
   4:     {
   5:         return c.Balance < 0;
   6:     }
   7: }

(You'll see why I called it "IsDelinquent1" and not simply "IsDelinquent" shortly).  We created a static class and created a utility method that will tell us if a customer is "delinquent" (based on our client's current definition).  Now let's do a quick check to find delinquent customers:

   1: private static void Method1()
   2: {
   3:     var customers = GetCustomers();
   4:  
   5:     foreach (Customer c in customers)
   6:     {
   7:         if (MyExtensions.IsDelinquent1(c))
   8:         {
   9:             Console.WriteLine(c.Name);
  10:         }
  11:     }
  12: }

Pretty simple.  However, it is a little verbose.  Let's now look at how we can utilize extension methods to make this cleaner.

We go back to our static "MyExtensions" class and add our extension method.  It's important to note that extension methods can only be defined in static classes that are contained directly in a namespace (i.e. not a nested class).

   1: public static bool IsDelinquent2(this Customer c)
   2: {
   3:     return c.Balance < 0;
   4: }

This looks almost exactly like the first method (the code block is identical).  We've simply added the "this" keyword at the beginning of the parameter list (before the "Customer" reference).  This tells the C# compiler (and the VS.NET IDE) that "IsDelinquent2" is an extension method on "Customer" since it appears right before a Customer parameter.  That's the only difference!

Utilizing this extension method makes the loop code much cleaner and easier to read:

   1: private static void Method2()
   2: {
   3:     var customers = GetCustomers();
   4:  
   5:     foreach (Customer c in customers)
   6:     {
   7:         if (c.IsDelinquent2())
   8:         {
   9:             Console.WriteLine(c.Name);
  10:         }
  11:     }
  12: }

Very nice!

Now the reason I've got static code all over this demo is because you can take all of the code, slap it into a VS2008 Console application and compile it (make sure the MyExtensions class is not nested within the default "Program" class).  Now fire up ILDASM and look at the decompiled IL for both "Method1" and "Method2" (I named them differently so you could compile them together and examine the differences).  You'll see that the IL code is exactly the same, byte for byte.  That's because extension methods are not a CLR addition, they are a C# addition.  They're a neat "macro" that the C# compiler automatically does for you.

It's a pretty neat implementation and can make interaction with external libraries a bit easier.  And if you're wondering, yes, the extension methods are listed as a method directly on the class with Intellisense.  They get a slightly different icon (I wasn't able to capture it with my screen capture utility) and the tooltip for the method in Intellisense has "(extension)" at the beginning of the method name.

Posted by PSteele | 2 comment(s)

Adding Action Filters to MonoRail Controllers

Neal Blomfield made interesting use of MonoRail filters.  Check it out.

Filters are commonly used for tasks like authentication and localisation, however by default they run for all actions in the controller and you must specify which actions to exclude using the [SkipFilter] attribute. In a majority of cases this works well as the filter is designed to handle cross-cutting concerns (which by definition affect most if not all actions), however there are times when you want to apply the filter to a minority of the actions in a controller, or add action specific metadata that may vary the way the filter executes depending on the action. Recently I came across just such a scenario…

Posted by PSteele
More Posts Next page »