<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Patrick Steele&amp;#39;s .NET Blog</title><subtitle type="html">Implements ICodeWithDotNet</subtitle><id>http://weblogs.asp.net/psteele/atom.aspx</id><link rel="alternate" type="text/html" href="http://weblogs.asp.net/psteele/default.aspx" /><link rel="self" type="application/atom+xml" href="http://weblogs.asp.net/psteele/atom.aspx" /><generator uri="http://communityserver.org" version="3.0.20510.895">Community Server</generator><updated>2008-04-15T18:40:50Z</updated><entry><title>Ann Arbor Give Camp - Angel's Place</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/psteele/archive/2008/07/15/ann-arbor-give-camp-angel-s-place.aspx" /><id>http://weblogs.asp.net/psteele/archive/2008/07/15/ann-arbor-give-camp-angel-s-place.aspx</id><published>2008-07-15T17:48:03Z</published><updated>2008-07-15T17:48:03Z</updated><content type="html">&lt;p&gt;I was fortunate enough to be not only an organizer for the Ann Arbor Give Camp, but I also put myself on the development team for &lt;a href="http://www.angelsplace.com/" target="_blank"&gt;Angel's Place&lt;/a&gt; -- a local charity that helps place developmentally and physically challenged adults into good homes.&amp;nbsp; Our team of Paul Vollweiler, Carl Furrow, Aditya (Adi) Thakker and myself had a great time with our assigment.&lt;/p&gt; &lt;p&gt;After Friday's night's dinner, we met with our charitiy representative Marcie Levey and started working on a solution for their ever-growing waiting list (that is currently stored in Excel!).&amp;nbsp; Once we had a good idea of what we wanted to do, Paul set up an SVN repository for us to use for the weekend and then Carl jumped on the UI.&amp;nbsp; Paul, Adi and I whiteboarded the schema until about 1am Saturday morning.&amp;nbsp; Then we started coding our domain model using &lt;a href="http://www.castleproject.org/activerecord/index.html" target="_blank"&gt;ActiveRecord&lt;/a&gt;.&amp;nbsp; We were just about done at 2am, but we kept going for about another hour writing some code to populate the inital tables.&lt;/p&gt; &lt;p&gt;On Saturday we finalized the domain model and started work on the UI (WinForms).&amp;nbsp; Carl had organized the form into different tabs which related to the different sections of the paper form the Angel's Place staff is already familiar with.&amp;nbsp; In addition, he set up an architecture where each tab had a separate user control that was used to display data for a particular applicant.&amp;nbsp; This allowed all of us to work together on the same UI without having to worry about conflicts in VS.NET's "designer" files.&amp;nbsp; We just concentrated our UI coding on a particular user control!&amp;nbsp; That along made us very productive in the home stretch.&lt;/p&gt; &lt;p&gt;All in all it was a great success!&amp;nbsp; We didn't complete our app 100% before Sunday, but Paul has put a lot more work into it and we'll be handing it over to the charity some time this week.&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:51d156b4-b79c-4772-9139-2ebaec27a5d8" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati tags: &lt;a href="http://technorati.com/tags/annarborgivecamp" rel="tag"&gt;annarborgivecamp&lt;/a&gt;&lt;/div&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6402438" width="1" height="1"&gt;</content><author><name>PSteele</name><uri>http://weblogs.asp.net/members/PSteele.aspx</uri></author></entry><entry><title>Ann Arbor Give Camp - The Internet Speaks!</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/psteele/archive/2008/07/15/ann-arbor-give-camp-the-internet-speaks.aspx" /><id>http://weblogs.asp.net/psteele/archive/2008/07/15/ann-arbor-give-camp-the-internet-speaks.aspx</id><published>2008-07-15T17:36:23Z</published><updated>2008-07-15T17:36:23Z</updated><content type="html">&lt;p&gt;People are blogging about their experience at Give Camp.&amp;nbsp; Here's just a few:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.michaeleatonconsulting.com/blog/archive/2008/07/14/ann-arbor-give-camp---wrap-up.aspx"&gt;http://www.michaeleatonconsulting.com/blog/archive/2008/07/14/ann-arbor-give-camp---wrap-up.aspx&lt;/a&gt;&lt;br&gt;&lt;a href="http://srtsolutions.com/blogs/mikewoelmer/archive/2008/07/14/ann-arbor-give-camp-and-the-developers-in-room-be-240.aspx"&gt;http://srtsolutions.com/blogs/mikewoelmer/archive/2008/07/14/ann-arbor-give-camp-and-the-developers-in-room-be-240.aspx&lt;/a&gt;&lt;br&gt;&lt;a href="http://fullextension.blogspot.com/2008/07/ann-arbor-give-camp-report.html"&gt;http://fullextension.blogspot.com/2008/07/ann-arbor-give-camp-report.html&lt;/a&gt;&lt;br&gt;&lt;a href="http://theumlguy.spaces.live.com/blog/cns!B4665B67C2981533!231.entry"&gt;http://theumlguy.spaces.live.com/blog/cns!B4665B67C2981533!231.entry&lt;/a&gt;&lt;br&gt;&lt;a href="http://www.codinggeekette.com/2008/07/ann-arbor-give-camp-day-3.aspx"&gt;http://www.codinggeekette.com/2008/07/ann-arbor-give-camp-day-3.aspx&lt;/a&gt;&lt;br&gt;&lt;a href="http://www.joshholmes.com/2008/07/14/AnnArborGiveCamp2008.aspx"&gt;http://www.joshholmes.com/2008/07/14/AnnArborGiveCamp2008.aspx&lt;/a&gt;&lt;br&gt;&lt;a href="https://blogs.msdn.com/johnmullinax/archive/2008/07/13/giving-at-give-camp.aspx"&gt;https://blogs.msdn.com/johnmullinax/archive/2008/07/13/giving-at-give-camp.aspx&lt;/a&gt;&lt;br&gt;&lt;a href="http://markegilbert.wordpress.com/2008/07/13/amusing-bits-from-ann-arbor-give-camp/"&gt;http://markegilbert.wordpress.com/2008/07/13/amusing-bits-from-ann-arbor-give-camp/&lt;/a&gt;&lt;br&gt;&lt;/p&gt; &lt;p&gt;And even the press is getting involved:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.wwj.com/Ann-Arbor-Give-Camp---Amazing-/2595217"&gt;http://www.wwj.com/Ann-Arbor-Give-Camp---Amazing-/2595217&lt;/a&gt;&lt;br&gt;&lt;a href="http://www.earthtimes.org/articles/show/developers-create-500000-in-custom,467966.shtml"&gt;http://www.earthtimes.org/articles/show/developers-create-500000-in-custom,467966.shtml&lt;/a&gt;&lt;br&gt;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:76f58bb5-b55f-449f-b955-c636aee1acc0" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati tags: &lt;a href="http://technorati.com/tags/annarborgivecamp" rel="tag"&gt;annarborgivecamp&lt;/a&gt;&lt;/div&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6402388" width="1" height="1"&gt;</content><author><name>PSteele</name><uri>http://weblogs.asp.net/members/PSteele.aspx</uri></author></entry><entry><title>Ann Arbor Give Camp - WOW!</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/psteele/archive/2008/07/15/ann-arbor-give-camp-wow.aspx" /><id>http://weblogs.asp.net/psteele/archive/2008/07/15/ann-arbor-give-camp-wow.aspx</id><published>2008-07-15T17:26:31Z</published><updated>2008-07-15T17:26:31Z</updated><content type="html">&lt;p&gt;Wow!&amp;nbsp; Wow!&amp;nbsp; All I can say is WOW!&lt;/p&gt; &lt;p&gt;As one who helped organize this event (along with Microsoft's &lt;a href="http://blogs.msdn.com/jennifer/" target="_blank"&gt;Jennifer Marsman&lt;/a&gt;, &lt;a href="http://www.dotnetrockstar.com/" target="_blank"&gt;John Hopkins&lt;/a&gt; and Todd Bohlen) I was simply amazed, impressed and astounded about the weekend's events.&amp;nbsp; We had an awesome group of developers give up a beautiful July weekend in Michigan (and if you know Michigan, there haven't been too many nice weekends this summer) to come out and help charities solve their IT problems -- mostly by developing/enhancing a website or creating some kind of small data collection app.&lt;/p&gt; &lt;p&gt;While the majority of the weekend was head's down development, one of the best parts was Sunday afternoon where everyone (charities and developers) got together and showed the work that was done.&amp;nbsp; It was amazing to see the amount of work accomplished in a single weekend.&amp;nbsp; You've got to realize we had some charities come in with nothing -- no domain name, no website, no email, nothing! -- and walked out Sunday afternoon with a full CMS-backed website that allowed them to get their message out.&amp;nbsp; Awesome!&lt;/p&gt; &lt;p&gt;I can't wait to be a part of the next Give Camp!&amp;nbsp; Thanks to Jennifer for bringing me in on this.&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:1c6d5869-3739-4cbb-8a2d-b2d781fbf01f" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati tags: &lt;a href="http://technorati.com/tags/annarborgivecamp" rel="tag"&gt;annarborgivecamp&lt;/a&gt;&lt;/div&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6402337" width="1" height="1"&gt;</content><author><name>PSteele</name><uri>http://weblogs.asp.net/members/PSteele.aspx</uri></author></entry><entry><title>Moving from NVelocity to Brail</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/psteele/archive/2008/07/10/moving-from-nvelocity-to-brail.aspx" /><id>http://weblogs.asp.net/psteele/archive/2008/07/10/moving-from-nvelocity-to-brail.aspx</id><published>2008-07-11T03:58:27Z</published><updated>2008-07-11T03:58:27Z</updated><content type="html">&lt;p&gt;I'm a big fan of &lt;a href="http://www.castleproject.org/monorail/index.html" target="_blank"&gt;Castle's Monorail&lt;/a&gt; -- an MVC implementation for ASP.NET.&amp;nbsp; One of the nice things about it is that you get to pick which view engine you want to use.&amp;nbsp; The engines currently available are &lt;a href="http://www.castleproject.org/monorail/documentation/trunk/viewengines/nvelocity/index.html" target="_blank"&gt;NVelocity&lt;/a&gt;, &lt;a href="http://www.castleproject.org/monorail/documentation/trunk/viewengines/brail/index.html" target="_blank"&gt;Brail&lt;/a&gt; (based on &lt;a href="http://boo.codehaus.org/" target="_blank"&gt;Boo&lt;/a&gt;) and &lt;a href="http://www.aspview.com/" target="_blank"&gt;AspView&lt;/a&gt;.&amp;nbsp; There's also a &lt;a href="http://weblogs.asp.net/mirvodasergey/archive/2008/06/02/introducing-monorail-nhaml.aspx" target="_blank"&gt;new view engine for Monorail based on NHaml&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;When people first start learning Monorail, a lot of them use NVelocity.&amp;nbsp; It's a very simple templating language (which kind of forces you to keep complex logic out of the view) and most all of the Monorail documentation has samples using NVelocity.&amp;nbsp; I've used NVelocity for the few small Monorail projects I've done and I've been pretty happy with it.&lt;/p&gt; &lt;p&gt;I wanted to give Brail a try so I pulled out one of my older Monorail sample projects (doesn't everybody build a small sample app when they're first learning something?).&amp;nbsp; Monorail supports registering more than one view engine so I just updated my web.config to include brail as well.&amp;nbsp; This seemed like an easy way to run NVelocity and Brail side-by-side so I could play around with converting my old views to Brail as well as creating new ones.&lt;/p&gt; &lt;p&gt;I did notice one thing right away: You can't have a layout in one engine and the view in another.&amp;nbsp; My controller had a "default" layout (called default.vm).&amp;nbsp; I added a new method to the controller called "BrailTest" and then created my view "BrailTest.brail".&amp;nbsp; When Monorail found the "BrailTest.brail", that meant the layout had to be called "default.brail".&amp;nbsp; When the layout "default.brail" wasn't found, I got an error.&amp;nbsp; So even though it's technically possible to use two view engines at the same time, note that you'll have to maintain two layout files.&amp;nbsp; I don't even know what would happend with view components!&amp;nbsp; :)&lt;/p&gt; &lt;h3&gt;Starting Fresh With Brail&lt;/h3&gt; &lt;p&gt;So I decided to start a new Monorail project that would use Brail as the view engine.&amp;nbsp; Accessing my PropertyBag variables is almost exactly the same: $myVar in NVelocity vs. ${myVar} in Brail.&amp;nbsp; What I fell in love with his having a real .NET CLR language (Boo) for my view engine.&amp;nbsp; If I need some tricky logic, I just create a small helper method in Boo and I'm all set.&amp;nbsp; Very nice!&lt;/p&gt; &lt;p&gt;So here's a few points for anyone thinking about moving from NVelocity to Brail:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Brail is case sensitive.&amp;nbsp; As a C# programmer, I usually keep my "case" in order, but I got sloppy with NVelocity and used a lot of lowercase everywhere.&amp;nbsp; Can't do that with Brail anymore.&lt;/li&gt; &lt;li&gt;Layouts: While NVelocity uses "$childContent" to indicate the location of the rendered view, Brail uses "${ChildOutput}".&lt;/li&gt; &lt;li&gt;If you decide to create a function in Brail ("def"), it needs to be the first thing in the Brail file -- before any rendering code.&lt;/li&gt; &lt;li&gt;Boo uses indenting for blocks.&amp;nbsp; Brail adds an additional requirement of having an "end" keyword.&amp;nbsp; Not a big deal for me since I haven't done any real coding in Boo.&lt;/li&gt; &lt;li&gt;Make sure you include the ":" with your else statements!&amp;nbsp; This one had me puzzled for quite a while.&amp;nbsp; If you're not familiar with blocks in Boo/Brail, he's a sample if statement:&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;if charity.AssignedRoom is not null:&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // do some stuff&lt;br&gt;end&lt;/p&gt; &lt;p&gt;Note the "end" is specific to Brail (not Boo).&amp;nbsp; Well, if you need to add an else clause, make sure you include the ":" with the else:&lt;/p&gt; &lt;p&gt;if charity.AssignedRoom is not null:&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // do some stuff&lt;br&gt;else:&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // do some other stuff&lt;br&gt;end&lt;/p&gt; &lt;p&gt;All in all, I really like Brail and don't think I'll be moving back to NVelocity any time soon.&amp;nbsp; Well done &lt;a href="http://www.ayende.com/Blog/Default.aspx" target="_blank"&gt;Ayende&lt;/a&gt;!&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6387183" width="1" height="1"&gt;</content><author><name>PSteele</name><uri>http://weblogs.asp.net/members/PSteele.aspx</uri></author></entry><entry><title>Lansing Day of .NET Recap</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/psteele/archive/2008/06/23/lansing-day-of-net-recap.aspx" /><id>http://weblogs.asp.net/psteele/archive/2008/06/23/lansing-day-of-net-recap.aspx</id><published>2008-06-24T02:25:23Z</published><updated>2008-06-24T02:25:23Z</updated><content type="html">&lt;p&gt;I had a great time at the Lansing Day of .NET on Saturday!&amp;nbsp; Not only are people &lt;a href="http://keithelder.net/blog/archive/2008/06/22/Lansing-Day-of-.Net---A-Blast.aspx" target="_blank"&gt;blogging&lt;/a&gt; about &lt;a href="http://joshua-clark.blogspot.com/2008/06/lansing-day-of-net.html" target="_blank"&gt;it&lt;/a&gt;, but it &lt;a href="http://www.wlns.com/global/story.asp?s=8537292" target="_blank"&gt;made the news&lt;/a&gt; too!&amp;nbsp; Awesome job guys.&amp;nbsp; You packed a lot of great stuff in one day.&amp;nbsp; 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.&lt;/p&gt; &lt;p&gt;I didn't get there in time to see &lt;a href="http://michaeleatonconsulting.com/blog/" target="_blank"&gt;Michael Eaton's&lt;/a&gt; ActiveRecord talk.&amp;nbsp; But I did catch &lt;a href="http://jrwren.wrenfam.com/blog/" target="_blank"&gt;Jay's&lt;/a&gt; Windsor talk.&amp;nbsp; After lunch, I did my &lt;a href="http://www.castleproject.org/monorail/index.html" target="_blank"&gt;Monorail&lt;/a&gt; presentation.&amp;nbsp; This was an expanded version of my 30-minute Monorail "overview" I gave during a vendor session at &lt;a href="http://www.codemash.org/" target="_blank"&gt;CodeMash&lt;/a&gt; this past January.&amp;nbsp; I took out a couple of the "flashy demos" of scaffolding and AJAX and got a bit more into the details of Monorail.&amp;nbsp; 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.&amp;nbsp; Probably a bit more of me actually coding a few controllers and less viewing code "concepts" in Powerpoint.&lt;/p&gt; &lt;p&gt;But the best part was my speaker badge &lt;a href="http://keithelder.net/blog/archive/2008/06/22/Lansing-Day-of-.Net---A-Blast.aspx" target="_blank"&gt;signed by The Elder&lt;/a&gt; himself!&amp;nbsp; I will cherish it for years to come.&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.lotsofemail.com/blog_images/LansingDayof.NETRecap_13B4B/ElderSig.jpg" target="_blank"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="185" alt="ElderSig" src="http://www.lotsofemail.com/blog_images/LansingDayof.NETRecap_13B4B/ElderSig_thumb.jpg" width="244" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6313293" width="1" height="1"&gt;</content><author><name>PSteele</name><uri>http://weblogs.asp.net/members/PSteele.aspx</uri></author></entry><entry><title>Speaking at Lansing Day of .NET</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/psteele/archive/2008/05/28/speaking-at-lansing-day-of-net.aspx" /><id>http://weblogs.asp.net/psteele/archive/2008/05/28/speaking-at-lansing-day-of-net.aspx</id><published>2008-05-29T02:42:48Z</published><updated>2008-05-29T02:42:48Z</updated><content type="html">&lt;p&gt;I got an email last week informing me that my &lt;a href="http://www.castleproject.org/monorail/index.html" target="_blank"&gt;Monorail&lt;/a&gt; talk has been accepted for &lt;a href="http://www.dayofdotnet.org/Lansing/2008/Default.aspx" target="_blank"&gt;Lansing's Day of .NET&lt;/a&gt; on June 21st.&amp;nbsp; Woo Hoo!!&amp;nbsp; If you check out the &lt;a href="http://www.dayofdotnet.org/Lansing/2008/Sessions.aspx" target="_blank"&gt;session list&lt;/a&gt;, you'll see that &lt;a href="http://mjeaton.net/" target="_blank"&gt;Michael Eaton&lt;/a&gt; will be presenting an &lt;a href="http://www.castleproject.org/activerecord/index.html" target="_blank"&gt;ActiveRecord&lt;/a&gt; session and &lt;a href="http://jrwren.wrenfam.com/blog/" target="_blank"&gt;Jay Wren&lt;/a&gt; will be using &lt;a href="http://www.castleproject.org/container/index.html" target="_blank"&gt;Windsor Container&lt;/a&gt; for is IoC talk.&amp;nbsp; We've got just about the whole &lt;a href="http://www.castleproject.org/" target="_blank"&gt;Castle Project&lt;/a&gt; stack covered -- in one day!&amp;nbsp; And the event is totally free!&amp;nbsp; Don't miss it!&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.dayofdotnet.org/Lansing/" target="_blank"&gt;&lt;img alt="Lansing Day of .Net, 21 June 2008 - I'll be there!" src="http://www.dayofdotnet.org/Lansing/2008/images/ldodn-160x100inv.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6227611" width="1" height="1"&gt;</content><author><name>PSteele</name><uri>http://weblogs.asp.net/members/PSteele.aspx</uri></author></entry><entry><title>Ann Arbor GiveCamp</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/psteele/archive/2008/05/23/ann-arbor-givecamp.aspx" /><id>http://weblogs.asp.net/psteele/archive/2008/05/23/ann-arbor-givecamp.aspx</id><published>2008-05-23T21:27:12Z</published><updated>2008-05-23T21:27:12Z</updated><content type="html">&lt;p&gt;I'm proud to announce that we've now got a website for the &lt;a href="http://www.annarborgivecamp.org/" target="_blank"&gt;Ann Arbor Give Camp&lt;/a&gt;.&amp;nbsp; This is a great opportunity for local developers to give back to the local community.&amp;nbsp; The &lt;a href="http://www.annarborgivecamp.org/" target="_blank"&gt;website&lt;/a&gt; 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...).&amp;nbsp; We take a bunch of local developers that have volunteered their time for a weekend and we get stuff done!&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.wearemicrosoft.com/WAM/Home.aspx" target="_blank"&gt;Dallas&lt;/a&gt; and &lt;a href="http://coders4charities.org/" target="_blank"&gt;Kansas City&lt;/a&gt; have recently done &lt;a href="http://givecamp.org/" target="_blank"&gt;Give Camps&lt;/a&gt; and they've gone over very well.&amp;nbsp; We've got a great set of folks to help organize this event: Microsoft's &lt;a href="http://blogs.msdn.com/jennifer/default.aspx" target="_blank"&gt;Jennifer Marsman&lt;/a&gt;, &lt;a href="http://srtsolutions.com/blogs/billwagner/" target="_blank"&gt;Bill Wagner&lt;/a&gt;, myself, &lt;a href="http://www.dotnetrockstar.com/index.html" target="_blank"&gt;John Hopkins&lt;/a&gt; and many others.&amp;nbsp; 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.&lt;/p&gt; &lt;p&gt;If you want to help out as a developer, go &lt;a href="http://www.annarborgivecamp.org/DevRegister.aspx" target="_blank"&gt;register at the site&lt;/a&gt;.&amp;nbsp; We're looking for all types of people -- PHP, Ruby, MySql, .NET, Sql Server, Web -- not just .NET developers.&amp;nbsp; We'll be holding the event at &lt;a href="http://www.wccnet.edu/" target="_blank"&gt;Washtenaw Community College&lt;/a&gt; on July 11th, 12th and 13th.&amp;nbsp; WCC is a great venue.&amp;nbsp; We've held a number of Day of .NET events there in the past and have been very happy with them.&amp;nbsp; And to show just how great WCC, &lt;strong&gt;&lt;em&gt;they've donated the space and internet access for this event!&lt;/em&gt;&lt;/strong&gt;&amp;nbsp; Awesome!&lt;/p&gt; &lt;p&gt;If you know of any charities that need help, &lt;a href="http://www.annarborgivecamp.org" target="_blank"&gt;send them over to the site&lt;/a&gt;.&amp;nbsp; Verio has already committed to providing &lt;strong&gt;free webhosting for two (2) years&lt;/strong&gt; to any charity that we help out during the Give Camp!&lt;/p&gt; &lt;p&gt;If you have any questions, &lt;a href="http://weblogs.asp.net/psteele/contact.aspx" target="_blank"&gt;drop me an email&lt;/a&gt; or check out the &lt;a href="http://www.annarborgivecamp.org" target="_blank"&gt;website&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6215058" width="1" height="1"&gt;</content><author><name>PSteele</name><uri>http://weblogs.asp.net/members/PSteele.aspx</uri></author></entry><entry><title>Come to GANG next week!</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/psteele/archive/2008/05/16/come-to-gang-next-week.aspx" /><id>http://weblogs.asp.net/psteele/archive/2008/05/16/come-to-gang-next-week.aspx</id><published>2008-05-16T12:53:20Z</published><updated>2008-05-16T12:53:20Z</updated><content type="html">&lt;p&gt;Next week, our local user group (&lt;a href="http://www.migang.org/" target="_blank"&gt;GANG&lt;/a&gt;) is having Jason Beres -- INETA Speaker and Director of Product Management for Infragistics -- come and talk about building applications with Silverlight 2.0.&amp;nbsp; I'm really looking forward to this one since I haven't had time to dive into Silverlight myself.&amp;nbsp; Come on down to &lt;a href="http://www.microsoft.com/about/companyinformation/usaoffices/heartland/southfield.mspx" target="_blank"&gt;Microsoft's Southfield, Michigan offices&lt;/a&gt; on Wednesday, May 21st at 6:30pm.&lt;/p&gt; &lt;p&gt;PS: Sorry about the &lt;a href="http://www.migang.org/" target="_blank"&gt;GANG website&lt;/a&gt; -- it's a little plain right now.&amp;nbsp; We're in the middle of re-working the website and should have the new one up before next weeks meeting.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6195592" width="1" height="1"&gt;</content><author><name>PSteele</name><uri>http://weblogs.asp.net/members/PSteele.aspx</uri></author></entry><entry><title>The Elder will be back!</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/psteele/archive/2008/05/14/the-elder-will-be-back.aspx" /><id>http://weblogs.asp.net/psteele/archive/2008/05/14/the-elder-will-be-back.aspx</id><published>2008-05-14T16:41:04Z</published><updated>2008-05-14T16:41:04Z</updated><content type="html">&lt;p&gt;&lt;a href="http://keithelder.net/blog/Default.aspx" target="_blank"&gt;Keith Elder&lt;/a&gt; will be &lt;a href="http://feeds.feedburner.com/~r/keithelder/~3/287527204/Speaking-at-Lansing-MI-Day-of-.Net-Thanks-To-Passing.aspx" target="_blank"&gt;back in Michigan&lt;/a&gt; next month for the &lt;a href="http://www.dayofdotnet.org/" target="_blank"&gt;Lansing Day of .NET&lt;/a&gt;!&amp;nbsp; This is great news.&amp;nbsp; Keith is a great presenter and is always entertaining and informative.&amp;nbsp; I've submitted a couple of abstracts myself.&amp;nbsp; Even if I don't present, I'll still be there.&lt;/p&gt; &lt;p&gt;Keep watching &lt;a href="http://www.dayofdotnet.org/" target="_blank"&gt;the site&lt;/a&gt; to see what other great speaker speakers will be sharing their expertise at this FREE all-day event.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6189042" width="1" height="1"&gt;</content><author><name>PSteele</name><uri>http://weblogs.asp.net/members/PSteele.aspx</uri></author></entry><entry><title>Lazy Loading/Eager Loading</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/psteele/archive/2008/05/07/lazy-loading-eager-loading.aspx" /><id>http://weblogs.asp.net/psteele/archive/2008/05/07/lazy-loading-eager-loading.aspx</id><published>2008-05-07T14:00:34Z</published><updated>2008-05-07T14:00:34Z</updated><content type="html">&lt;p&gt;The &lt;a href="http://blogs.hibernatingrhinos.com/nhibernate/Default.aspx" target="_blank"&gt;NHibernate FAQ&lt;/a&gt; has a &lt;a href="http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/05/06/loading-a-complex-object-graph.aspx" target="_blank"&gt;new post&lt;/a&gt; about complex object graphs and lazy loading.&amp;nbsp; If you use &lt;a href="http://www.nhibernate.org/" target="_blank"&gt;NHibernate&lt;/a&gt; (or, &lt;a href="http://www.castleproject.org/activerecord/index.html" target="_blank"&gt;ActiveRecord&lt;/a&gt; -- which makes NHibernate a whole lot easier), it's worth a look.&amp;nbsp; The technique described can greatly improve the way your app interacts with the database.&amp;nbsp; &lt;a href="http://en.wikipedia.org/wiki/Object-relational_mapping" target="_blank"&gt;OR mappers&lt;/a&gt; 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.&lt;/p&gt; &lt;p&gt;If you're using &lt;a href="http://www.castleproject.org/activerecord/index.html" target="_blank"&gt;ActiveRecord&lt;/a&gt;, here's a few more items regarding lazy loading:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.castleproject.org/activerecord/documentation/v1rc1/usersguide/lazy.html" target="_blank"&gt;Enabling Lazy Loading in ActiveRecord&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.castleproject.org/activerecord/documentation/trunk/advanced/tuning.html" target="_blank"&gt;Tuning ActiveRecord&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.ayende.com/Blog/archive/7627.aspx" target="_blank"&gt;Combating the Select N + 1 Problem In NHibernate&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6165581" width="1" height="1"&gt;</content><author><name>PSteele</name><uri>http://weblogs.asp.net/members/PSteele.aspx</uri></author></entry><entry><title>Navigating around in the VS.NET IDE</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/psteele/archive/2008/05/05/navigating-around-in-the-vs-net-ide.aspx" /><id>http://weblogs.asp.net/psteele/archive/2008/05/05/navigating-around-in-the-vs-net-ide.aspx</id><published>2008-05-05T14:58:46Z</published><updated>2008-05-05T14:58:46Z</updated><content type="html">&lt;p&gt;Last week, &lt;a href="http://srtsolutions.com/blogs/billwagner" target="_blank"&gt;Bill Wagner&lt;/a&gt; and I were providing some C# training for one of our clients.&amp;nbsp; Bill showed the class how to use F12 to jump to the definition of a method.&amp;nbsp; One of the students asked how to go back to your previous position and Bill didn't know the key binding off hand.&lt;/p&gt; &lt;p&gt;As someone who comes from a VB6 background, I've maintained my VB6 keyboard mappings since I moved to C# in 2003.&amp;nbsp; 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.&lt;/p&gt; &lt;p&gt;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.&amp;nbsp; First off, I wanted to see what IDE command is mapped to my "go back" function.&amp;nbsp; 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):&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="386" alt="image" src="http://www.lotsofemail.com/blog_images/NavigatingaroundintheVS.NETIDE_9A61/image.png" width="648" border="0"&gt; &lt;/p&gt; &lt;p&gt;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.&amp;nbsp; Now I changed my keyboard mapping scheme to C# and entered "View.NavigateBackward" into the "Show commands containing" field:&lt;/p&gt; &lt;p&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="386" alt="image" src="http://www.lotsofemail.com/blog_images/NavigatingaroundintheVS.NETIDE_9A61/image_3.png" width="648" border="0"&gt; &lt;/p&gt; &lt;p&gt;So I see control and "-" (minus) is the keystroke to jump back in C#.&amp;nbsp; I changed my IDE settings to use C# and tested this out.&amp;nbsp; 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.&amp;nbsp; :)&lt;/p&gt; &lt;p&gt;And now I've changed my settings back to VB6 mapping scheme since I'm a creature of habit!&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6159597" width="1" height="1"&gt;</content><author><name>PSteele</name><uri>http://weblogs.asp.net/members/PSteele.aspx</uri></author></entry><entry><title>LINQ: Deferred Execution</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/psteele/archive/2008/04/18/linq-deferred-execution.aspx" /><id>http://weblogs.asp.net/psteele/archive/2008/04/18/linq-deferred-execution.aspx</id><published>2008-04-18T18:22:45Z</published><updated>2008-04-18T18:22:45Z</updated><content type="html">&lt;p&gt;Another interesting tidbit I learned about at the summit was deferred execution of LINQ queries.&lt;/p&gt; &lt;p&gt;Here's an example that highlights what deferred execution means to you.&amp;nbsp;&amp;nbsp; Let's create a Customer class and then build up a list of customers:&lt;/p&gt; &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; height: 113px; background-color: #f4f4f4; max-height: 200px"&gt; &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Customer&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; ID { get; set; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Name { get; set; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; Balance { get; set; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; height: 162px; background-color: #f4f4f4; max-height: 200px"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; List&amp;lt;Customer&amp;gt; GetCustomers()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;Customer&amp;gt;()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Customer {ID = 1, Name=&lt;span style="color: #006080"&gt;"Bill"&lt;/span&gt;, Balance = 22.50},&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Customer {ID = 2, Name=&lt;span style="color: #006080"&gt;"Bob"&lt;/span&gt;, Balance = 0.00},&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Customer {ID = 3, Name=&lt;span style="color: #006080"&gt;"Joe"&lt;/span&gt;, Balance = -5.00}&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;     };&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;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):&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; height: 211px; background-color: #f4f4f4; max-height: 200px"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; var customers = GetCustomers();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; firstLetter = &lt;span style="color: #006080"&gt;"B"&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; var query = from c &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; customers&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;where&lt;/span&gt; c.Name.StartsWith(firstLetter)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;             select c;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt; firstLetter = &lt;span style="color: #006080"&gt;"J"&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (Customer c &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; query)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;     Console.WriteLine(c.Name);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;What do you think prints out?&amp;nbsp; Due to deferred execution, the application will only print "Joe", not "Bill" and "Bob" as you might expect.&lt;/p&gt;
&lt;p&gt;The code executed in line 4 only builds the query into a query expression tree.&amp;nbsp; And that expression tree includes a reference to the "firstLetter" variable, not its contents.&amp;nbsp; The expression tree is not executed until line 9 when a foreach loop is used.&amp;nbsp; As a result, the value of the "firstLetter" variable is not obtained until line 9.&lt;/p&gt;
&lt;p&gt;So be careful how you use locally-scoped variables in your LINQ queries and be aware of deferred execution in LINQ queries.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6110559" width="1" height="1"&gt;</content><author><name>PSteele</name><uri>http://weblogs.asp.net/members/PSteele.aspx</uri></author></entry><entry><title>Extension Methods: Behind the scenes</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/psteele/archive/2008/04/18/extension-methods-behind-the-scenes.aspx" /><id>http://weblogs.asp.net/psteele/archive/2008/04/18/extension-methods-behind-the-scenes.aspx</id><published>2008-04-18T18:21:19Z</published><updated>2008-04-18T18:21:19Z</updated><content type="html">&lt;p&gt;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.&amp;nbsp; 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.&amp;nbsp; This was my opportunity to get the information directly from the C# language PM &lt;a href="http://blogs.msdn.com/madst/" target="_blank"&gt;Mads Torgersen&lt;/a&gt;.&amp;nbsp; One thing I found interesting was how extension methods were implemented.&lt;/p&gt; &lt;p&gt;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.&amp;nbsp; In reality, you're not truly adding new methods, but the IDE experience makes it look that way so it flows very nicely.&lt;/p&gt; &lt;p&gt;First, let's look at how we'd tackle a problem without extension methods.&amp;nbsp; We have a simple Customer class.&amp;nbsp; I've used C# 3.0's auto-properties to allow me to quickly define the class:&lt;/p&gt; &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; height: 115px; background-color: #f4f4f4; max-height: 200px"&gt; &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Customer&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; ID { get; set; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Name { get; set; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; Balance { get; set; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Now let's create a list of customers since we're going to iterate over them later:&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; height: 167px; background-color: #f4f4f4; max-height: 200px"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; List&amp;lt;Customer&amp;gt; GetCustomers()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;Customer&amp;gt;()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Customer {ID = 1, Name=&lt;span style="color: #006080"&gt;"Bill"&lt;/span&gt;, Balance = 22.50},&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Customer {ID = 2, Name=&lt;span style="color: #006080"&gt;"Bob"&lt;/span&gt;, Balance = 0.00},&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Customer {ID = 3, Name=&lt;span style="color: #006080"&gt;"Joe"&lt;/span&gt;, Balance = -5.00}&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;     };&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Note that in the GetCustomers code above I'm utilizing C# 3.0 property initializers too to make this demo simple and concise.&lt;/p&gt;
&lt;p&gt;Now we get to the meat of the problem.&amp;nbsp; First off, we're assuming that the Customer class is in another DLL that we don't have source code for it.&amp;nbsp; We'd like to know which customer's are delinquent, i.e. a balance less than zero.&amp;nbsp; 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...).&amp;nbsp; And what if our client decided to change the definition of "delinquent" (for example "a balance less than -10.00)?&amp;nbsp; We'd have to change that balance check everywhere.&amp;nbsp; Instead, we'll create a utility method for this (since we can't simply add it to the Customer class):&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; height: 133px; background-color: #f4f4f4; max-height: 200px"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyExtensions&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; IsDelinquent1(Customer c)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; c.Balance &amp;lt; 0;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;(You'll see why I called it "IsDelinquent1" and not simply "IsDelinquent" shortly).&amp;nbsp; 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).&amp;nbsp; Now let's do a quick check to find delinquent customers:&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; height: 210px; background-color: #f4f4f4; max-height: 200px"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Method1()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     var customers = GetCustomers();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (Customer c &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; customers)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (MyExtensions.IsDelinquent1(c))&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;         {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;             Console.WriteLine(c.Name);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;         }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Pretty simple.&amp;nbsp; However, it is a little verbose.&amp;nbsp; Let's now look at how we can utilize extension methods to make this cleaner.&lt;/p&gt;
&lt;p&gt;We go back to our static "MyExtensions" class and add our extension method.&amp;nbsp; 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).&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; height: 81px; background-color: #f4f4f4; max-height: 200px"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; IsDelinquent2(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; Customer c)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; c.Balance &amp;lt; 0;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This looks almost &lt;strong&gt;exactly&lt;/strong&gt; like the first method (the code block is identical).&amp;nbsp; We've simply added the "this" keyword at the beginning of the parameter list (before the "Customer" reference).&amp;nbsp; 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.&amp;nbsp; That's the only difference!&lt;/p&gt;
&lt;p&gt;Utilizing this extension method makes the loop code much cleaner and easier to read:&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; height: 211px; background-color: #f4f4f4; max-height: 200px"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Method2()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     var customers = GetCustomers();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (Customer c &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; customers)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (c.IsDelinquent2())&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;         {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;             Console.WriteLine(c.Name);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;         }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Very nice!&lt;/p&gt;
&lt;p&gt;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).&amp;nbsp; 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).&amp;nbsp; You'll see that the IL code is &lt;strong&gt;exactly the same&lt;/strong&gt;, byte for byte.&amp;nbsp; That's because extension methods are not a CLR addition, they are a C# addition.&amp;nbsp; They're a neat "macro" that the C# compiler automatically does for you.&lt;/p&gt;
&lt;p&gt;It's a pretty neat implementation and can make interaction with external libraries a bit easier.&amp;nbsp; And if you're wondering, yes, the extension methods are listed as a method directly on the class with Intellisense.&amp;nbsp; 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.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6110555" width="1" height="1"&gt;</content><author><name>PSteele</name><uri>http://weblogs.asp.net/members/PSteele.aspx</uri></author></entry><entry><title>Adding Action Filters to MonoRail Controllers</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/psteele/archive/2008/04/15/adding-action-filters-to-monorail-controllers.aspx" /><id>http://weblogs.asp.net/psteele/archive/2008/04/15/adding-action-filters-to-monorail-controllers.aspx</id><published>2008-04-15T22:51:00Z</published><updated>2008-04-15T22:51:00Z</updated><content type="html">&lt;p&gt;&lt;a href="http://randomcode.net.nz" mce_href="http://randomcode.net.nz" target="_blank"&gt;Neal Blomfield&lt;/a&gt; made interesting use of MonoRail filters.&amp;nbsp; &lt;a href="http://randomcode.net.nz/2008/03/03/adding-action-filters-to-monorail-controllers/" mce_href="http://randomcode.net.nz/2008/03/03/adding-action-filters-to-monorail-controllers/" target="_blank"&gt;Check it out&lt;/a&gt;.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;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 &lt;code&gt;[SkipFilter]&lt;/code&gt; 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…&lt;/p&gt;&lt;/blockquote&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6102612" width="1" height="1"&gt;</content><author><name>PSteele</name><uri>http://weblogs.asp.net/members/PSteele.aspx</uri></author></entry><entry><title>Sessionless MonoRail Controllers</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/psteele/archive/2008/04/15/sessionless-monorail-controllers.aspx" /><id>http://weblogs.asp.net/psteele/archive/2008/04/15/sessionless-monorail-controllers.aspx</id><published>2008-04-15T22:40:50Z</published><updated>2008-04-15T22:40:50Z</updated><content type="html">&lt;p&gt;I saw this post on the &lt;a href="http://www.castleproject.org/community/mailinglists.html" target="_blank"&gt;Castle Users mailing list&lt;/a&gt; and thought it was interesting and I wanted to post it.&lt;/p&gt; &lt;p&gt;By default, &lt;a href="http://www.castleproject.org/monorail/index.html" target="_blank"&gt;MonoRail&lt;/a&gt; controllers assume that ASP.NET session state is enabled.&amp;nbsp; If you disable ASP.NET's session state inside web.config, you'll get an exception when &lt;a href="http://www.castleproject.org/monorail/index.html" target="_blank"&gt;MonoRail&lt;/a&gt; tries to process the request.&amp;nbsp; What you need to do in this situation is to add a ControllerDetails attribute to your controller and set "Sessionless = true".&amp;nbsp; Thanks to Roelof Blom for posting a quick solution.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6102603" width="1" height="1"&gt;</content><author><name>PSteele</name><uri>http://weblogs.asp.net/members/PSteele.aspx</uri></author></entry></feed>