<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>SoftSource Consulting: Blogs</title><link>http://blogs.sftsrc.com/MainFeed.aspx</link><description>The collected thoughts of NERDS</description><generator>Subtext Version 2.1.1.1</generator><item><title>Mine is the pattern...</title><link>http://blogs.sftsrc.com/stuart/archive/2009/06/08/165.aspx</link><pubDate>Mon, 08 Jun 2009 17:54:53 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2009/06/08/165.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/165.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/165.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2009/06/08/165.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/165.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Mine is the pattern...</source><description>&lt;span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: 'Times New Roman'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"&gt;
&lt;div style="margin: 0px; padding: 0.6em; color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); font-family: Georgia,'Times New Roman','Bitstream Charter',Times,serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 13px; line-height: 19px; font-size-adjust: none; font-stretch: normal;"&gt;
&lt;p&gt;Software is broken, from the first version&lt;br /&gt;
Fowler has spoken, his gospel word.&lt;br /&gt;
Praise for the patterns, praise for MVP&lt;br /&gt;
Praise for our passive view of our world.&lt;/p&gt;
&lt;p&gt;Hear there's a new thought, coming from Redmond&lt;br /&gt;
Wait it's an old thought we already had.&lt;br /&gt;
Praise for MVC, in its new format&lt;br /&gt;
Sprung in completeness where their feet pass.&lt;/p&gt;
&lt;p&gt;Mine is a castle, and it's named Windsor&lt;br /&gt;
Born not from one light, silver or gray.&lt;br /&gt;
Praise it with caution, praise it with warning&lt;br /&gt;
MS' recreation of the new way.&lt;/p&gt;
&lt;p&gt;&lt;span mce_name="em" mce_style="font-style: italic;" class="Apple-style-span" mce_fixed="1" style="font-style: italic;"&gt;(C) MVVMVPVC&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/span&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/165.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>SQL to Insert a State table</title><link>http://blogs.sftsrc.com/stuart/archive/2009/05/26/testing-the-waters.aspx</link><pubDate>Tue, 26 May 2009 23:52:40 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2009/05/26/testing-the-waters.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/159.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/159.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2009/05/26/testing-the-waters.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/159.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">SQL to Insert a State table</source><description>Just in case this is useful to anyone else who needs a SQL table populated with the 50 U.S. states plus D.C.&lt;br /&gt;
insert [State] ([Abbreviation], [Name])&lt;br /&gt;
select    'AL', 'Alabama'&lt;br /&gt;
union&lt;br /&gt;
select    'AK', 'Alaska'&lt;br /&gt;
union&lt;br /&gt;
select    'AZ', 'Arizona'&lt;br /&gt;
union&lt;br /&gt;
select    'AR', 'Arkansas'&lt;br /&gt;
union&lt;br /&gt;
select    'CA', 'California'&lt;br /&gt;
union&lt;br /&gt;
select    'CO', 'Colorado'&lt;br /&gt;
union&lt;br /&gt;
select    'CT', 'Connecticut'&lt;br /&gt;
union&lt;br /&gt;
select    'DE', 'Delaware'&lt;br /&gt;
union&lt;br /&gt;
select    'DC', 'District of Columbia'&lt;br /&gt;
union&lt;br /&gt;
select    'FL', 'Florida'&lt;br /&gt;
union&lt;br /&gt;
select    'GA', 'Georgia'&lt;br /&gt;
union&lt;br /&gt;
select    'HI', 'Hawaii'&lt;br /&gt;
union&lt;br /&gt;
select    'ID', 'Idaho'&lt;br /&gt;
union&lt;br /&gt;
select    'IL', 'Illinois'&lt;br /&gt;
union&lt;br /&gt;
select    'IN', 'Indiana'&lt;br /&gt;
union&lt;br /&gt;
select    'IA', 'Iowa'&lt;br /&gt;
union&lt;br /&gt;
select    'KS', 'Kansas'&lt;br /&gt;
union&lt;br /&gt;
select    'KY', 'Kentucky'&lt;br /&gt;
union&lt;br /&gt;
select    'LA', 'Louisiana'&lt;br /&gt;
union&lt;br /&gt;
select    'ME', 'Maine'&lt;br /&gt;
union&lt;br /&gt;
select    'MD', 'Maryland'&lt;br /&gt;
union&lt;br /&gt;
select    'MA', 'Massachusetts'&lt;br /&gt;
union&lt;br /&gt;
select    'MI', 'Michigan'&lt;br /&gt;
union&lt;br /&gt;
select    'MN', 'Minnesota'&lt;br /&gt;
union&lt;br /&gt;
select    'MS', 'Mississippi'&lt;br /&gt;
union&lt;br /&gt;
select    'MO', 'Missouri'&lt;br /&gt;
union&lt;br /&gt;
select    'MT', 'Montana'&lt;br /&gt;
union&lt;br /&gt;
select    'NE', 'Nebraska'&lt;br /&gt;
union&lt;br /&gt;
select    'NV', 'Nevada'&lt;br /&gt;
union&lt;br /&gt;
select    'NH', 'New Hampshire'&lt;br /&gt;
union&lt;br /&gt;
select    'NJ', 'New Jersey'&lt;br /&gt;
union&lt;br /&gt;
select    'NM', 'New Mexico'&lt;br /&gt;
union&lt;br /&gt;
select    'NY', 'New York'&lt;br /&gt;
union&lt;br /&gt;
select    'NC', 'North Carolina'&lt;br /&gt;
union&lt;br /&gt;
select    'ND', 'North Dakota'&lt;br /&gt;
union&lt;br /&gt;
select    'OH', 'Ohio'&lt;br /&gt;
union&lt;br /&gt;
select    'OK', 'Oklahoma'&lt;br /&gt;
union&lt;br /&gt;
select    'OR', 'Oregon'&lt;br /&gt;
union&lt;br /&gt;
select    'PA', 'Pennsylvania'&lt;br /&gt;
union&lt;br /&gt;
select    'RI', 'Rhode Island'&lt;br /&gt;
union&lt;br /&gt;
select    'SC', 'South Carolina'&lt;br /&gt;
union&lt;br /&gt;
select    'SD', 'South Dakota'&lt;br /&gt;
union&lt;br /&gt;
select    'TN', 'Tennessee'&lt;br /&gt;
union&lt;br /&gt;
select    'TX', 'Texas'&lt;br /&gt;
union&lt;br /&gt;
select    'UT', 'Utah'&lt;br /&gt;
union&lt;br /&gt;
select    'VT', 'Vermont'&lt;br /&gt;
union&lt;br /&gt;
select    'VA', 'Virginia'&lt;br /&gt;
union&lt;br /&gt;
select    'WA', 'Washington'&lt;br /&gt;
union&lt;br /&gt;
select    'WV', 'West Virginia'&lt;br /&gt;
union&lt;br /&gt;
select    'WI', 'Wisconsin'&lt;br /&gt;
union&lt;br /&gt;
select    'WY', 'Wyoming'&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/159.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>Server Quest - A Day in the Life of a Geek</title><link>http://blogs.sftsrc.com/stuart/archive/2009/05/19/158.aspx</link><pubDate>Tue, 19 May 2009 22:13:53 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2009/05/19/158.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/158.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/158.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2009/05/19/158.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/158.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Server Quest - A Day in the Life of a Geek</source><description>Somewhere in Redmond, someone &lt;span style="font-style: italic;"&gt;wasn't&lt;/span&gt; busy for far too long:&lt;br /&gt;
&lt;a href="http://www.microsoft.com/click/serverquest/"&gt;http://www.microsoft.com/click/serverquest/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
This is a heck of a demonstration of just what &lt;a href="http://silverlight.net/"&gt;Silverlight&lt;/a&gt; can do though.  Very, very impressive!&lt;br /&gt;
&lt;br /&gt;
To learn how to create cutting edge &lt;a href="http://silverlight.net/"&gt;Silverlight&lt;/a&gt; applications, &lt;a href="http://events.sftsrc.com/"&gt;sign up for one of our one-day technical courses&lt;/a&gt; at &lt;br /&gt;
&lt;a href="http://events.sftsrc.com/"&gt;http://events.sftsrc.com/&lt;/a&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/158.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>SQL 2008 Management Studio - Unable to Enumerate Databases</title><link>http://blogs.sftsrc.com/stuart/archive/2009/05/13/155.aspx</link><pubDate>Wed, 13 May 2009 17:24:49 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2009/05/13/155.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/155.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/155.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2009/05/13/155.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/155.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">SQL 2008 Management Studio - Unable to Enumerate Databases</source><description>&lt;span style="font-style: italic; color: rgb(0, 51, 102);"&gt;"If at first you don't succeed..."&lt;/span&gt;&lt;br style="color: rgb(0, 0, 0);" /&gt;
&lt;br /&gt;
Apparently the cool new conclusion to this motto is &lt;a href="http://michellerafter.files.wordpress.com/2009/03/panic-button.jpg"&gt;"throw your hands in the air and panic"&lt;/a&gt;.  This is certainly how the SQL 2008 Management Studio reacts when it encounters a problem enumerating object explorer information for one or more databases on a server.  I recently installed the SQL 2008 tools and was quite surprised to encounter an error dialog following my first actions.  I connected to a server that contains several databases, only a few of which I have rights to access.  Upon expanding the Databases node in the Object Explorer window, I received the following error:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;img height="207" width="621" src="/images/blogs_sftsrc_com/stuart/05132009_SQL2K8_ErrorDialog.jpg" alt="" /&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px; color: rgb(51, 51, 153);"&gt; Failed to retrieve data for this request. (Microsoft.SqlServer.Management.Sdk.Sfc)&lt;br /&gt;
&lt;br /&gt;
Additional information:&lt;br /&gt;
An exception occured while executing a Transact-SQL statement or batch.&lt;br /&gt;
(Microsoft.SqlServer.ConnectionInfo)&lt;br /&gt;
The server principal "MyServerPrincipal" is not able to access the database "FirstDBInList" under the current security context. (Microsoft SQL Server, Error: 916)&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
Yikes!  I know that I don't have access to &lt;span style="font-style: italic;"&gt;FirstDBInList &lt;/span&gt;but I'm unsure as to why that would stop me from enumerating the databases on the server.  Typically I'm allowed to at least see the list so that I can interact with my database via that window.  I am unable to perform any operations on the databases to which I don't have rights but that shouldn't stop me from interacting with the databases for which I have been granted permissions.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold; text-decoration: underline; color: rgb(128, 0, 0);"&gt;What's the problem?&lt;/span&gt;&lt;br /&gt;
Then a little bell rung in my head.  I'd seen this before.  I remember this from the SQL 2000 days.  A little googling turned up &lt;a href="http://sqlblog.com/blogs/aaron_bertrand/archive/2008/07/07/a-little-management-studio-oops.aspx"&gt;this great article&lt;/a&gt; by &lt;a href="http://sqlblog.com/blogs/aaron_bertrand/default.aspx"&gt;Aaron Bertrand&lt;/a&gt;.  It turns out that the &lt;span style="font-style: italic;"&gt;Object Explorer Details&lt;/span&gt; window is part of the problem.  Whereas the Object Explorer window only shows the familiar list of nodes, the &lt;span style="font-style: italic;"&gt;Object Explorer Details&lt;/span&gt; window attempts to go one step further and show additional information about each database.  However, in order to show that information the studio attempts to connect to each of the databases in the list.  If the current user does not have rights to one or more of those databases and they are configured to auto-close (as many are in many environments) then studio will panic after it is unable to retrieve the information it requested.  Instead of degrading gracefully and graying out the node or simply moving onto the next database in the list, it simply halts all operations and throws up the error dialog seen above.  Not very shiny!  Remember too that this is the SQL 2008 Management Studio in its &lt;span style="font-weight: bold;"&gt;default&lt;/span&gt; configuration.  Not exactly an edge case.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold; text-decoration: underline; color: rgb(128, 0, 0);"&gt;How do I fix it?&lt;/span&gt;&lt;br /&gt;
In order to fix the issue we simply need to tell studio to not query the databases for information it won't be able to retrieve.  It turns out that the offender in this case is "Collation", or rather that studio is unable to determine the state of collation on databases to which appropriate rights have not been granted.  The following steps can be used to achieve this.&lt;br /&gt;
&lt;br /&gt;
First, open the &lt;span style="font-style: italic;"&gt;Object Explorer Details&lt;/span&gt; pane either by clicking &lt;span style="font-style: italic;"&gt;View-&amp;gt;Object Explorer Details&lt;/span&gt; or by pressing &lt;span style="font-style: italic;"&gt;F7&lt;/span&gt;.  Then double click &lt;span style="font-style: italic;"&gt;Databases &lt;/span&gt;in the right-hand pane.  Finally right-click the bar showing the column headers and uncheck Collation.  You can now close the &lt;span style="font-style: italic;"&gt;Object Explorer Details&lt;/span&gt; pane, right-click &lt;span style="font-style: italic;"&gt;Databases &lt;/span&gt;in the regular &lt;span style="font-style: italic;"&gt;Object Explorer &lt;/span&gt;pane and select &lt;span style="font-style: italic;"&gt;Refresh&lt;/span&gt;.  The node should now expand as expected.&lt;br /&gt;
&lt;br /&gt;
&lt;img height="116" width="340" alt="" src="/images/blogs_sftsrc_com/stuart/05132009_ShowObjectExplorerDetails.jpg" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;img height="153" width="538" alt="" src="/images/blogs_sftsrc_com/stuart/05312009_UncheckCollation.jpg" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold; text-decoration: underline; color: rgb(128, 0, 0);"&gt;Why did that work?&lt;/span&gt;&lt;br /&gt;
This solution works for the following reasons.  The &lt;span style="font-style: italic;"&gt;Object Explorer Details &lt;/span&gt;(OED) pane is used to show additional information about entities on a server.  The column headers in the &lt;span style="font-style: italic;"&gt;Databases &lt;/span&gt;view of OED each show a particular piece of information for each database on the server.  When the Databases node in the regular Object Explorer pane is expanded, the management studio attempts to query for the information for each of these selected column headers just in case the OED pane will be shown.  However, if the current user does not have rights to query for that information on one of the databases then an error is thrown and processing stops.  This has the unfortunate side-effect of also stopping the enumeration of the databases in the regular Object Explorer window.  By removing the Collation column from the OED view, we effectively removed the check for collation settings when enumerating the list of databases.  The other default columns all represent data that can be queried even on databases for which the current user does not have rights.  However, if you find that the error resurfaces, try removing all of the other column headers from this view.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold; text-decoration: underline; color: rgb(128, 0, 0);"&gt;What can we learn from this?&lt;/span&gt;&lt;br /&gt;
This illustrates a larger programming principal, one that is often ignored to the detrement of many software packages; error handling and graceful degradation.&lt;br /&gt;
&lt;br /&gt;
It is great that enumerating the data for the Object Explorer window also queries for information that the OED window might need.  However, it is not so great that a failure in the additional "helpful" task causes the originally requested operation to fail.  As a user the first assumption when encountering an error is that the current action being performed is responsible, not that some helpful side task was the culprit.  If helpful additional tasks are going to be performed, then wrap them in a layer of safety, have them handle their errors completely and get out of the way of the main task if they encounter a problem.&lt;br /&gt;
&lt;span style="font-weight: bold; text-decoration: underline; color: rgb(128, 0, 0);"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;span style="text-decoration: underline; color: rgb(0, 0, 0);"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;The second principal here is that of graceful degradation.  Often programs will show an error dialog or even quit completely when they run into a problem.  However, in many cases there is no need for such an abrupt halt.  The areas of the application that were of importance to the user might be completely unaffected by the problem that occured.  In the case of this management studio problem the user could have continued working quite happily without knowing whether collation was enabled for databases that they don't even have access rights to.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold; text-decoration: underline; color: rgb(128, 0, 0);"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;
Throwing an exception and halting all processing in this case is a bit like &lt;a href="http://farm1.static.flickr.com/149/419361622_c27fb6d492.jpg"&gt;taking the football home&lt;/a&gt; from the park just because you fell and scraped your knee.  It didn't make you many friends as a young MS-DOS program and it won't as an adult enterprise management application either.  Play nice...try, catch, and throw like the rest of the kids and leave the drama at home.&lt;/span&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/155.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>SSRS doesn't LIKE me anymore</title><link>http://blogs.sftsrc.com/stuart/archive/2009/05/08/154.aspx</link><pubDate>Fri, 08 May 2009 18:11:28 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2009/05/08/154.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/154.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/154.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2009/05/08/154.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/154.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">SSRS doesn't LIKE me anymore</source><description>When is % not equal to  %?  When you're using the LIKE statement in SQL Server Reporting Services.  If you've used the LIKE statement but haven't felt the love, it's because the standard wild-card operator (%) for a LIKE statement isn't the same in SSRS.  Instead of the  % operator they use *.&lt;br /&gt;
&lt;br /&gt;
So the statement:&lt;br /&gt;
 WHERE Customer.Email LIKE '%' + @qEmail + '%'&lt;br /&gt;
should instead be:&lt;br /&gt;
 WHERE Customer.Email LIKE '*' + @qEmail + '*'&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/154.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>Upcoming Developer Courses</title><link>http://blogs.sftsrc.com/stuart/archive/2009/04/14/147.aspx</link><pubDate>Tue, 14 Apr 2009 18:55:04 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2009/04/14/147.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/147.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/147.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2009/04/14/147.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/147.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Upcoming Developer Courses</source><description>&lt;div&gt;Spring is here and we're now offering a new set of courses for the coming months.  Be sure to check out the details below and reserve your seat now.  You can keep up to date with the latest course offerings at &lt;a href="http://events.sftsrc.com"&gt;http://events.sftsrc.com&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;April 22nd - 24th:  &lt;/span&gt;&lt;a href="http://events.sftsrc.com/EventDescription.aspx?EventId=394&amp;amp;AbstractId=12"&gt;Silverlight for the Web Developer&lt;/a&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt; Microsoft Silverlight is a cross-browser and cross-platform web-centric programming API which allows you to integrate extremely rich UI islands into a standard web application. Using Silverlight, developers can inject multimedia (video, audio, etc), user interactivity (games, gadgets) and other visual enhancements into their designs. This course examines the role of the Silverlight SDK and the numerous surrounding technologies (JavaScript, ASP.NET, XAML) and development tools (Microsoft Blend, Visual Studio 2005/2008 templates) used to build Silverlight-enabled web content.&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;May 11th - 13th: &lt;/span&gt;&lt;a href="http://events.sftsrc.com/EventDescription.aspx?EventId=1047&amp;amp;AbstractId=13"&gt;Windows Communication Foundation (WCF)&lt;/a&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt; Windows Communication Foundation (WCF) is an API used to build distributed applications using .NET 3.0 and higher. WCF was designed to expose the current multitude of Windows remoting APIs (web services, MSMQ, TCP, peer-to-peer, etc) from a single unified toolkit. In this course, attendees will examine the overall WCF programming model, binding choices, host options, security issues and the use of declarative markup to specify the underlying infrastructure.&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;May 26th - 27th: &lt;/span&gt;&lt;a href="http://events.sftsrc.com/EventDescription.aspx?EventId=392&amp;amp;AbstractId=15"&gt;LINQ&lt;/a&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt; You will learn to use the new .NET Framework 3.5 feature, Language Integrated Query (LINQ) to easily create complex data-independent queries. In addition, you’ll learn about the new language features added to Visual C# in Visual Studio 2008 in order to make LINQ possible. You’ll start by working through a quick overview of LINQ, and how it applies to working with collections of objects, retrieving data stored in SQL Server, and creating XML content. Subsequent topics introduce new LINQ-oriented language features, LINQ to Objects, LINQ to DataSets, LINQ to SQL, LINQ to XML, and LINQ to Entities. By the time you’ve completed the course, you’ll have a good understanding of how to construct LINQ queries to work with data and how Visual Studio 2008 supports LINQ.&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;May 28th: &lt;/span&gt;&lt;a href="http://events.sftsrc.com/EventDescription.aspx?EventId=1053&amp;amp;AbstractId=674"&gt;Agile in a day&lt;/a&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt; While more and more companies are practicing “Agile” software development, there is still a great deal of misunderstanding and confusion that surrounds the term.  This one day lecture class will cover the basics of Agile development using Scrum, including&lt;br /&gt;
&lt;br /&gt;
* Product, release and sprint planning&lt;br /&gt;
* The product backlog&lt;br /&gt;
* The roles of the Scrum master and product owner&lt;br /&gt;
* The importance of demos&lt;br /&gt;
* What it means to be done with a task in Scrum&lt;br /&gt;
&lt;br /&gt;
The instructor has participated in numerous Agile projects in a wide variety of organizations, and will include a discussion on common pitfalls and barriers to Agile adoption as well.&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;May 29th: &lt;/span&gt;&lt;a href="http://events.sftsrc.com/EventDescription.aspx?EventId=1051&amp;amp;AbstractId=670"&gt;Hands-on Continuous Integration with Free Tools&lt;/a&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;&lt;span style=""&gt;This one day course will provide a hands on look at setting up a Continuous Integration process using freely available tools from beginning to end. Students will learn the theory and practice behind establishing a Continuous Integration process, including setting up a build script, running unit tests, setting up an automated build/test server, and capturing reporting information for the whole process.&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/147.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>DirectX 10 - Learning from scratch</title><link>http://blogs.sftsrc.com/stuart/archive/2009/04/08/145.aspx</link><pubDate>Thu, 09 Apr 2009 02:00:52 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2009/04/08/145.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/145.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/145.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2009/04/08/145.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/145.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">DirectX 10 - Learning from scratch</source><description>&lt;p&gt;It's been several years since I did any games programming.  I have always maintained an avid interest in 3d modelling and graphics programming and love the world of video games and video game development, however I have found it hard to set aside the time necessary to really dig into the field further.  I've been unwilling to consider becoming a professional games developer because the reality is that all but a select few earn the kind of money that is available in commercial software development.  As the head of household and provider for our family I can't justify cutting my salary in half (or more) to work insane hours in one of the most demanding corners of our industry.&lt;/p&gt;
&lt;p&gt;However, the draw of games development and more specifically of DirectX development has sucked me in once more.  I'm enamored by the idea of being able to create 3d models and render them inside a game engine.  It's not even about an interest in commercial exploitation or of using a game framework to create the next big hit, I'm just fascinated by the science and technology of 3dmodeling, rendering, shading, lighting, and voodoo. &lt;/p&gt;
&lt;p&gt;So, dear friends, I am going to do my best to document my journeys through the jungle of DirectX development.  Primarily my goals from this are to create a basic DirectX 10 application, capable of rendering .x models created in TrueSpace 7.6 and develop an understanding for how graphics devices and model rendering in DX10 works.  I understand the basic principles and a lot of the underlying math, but the technology of rendering has moved on so much since I was last involved (DirectX 6).  This project will hopefully provide a nice refresher on C++ as well as give me a deeper understanding on where 3d graphics technology stands today.  Who knows, perhaps this little venture will produce something I can share. :)&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/145.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>SQL Delta diff tool problem with datetime2</title><link>http://blogs.sftsrc.com/leob/archive/2009/03/31/143.aspx</link><pubDate>Tue, 31 Mar 2009 23:55:29 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/leob/archive/2009/03/31/143.aspx</guid><wfw:comment>http://blogs.sftsrc.com/leob/comments/143.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/leob/comments/commentRss/143.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/leob/archive/2009/03/31/143.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/leob/services/trackbacks/143.aspx</trackback:ping><source url="http://blogs.sftsrc.com/leob/rss.aspx">SQL Delta diff tool problem with datetime2</source><description>&lt;p&gt;I am a big fan of SQL Delta (&lt;a href="http://www.sqldelta.com/"&gt;http://www.sqldelta.com/&lt;/a&gt;) and in the time I have been using the trial version have found it to be very useful and far better than the Schema Compare tool in Visual Studio.  I ran across one annoying (but easy to fix) problem: it does not know about the datetime2 data type in SQL Server 2008 and it punts when it encounters that type in your database objects.
&lt;/p&gt;
&lt;p&gt;
The fix is pretty simple: when scripting tables that have columns of type datetime2, manually enter the type in the nice, empty space SQL Delta places there where the type ought to be.
&lt;/p&gt;
&lt;p&gt;
My trial has since run out so I never got the opportunity to see if there is a way to configure or add new types for it to recognize, but that would be a pretty cool feature, wouldn't it?
&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/leob/aggbug/143.aspx" width="1" height="1" /&gt;</description><dc:creator>Leo Bartnik</dc:creator></item><item><title>SQL Server scripting woes</title><link>http://blogs.sftsrc.com/leob/archive/2009/03/31/142.aspx</link><pubDate>Tue, 31 Mar 2009 22:26:01 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/leob/archive/2009/03/31/142.aspx</guid><wfw:comment>http://blogs.sftsrc.com/leob/comments/142.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/leob/comments/commentRss/142.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/leob/archive/2009/03/31/142.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/leob/services/trackbacks/142.aspx</trackback:ping><source url="http://blogs.sftsrc.com/leob/rss.aspx">SQL Server scripting woes</source><description>&lt;p&gt;
For the past few days a co-worker Geoff and I have been working on setting up database object creation scripts in a SQL Express 2008 environment, and we ran into two issues where the script generation tools built into SQL Server Management Studio have some unexpected behaviors that were tripping up the process.  In one case there was a silent failure to perform a particular scripting task and in the other there was a loud failure that seemingly was unrelated to the configuration of the scripts we were attempting to generate.  In both cases we were able to solve the issues and move forward, but not without some head scratching and trial-and-error problem solving effort.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Scenario 1:&lt;/strong&gt;  The script wizard indicates it successfully scripted all objects in the database but actually does not script one or more of the table objects.  The constraints, etc. are scripted, and the wizard reports that it successfully scripted the object in question, but when you examine the T-SQL output, the CREATE of the table is not there.  And of course when you run the script it fails at the point where it attempts to apply constraints to tables that do not exist.
&lt;/p&gt;
&lt;p&gt;
The problem is that the object name and references to it throughout the various scripts and relationships were not always in the same case.  Even if your SQL Server instance is not configured to be case sensitive, the scripting engine apparently is configured that way, at least when it is trying to figure out dependent objects of associative tables.  The solution that Geoff came up with was to find and replace all instances of the table name so that they were in the same case, run the script at that point to get the objects updated, then re-run the whole thing from the start to capture all the changes correctly in the final script that gets checked into source control.  Hats off to Geoff and his hunch on this one; he was right on the money.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Scenario 2:&lt;/strong&gt; The script generator throws a "full-text index" scripting not supported error, even though you have set that setting to *not* script full-text indexes.  This arises when you choose which database objects to script by checking their boxes in a list of all the items in the database.  Interestingly, the error is not thrown when you indicate at the beginning of the scripting process that you want the tool to generate scripts for all the objects in the database and you don't choose them individually.  It also does not occur if you go the route of scripting the table directly from the object browser, which made it all the more elusive to track down.
&lt;/p&gt;
&lt;p&gt;
My hunch is that either there are two different scripting processes at work in this scenario, or there is some kind of additional licensing-related check that happens when you take a certain path that is not present in the other methods.  The generator acted as if a setting of false on the full-text index option meant that we wanted it scripted and did not consider that it should just be skipped altogether (that's just a hunch, I didn't confirm it).
&lt;/p&gt;
&lt;p&gt;
What all this tells me is nothing I didn't already know:  working with SQL Server means delving into a sometimes arcane, often darkly lit environment where it seems like the only way to get through successfully is to keep experimenting and following hunches.  Even when you have what you think is a pretty clear error message it often turns out to be the case that other peoples' solutions are not for the same problem you are having (even though the message is the same).  Once you have a few of these experiences, though, they come in handy down the road and you won't forget them the next time you run across the same situation.
&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/leob/aggbug/142.aspx" width="1" height="1" /&gt;</description><dc:creator>Leo Bartnik</dc:creator></item><item><title>Twitted my last tweet?</title><link>http://blogs.sftsrc.com/stuart/archive/2009/03/31/141.aspx</link><pubDate>Tue, 31 Mar 2009 21:23:42 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2009/03/31/141.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/141.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/141.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2009/03/31/141.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/141.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Twitted my last tweet?</source><description>&lt;p style="text-align: justify;"&gt;I had a realization this afternoon that I may have twitted my last tweet on &lt;a href="http://www.twitter.com/" mce_href="http://www.twitter.com" target="_blank"&gt;twitter&lt;/a&gt; (say &lt;em&gt;that&lt;/em&gt; six times fast!)  The social networking phenomenon that I've contributed to over the last year has become less and less interesting to me as time has passed.  I can see where the service delivers incredible value for some people, I'm just not certain I'm that audience.  In fact, I found myself having to actively become that audience in order for the service to make sense in my life.  That's altogether the wrong way round.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;I still like the idea of updating my status for friends to see, but &lt;a href="http://www.facebook.com/" mce_href="http://www.facebook.com" target="_blank"&gt;FaceBook&lt;/a&gt; fills that niche much more succesfully than twitter for me, not only in terms of the people in my life who use facebook versus twitter, but also because the people I know who use facebook post updates that are of more interest to me.  I've found that my tweeps (friends on twitter) tend to post more from a marketing and "personal online brand" perspective.  On twitter my friends network, promote brands and initiatives, and support each other's promotions in an effort to further the common good, and for that crowd those are wonderful things.  My friends on facebook tend to update more of what is happening in their personal lives and how they are feeling on a day to day basis.  For me, those are simply the posts that I find more interesting and that add more value to my life in terms of what I'm looking to achieve from social networking.&lt;br /&gt;
&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/141.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>Auto-Generate Friendly Urls</title><link>http://blogs.sftsrc.com/stuart/archive/2009/03/05/136.aspx</link><pubDate>Thu, 05 Mar 2009 19:40:46 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2009/03/05/136.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/136.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/136.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2009/03/05/136.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/136.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Auto-Generate Friendly Urls</source><description>I'd forgotten to check the Auto-Generate Friends Urls for this blog when setting it up.  The posts will now be named using a friendly version of the post title instead of a sequential number.&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/136.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>Dynamic OrderBy in LINQ</title><link>http://blogs.sftsrc.com/stuart/archive/2009/02/19/130.aspx</link><pubDate>Thu, 19 Feb 2009 21:01:18 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2009/02/19/130.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/130.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/130.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2009/02/19/130.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/130.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Dynamic OrderBy in LINQ</source><description>&lt;p&gt; Have you ever found yourself writing this code?&lt;br /&gt;
&lt;/p&gt;
&lt;div style="border: 1px solid rgb(68, 68, 68); padding: 3px; background-color: rgb(255, 255, 221); font-family: Courier New; text-align: left;"&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;switch&lt;/span&gt; (columnName)&lt;br /&gt;
{&lt;br /&gt;
    &lt;span style="color: rgb(0, 0, 255);"&gt;case &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"Name"&lt;/span&gt;:&lt;br /&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;return &lt;/span&gt;objList.OrderBy(o =&amp;gt; o.Name);&lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: rgb(0, 0, 255);"&gt;case &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"Address"&lt;/span&gt;:&lt;br /&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;return &lt;/span&gt;objList.OrderBy(o =&amp;gt; o.Address);&lt;br /&gt;
&lt;br /&gt;
    ... etc ...&lt;br /&gt;
} &lt;/div&gt;
&lt;p&gt; If so then you have probably wished you could do this:&lt;br /&gt;
&lt;/p&gt;
&lt;div style="border: 1px solid rgb(68, 68, 68); padding: 3px; background-color: rgb(255, 255, 221); font-family: Courier New; text-align: left;"&gt;     &lt;span style="color: rgb(0, 0, 255);"&gt;return &lt;/span&gt;objList.OrderBy(columnName); &lt;/div&gt;
&lt;p&gt; However, that's not going to work because the LINQ method is looking for an expression tree rather than a column name.  There are a few libraries out there such as the &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx"&gt;Dynamic LINQ Library&lt;/a&gt;, but if that feels a little heavyweight for you then the following solution may help.&lt;br /&gt;
&lt;br /&gt;
This class is a generic sorter for collections of type T.  There are two basic usage scenarios that are covered by its two sort methods.  The first scenario is as above where you want to specify a column upon an object in a collection.&lt;br /&gt;
You would call the class using:&lt;br /&gt;
&lt;/p&gt;
&lt;div style="border: 1px solid rgb(68, 68, 68); padding: 3px; background-color: rgb(255, 255, 221); font-family: Courier New; text-align: left;"&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;var &lt;/span&gt;prm = Expression.Parameter(&lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(0, 128, 128);"&gt;MyObject&lt;/span&gt;), &lt;span style="color: rgb(128, 0, 0);"&gt;"root"&lt;/span&gt;);&lt;br /&gt;
&lt;span style="color: rgb(0, 0, 255);"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyObject&lt;/span&gt;&amp;gt; sortedList = &lt;span style="color: rgb(0, 0, 255);"&gt;new &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;Sorter&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyObject&lt;/span&gt;&amp;gt;().Sort(list, prm, &lt;span style="color: rgb(128, 0, 0);"&gt;"Name"&lt;/span&gt;, SortDirection.Ascending); &lt;/div&gt;
&lt;br /&gt;
However, what if your object hierarchy was a little deeper than that.  Consider the following:&lt;br /&gt;
&lt;div style="border: 1px solid rgb(68, 68, 68); padding: 3px; background-color: rgb(255, 255, 221); font-family: Courier New; text-align: left;"&gt;     &lt;span style="color: rgb(0, 0, 255);"&gt;return &lt;/span&gt;objList.OrderBy(o =&amp;gt; o.Details.Name); &lt;/div&gt;
&lt;br /&gt;
The column is actually a property of an embedded object.  This is the scenario that the second method handles.  Because the actual sort column is an embedded object, we need to build an expression manually that describes the "path" to that property.  The code is very similar to that of the first example, except in this case we are providing a MemberExpression instead of the string sortExpression.&lt;br /&gt;
&lt;div style="border: 1px solid rgb(68, 68, 68); padding: 3px; background-color: rgb(255, 255, 221); font-family: Courier New; text-align: left;"&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;var &lt;/span&gt;prm = Expression.Parameter(&lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(0, 128, 128);"&gt;MyObject&lt;/span&gt;),&lt;span style="color: rgb(128, 0, 0);"&gt; "root"&lt;/span&gt;);&lt;br /&gt;
&lt;span style="color: rgb(0, 128, 128);"&gt;MemberExpression &lt;/span&gt;keySelectExpr =&lt;br /&gt;
    &lt;span style="color: rgb(0, 128, 128);"&gt;Expression&lt;/span&gt;.Property(&lt;span style="color: rgb(0, 128, 128);"&gt;Expression&lt;/span&gt;.Property(prm, &lt;span style="color: rgb(128, 0, 0);"&gt;"Details"&lt;/span&gt;), &lt;span style="color: rgb(128, 0, 0);"&gt;"Name"&lt;/span&gt;);&lt;br /&gt;
&lt;span style="color: rgb(0, 0, 255);"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyObject&lt;/span&gt;&amp;gt; sortedList = &lt;span style="color: rgb(0, 0, 255);"&gt;new &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;Sorter&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyObject&lt;/span&gt;&amp;gt;().Sort(list, prm, keySelectExpr, &lt;span style="color: rgb(0, 128, 128);"&gt;SortDirection&lt;/span&gt;.Ascending); &lt;/div&gt;
&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt; &lt;font size="4"&gt;&lt;strong&gt;Source Code&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;
The following is the code for the generic sorter class:&lt;br /&gt;
&lt;/p&gt;
&lt;div style="border: 1px solid rgb(68, 68, 68); padding: 3px; background-color: rgb(255, 255, 221); font-family: Courier New; text-align: left;"&gt; &lt;span style="color: rgb(0, 102, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt; /// A generic sorter class used to wrap the LINQ OrderBy functions.&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt; /// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt; /// &amp;lt;typeparam name="T"&amp;gt;The &amp;lt;see cref="System.Type"/&amp;gt; of object being sorted.&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: rgb(0, 0, 255);"&gt;public class &lt;/span&gt;Sorter&amp;lt;T&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &lt;span style="color: rgb(0, 102, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// Sorts a list of type T.&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;param name="list"&amp;gt;The list to sort.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;param name="prmExpression"&amp;gt;The expression defining the parameter to supply to the lambda expression.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;param name="sortExpression"&amp;gt;The name of the property on the parameter object to sort by.&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;param name="sortDirection"&amp;gt;The direction in which to sort the objects.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;returns&amp;gt;The sorted list.&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;br /&gt;
    &lt;span style="color: rgb(0, 0, 255);"&gt;public &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;List&lt;/span&gt;&amp;lt;T&amp;gt; Sort(&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;IEnumerable&lt;/span&gt;&amp;lt;T&amp;gt; list,&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;ParameterExpression &lt;/span&gt;prmExpression,&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;string &lt;/span&gt;sortExpression,&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;SortDirection &lt;/span&gt;sortDirection) {&lt;br /&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;var &lt;/span&gt;lambda = &lt;span style="color: rgb(0, 128, 128);"&gt;Expression&lt;/span&gt;.Lambda&amp;lt;&lt;span style="color: rgb(0, 128, 128);"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;(&lt;span style="color: rgb(0, 128, 128);"&gt;Expression&lt;/span&gt;.Convert(&lt;span style="color: rgb(0, 128, 128);"&gt;Expression&lt;/span&gt;.Property(prmExpression, sortExpression), &lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;)), prmExpression);&lt;br /&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;return &lt;/span&gt;sortDirection == &lt;span style="color: rgb(0, 128, 128);"&gt;SortDirection&lt;/span&gt;.Ascending ?&lt;br /&gt;
            list.AsQueryable&amp;lt;T&amp;gt;().OrderBy&amp;lt;T, &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;&amp;gt;(lambda).ToList() :&lt;br /&gt;
            list.AsQueryable&amp;lt;T&amp;gt;().OrderByDescending&amp;lt;T, &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;&amp;gt;(lambda).ToList();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: rgb(0, 102, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// Sorts a list of type T.&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;param name="list"&amp;gt;The list to sort.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;param name="prmExpression"&amp;gt;The expression defining the parameter to supply to the lambda expression.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;param name="keySelectionExpression"&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// A &amp;lt;see cref="MemberExpression"/&amp;gt; that identifies a property on an object in the supplied &amp;lt;param name="list"/&amp;gt; that is used to&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// perform the sort.&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;param name="sortDirection"&amp;gt;The direction in which to sort the objects.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;returns&amp;gt;The sorted list.&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;br /&gt;
    &lt;span style="color: rgb(0, 0, 255);"&gt;public &lt;/span&gt;List&amp;lt;T&amp;gt; Sort(&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;IEnumerable&lt;/span&gt;&amp;lt;T&amp;gt; list,&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;ParameterExpression &lt;/span&gt;prmExpression,&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;MemberExpression &lt;/span&gt;sortExpression,&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;SortDirection &lt;/span&gt;sortDirection) {&lt;br /&gt;
&lt;div style="text-align: left;"&gt;         &lt;span style="color: rgb(0, 0, 255);"&gt;var &lt;/span&gt;lambda = &lt;span style="color: rgb(0, 128, 128);"&gt;Expression&lt;/span&gt;.Lambda&amp;lt;&lt;span style="color: rgb(0, 128, 128);"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;(&lt;span style="color: rgb(0, 128, 128);"&gt;Expression&lt;/span&gt;.Convert(sortExpression, &lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;)), prmExpression);&lt;br /&gt;
&lt;/div&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;return &lt;/span&gt;sortDirection == &lt;span style="color: rgb(0, 128, 128);"&gt;SortDirection&lt;/span&gt;.Ascending ?&lt;br /&gt;
            list.AsQueryable&amp;lt;T&amp;gt;().OrderBy&amp;lt;T, &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;&amp;gt;(lambda).ToList() :&lt;br /&gt;
            list.AsQueryable&amp;lt;T&amp;gt;().OrderByDescending&amp;lt;T, &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;&amp;gt;(lambda).ToList();&lt;br /&gt;
    }&lt;br /&gt;
} &lt;/div&gt;
&lt;p&gt; &lt;font size="4"&gt;&lt;strong&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="4"&gt;&lt;strong&gt;What is the Expression.Convert() part for?&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;
You may have noticed the code does a conversion on the sort expression that we provide:&lt;br /&gt;
&lt;/p&gt;
&lt;div style="border: 1px solid rgb(68, 68, 68); padding: 3px; background-color: rgb(255, 255, 221); font-family: Courier New; text-align: left;"&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;Expression&lt;/span&gt;.Convert(sortExpression, typeof(&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;)) &lt;/div&gt;
&lt;br /&gt;
You may wonder why this is necessary as you are providing a &lt;font face="Courier New"&gt;string&lt;/font&gt; for the &lt;font face="Courier New"&gt;sortExpression&lt;/font&gt; parameter.  However, it is important to remember that this isn't the type that is being specified in the expression tree, it is the type of the property on the object that is being sorted.&lt;br /&gt;
&lt;br /&gt;
If you are sorting by MyObject.Name (where Name is a string property) then the type is string.  However, if you are sorting by MyObject.Date (where Date is a DateTime) then this type needs to be a Date, not a string.  That is why we do Expression.Convert(sortExpression, typeof(object)).  We downcast to object to avoid a type mismatch problem in the evaluated expression tree.&lt;br /&gt;
&lt;p&gt;&lt;font size="4"&gt;&lt;strong&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="4"&gt;&lt;strong&gt;Sample Listing&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;
The following is a sample listing for a console application.  Just remember to add a reference to System.Web as I use the SortDirection class from System.Web.UI.WebControls.  Just use a different type if you end up using this outside of a web application.&lt;br /&gt;
&lt;/p&gt;
&lt;div style="border: 1px solid rgb(68, 68, 68); padding: 3px; background-color: rgb(255, 255, 221); font-family: Courier New; text-align: left;"&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;using &lt;/span&gt;System;&lt;br /&gt;
&lt;span style="color: rgb(0, 0, 255);"&gt;using &lt;/span&gt;System.Collections.Generic;&lt;br /&gt;
&lt;span style="color: rgb(0, 0, 255);"&gt;using &lt;/span&gt;System.Linq;&lt;br /&gt;
&lt;span style="color: rgb(0, 0, 255);"&gt;using &lt;/span&gt;System.Text;&lt;br /&gt;
&lt;span style="color: rgb(0, 0, 255);"&gt;using &lt;/span&gt;System.Linq.Expressions;&lt;br /&gt;
&lt;span style="color: rgb(0, 0, 255);"&gt;using &lt;/span&gt;System.Web.UI.WebControls;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: rgb(0, 0, 255);"&gt;namespace &lt;/span&gt;DynamicOrderBy&lt;br /&gt;
{&lt;br /&gt;
&lt;span style="color: rgb(0, 0, 255);"&gt;class &lt;/span&gt;Program&lt;br /&gt;
{&lt;br /&gt;
    &lt;span style="color: rgb(0, 0, 255);"&gt;static void &lt;/span&gt;Main(&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;
    {&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyObject&lt;/span&gt;&amp;gt; list = &lt;span style="color: rgb(0, 0, 255);"&gt;new &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyObject&lt;/span&gt;&amp;gt;();&lt;br /&gt;
        list.Add(new MyObject { Name =&lt;span style="color: rgb(128, 0, 0);"&gt; "Name3"&lt;/span&gt;, Address = &lt;span style="color: rgb(128, 0, 0);"&gt;"Address3"&lt;/span&gt; });&lt;br /&gt;
        list.Add(new MyObject { Name =&lt;span style="color: rgb(128, 0, 0);"&gt; "Name1"&lt;/span&gt;, Address = &lt;span style="color: rgb(128, 0, 0);"&gt;"Address1"&lt;/span&gt; });&lt;br /&gt;
        list.Add(new MyObject { Name =&lt;span style="color: rgb(128, 0, 0);"&gt; "Name2"&lt;/span&gt;, Address =&lt;span style="color: rgb(128, 0, 0);"&gt; "Address2"&lt;/span&gt; });&lt;br /&gt;
&lt;br /&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;var &lt;/span&gt;prm = &lt;span style="color: rgb(0, 128, 128);"&gt;Expression&lt;/span&gt;.Parameter(&lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(0, 128, 128);"&gt;MyObject&lt;/span&gt;), "root");&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyObject&lt;/span&gt;&amp;gt; sortedList = new Sorter&amp;lt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyObject&lt;/span&gt;&amp;gt;().Sort(list, prm, "Name", SortDirection.Ascending);&lt;br /&gt;
&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;Console&lt;/span&gt;.WriteLine("Sorting simple list:");&lt;br /&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;foreach &lt;/span&gt;(&lt;span style="color: rgb(0, 128, 128);"&gt;MyObject &lt;/span&gt;obj &lt;span style="color: rgb(0, 0, 255);"&gt;in &lt;/span&gt;sortedList)&lt;br /&gt;
            &lt;span style="color: rgb(0, 128, 128);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(0, 128, 128);"&gt;String&lt;/span&gt;.Format(&lt;span style="color: rgb(128, 0, 0);"&gt;"{0} : {1}"&lt;/span&gt;, obj.Name, obj.Address));&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(0, 128, 128);"&gt;String&lt;/span&gt;.Empty);&lt;br /&gt;
&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyComplexObject&lt;/span&gt;&amp;gt; complexList =&lt;br /&gt;
            &lt;span style="color: rgb(0, 0, 255);"&gt;new &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyComplexObject&lt;/span&gt;&amp;gt;();&lt;br /&gt;
        complexList.Add(&lt;span style="color: rgb(0, 0, 255);"&gt;new &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyComplexObject &lt;/span&gt;{ Detail = &lt;span style="color: rgb(0, 0, 255);"&gt;new &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyObject &lt;/span&gt;{ Name = &lt;span style="color: rgb(128, 0, 0);"&gt;"Name3"&lt;/span&gt;, Address = &lt;span style="color: rgb(128, 0, 0);"&gt;"Address3" &lt;/span&gt;} });&lt;br /&gt;
        complexList.Add(&lt;span style="color: rgb(0, 0, 255);"&gt;new &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyComplexObject &lt;/span&gt;{ Detail = &lt;span style="color: rgb(0, 0, 255);"&gt;new &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyObject &lt;/span&gt;{ Name = &lt;span style="color: rgb(128, 0, 0);"&gt;"Name1"&lt;/span&gt;, Address = &lt;span style="color: rgb(128, 0, 0);"&gt;"Address1"&lt;/span&gt; } });&lt;br /&gt;
        complexList.Add(&lt;span style="color: rgb(0, 0, 255);"&gt;new &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyComplexObject &lt;/span&gt;{ Detail = &lt;span style="color: rgb(0, 0, 255);"&gt;new &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyObject &lt;/span&gt;{ Name = &lt;span style="color: rgb(128, 0, 0);"&gt;"Name2"&lt;/span&gt;, Address = &lt;span style="color: rgb(128, 0, 0);"&gt;"Address2"&lt;/span&gt; } });&lt;br /&gt;
&lt;br /&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;var &lt;/span&gt;prmComplex = &lt;span style="color: rgb(0, 128, 128);"&gt;Expression&lt;/span&gt;.Parameter(&lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(0, 128, 128);"&gt;MyComplexObject&lt;/span&gt;), &lt;span style="color: rgb(128, 0, 0);"&gt;"root"&lt;/span&gt;);&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;MemberExpression &lt;/span&gt;keySelectExpr =&lt;br /&gt;
            &lt;span style="color: rgb(0, 128, 128);"&gt;Expression&lt;/span&gt;.Property(&lt;span style="color: rgb(0, 128, 128);"&gt;Expression&lt;/span&gt;.Property(prmComplex, &lt;span style="color: rgb(128, 0, 0);"&gt;"Detail"&lt;/span&gt;), &lt;span style="color: rgb(128, 0, 0);"&gt;"Name"&lt;/span&gt;);&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyComplexObject&lt;/span&gt;&amp;gt; sortedComplexList = &lt;span style="color: rgb(0, 0, 255);"&gt;new &lt;/span&gt;Sorter&amp;lt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyComplexObject&lt;/span&gt;&amp;gt;().Sort(complexList, prmComplex, keySelectExpr, SortDirection.Ascending);&lt;br /&gt;
&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(128, 0, 0);"&gt;"Sorting complex list:"&lt;/span&gt;);&lt;br /&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;foreach &lt;/span&gt;(&lt;span style="color: rgb(0, 128, 128);"&gt;MyComplexObject &lt;/span&gt;obj &lt;span style="color: rgb(0, 0, 255);"&gt;in &lt;/span&gt;sortedComplexList)&lt;br /&gt;
            &lt;span style="color: rgb(0, 128, 128);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(0, 128, 128);"&gt;String&lt;/span&gt;.Format(&lt;span style="color: rgb(128, 0, 0);"&gt;"{0} : {1}"&lt;/span&gt;, obj.Detail.Name, obj.Detail.Address));&lt;br /&gt;
&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(0, 128, 128);"&gt;String&lt;/span&gt;.Empty);&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(128, 0, 0);"&gt;"Press any key to exit..."&lt;/span&gt;);&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;Console&lt;/span&gt;.ReadLine();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: rgb(0, 0, 255);"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyObject&lt;/span&gt;&lt;br /&gt;
{&lt;br /&gt;
    &lt;span style="color: rgb(0, 0, 255);"&gt;public string &lt;/span&gt;Name { &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;; &lt;span style="color: rgb(0, 0, 255);"&gt;set&lt;/span&gt;; }&lt;br /&gt;
    &lt;span style="color: rgb(0, 0, 255);"&gt;public string &lt;/span&gt;Address { &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;; &lt;span style="color: rgb(0, 0, 255);"&gt;set&lt;/span&gt;; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: rgb(0, 0, 255);"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyComplexObject&lt;/span&gt;&lt;br /&gt;
{&lt;br /&gt;
    &lt;span style="color: rgb(0, 0, 255);"&gt;public &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;MyObject &lt;/span&gt;Detail { &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;; &lt;span style="color: rgb(0, 0, 255);"&gt;set&lt;/span&gt;; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt; /// A generic sorter class used to wrap the LINQ OrderBy functions.&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt; /// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt; /// &amp;lt;typeparam name="T"&amp;gt;The &amp;lt;see cref="System.Type"/&amp;gt; of object being sorted.&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: rgb(0, 0, 255);"&gt;public class &lt;/span&gt;Sorter&amp;lt;T&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &lt;span style="color: rgb(0, 102, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// Sorts a list of type T.&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;param name="list"&amp;gt;The list to sort.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;param name="prmExpression"&amp;gt;The expression defining the parameter to supply to the lambda expression.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;param name="sortExpression"&amp;gt;The name of the property on the parameter object to sort by.&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;param name="sortDirection"&amp;gt;The direction in which to sort the objects.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;returns&amp;gt;The sorted list.&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;br /&gt;
    &lt;span style="color: rgb(0, 0, 255);"&gt;public &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;List&lt;/span&gt;&amp;lt;T&amp;gt; Sort(&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;IEnumerable&lt;/span&gt;&amp;lt;T&amp;gt; list,&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;ParameterExpression &lt;/span&gt;prmExpression,&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;string &lt;/span&gt;sortExpression,&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;SortDirection &lt;/span&gt;sortDirection) {&lt;br /&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;var &lt;/span&gt;lambda = &lt;span style="color: rgb(0, 128, 128);"&gt;Expression&lt;/span&gt;.Lambda&amp;lt;&lt;span style="color: rgb(0, 128, 128);"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;(&lt;span style="color: rgb(0, 128, 128);"&gt;Expression&lt;/span&gt;.Convert(&lt;span style="color: rgb(0, 128, 128);"&gt;Expression&lt;/span&gt;.Property(prmExpression, sortExpression), &lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;)), prmExpression);&lt;br /&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;return &lt;/span&gt;sortDirection == &lt;span style="color: rgb(0, 128, 128);"&gt;SortDirection&lt;/span&gt;.Ascending ?&lt;br /&gt;
            list.AsQueryable&amp;lt;T&amp;gt;().OrderBy&amp;lt;T, &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;&amp;gt;(lambda).ToList() :&lt;br /&gt;
            list.AsQueryable&amp;lt;T&amp;gt;().OrderByDescending&amp;lt;T, &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;&amp;gt;(lambda).ToList();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    &lt;span style="color: rgb(0, 102, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// Sorts a list of type T.&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;param name="list"&amp;gt;The list to sort.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;param name="prmExpression"&amp;gt;The expression defining the parameter to supply to the lambda expression.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;param name="keySelectionExpression"&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// A &amp;lt;see cref="MemberExpression"/&amp;gt; that identifies a property on an object in the supplied &amp;lt;param name="list"/&amp;gt; that is used to&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// perform the sort.&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;param name="sortDirection"&amp;gt;The direction in which to sort the objects.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(0, 102, 0);" /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;     /// &amp;lt;returns&amp;gt;The sorted list.&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;br /&gt;
    &lt;span style="color: rgb(0, 0, 255);"&gt;public &lt;/span&gt;List&amp;lt;T&amp;gt; Sort(&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;IEnumerable&lt;/span&gt;&amp;lt;T&amp;gt; list,&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;ParameterExpression &lt;/span&gt;prmExpression,&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;MemberExpression &lt;/span&gt;sortExpression,&lt;br /&gt;
        &lt;span style="color: rgb(0, 128, 128);"&gt;SortDirection &lt;/span&gt;sortDirection) {&lt;br /&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;var &lt;/span&gt;lambda = &lt;span style="color: rgb(0, 128, 128);"&gt;Expression&lt;/span&gt;.Lambda&amp;lt;&lt;span style="color: rgb(0, 128, 128);"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;(&lt;span style="color: rgb(0, 128, 128);"&gt;Expression&lt;/span&gt;.Convert(sortExpression, &lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;)), prmExpression);&lt;br /&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;return &lt;/span&gt;sortDirection == &lt;span style="color: rgb(0, 128, 128);"&gt;SortDirection&lt;/span&gt;.Ascending ?&lt;br /&gt;
            list.AsQueryable&amp;lt;T&amp;gt;().OrderBy&amp;lt;T, &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;&amp;gt;(lambda).ToList() :&lt;br /&gt;
            list.AsQueryable&amp;lt;T&amp;gt;().OrderByDescending&amp;lt;T, &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;&amp;gt;(lambda).ToList();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
} &lt;/div&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/130.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>Silverlight Days</title><link>http://blogs.sftsrc.com/shaun/archive/2009/02/13/124.aspx</link><pubDate>Fri, 13 Feb 2009 13:21:33 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/shaun/archive/2009/02/13/124.aspx</guid><wfw:comment>http://blogs.sftsrc.com/shaun/comments/124.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/shaun/comments/commentRss/124.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/shaun/archive/2009/02/13/124.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/shaun/services/trackbacks/124.aspx</trackback:ping><source url="http://blogs.sftsrc.com/shaun/rss.aspx">Silverlight Days</source><description>&lt;p&gt;Patrick Cauldwell and I have just completed presenting two one day deep-dive sessions on what we felt are practical Silverlight topics. After thinking about it, I have decided that over the next few days I will share some of my demos with my editorializing.&lt;/p&gt;
&lt;p&gt;In my first presentation, I covered Styling, Skinning and Custom Controls, and in my second presentation I covered Silverlight/browser integration. &lt;/p&gt;
&lt;p&gt;The first topic I will be addressing will be "How to use Silverlight as a replacement for Javascript libraries". &lt;/p&gt;
&lt;p&gt;As I complete each topic, I will add them to the following table of contents:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://blogs.sftsrc.com/shaun/archive/2009/02/17/127.aspx"&gt;Silverlight as a Javascript Library Replacement&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I would also invite you to contact me at &lt;a href="mailto:shaun@sftsrc.com"&gt;shaun@sftsrc.com&lt;/a&gt; if you have specific Silverlight (or other) topics that you would like me to consider addressing.&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/shaun/aggbug/124.aspx" width="1" height="1" /&gt;</description><dc:creator>Shaun McAravey</dc:creator></item><item><title>Practical Silverlight: More than just Flash</title><link>http://blogs.sftsrc.com/stuart/archive/2009/01/23/122.aspx</link><pubDate>Fri, 23 Jan 2009 16:55:51 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2009/01/23/122.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/122.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/122.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2009/01/23/122.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/122.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Practical Silverlight: More than just Flash</source><description>&lt;p style="text-align: justify;"&gt;Register &lt;a href="https://registration.sftsrc.com/"&gt;here&lt;/a&gt; to learn how to use Silverlight to build next-generation applications in half the time it would take with traditional web development technologies.  SoftSource provides you with a competitive advantage in application development, delivering the highest quality of software on time and within your budget.  Now learn the secrets from our trainers about how to leverage this cutting edge technology to deliver the same results yourself.&lt;br /&gt;
&lt;/p&gt;
&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;
&lt;p style="text-align: justify; font-style: italic;"&gt;"Until now, the standard for user experience for browser-hosted applications has been defined by AJAX and JavaScript. However, the powerful and rich user experience provided by these applications has come at a significant cost in development. Silverlight allows us to deliver an even more compelling user experience while simultaneously simplifying the programming model and leveraging our existing .NET skills. During this session we will cover the foundational concepts and technologies you will need to know to jumpstart your transition to Silverlight development. Several highlights include: &lt;/p&gt;
&lt;div style="text-align: justify; font-style: italic;"&gt; &lt;/div&gt;
&lt;ul style="font-style: italic;"&gt;
    &lt;li style="text-align: justify;"&gt;Silverlight Architecture&lt;/li&gt;
    &lt;li style="text-align: justify;"&gt;Dependency and Attached properties&lt;/li&gt;
    &lt;li style="text-align: justify;"&gt;XAML resources&lt;/li&gt;
    &lt;li style="text-align: justify;"&gt;How to access your code in XAML."&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="text-align: left;"&gt; Registration for the &lt;span style="font-weight: bold;"&gt;Portland &lt;/span&gt;event can be found &lt;a href="https://registration.sftsrc.com/Register.aspx?EventId=1"&gt;here&lt;/a&gt;: &lt;a href="https://registration.sftsrc.com/Register.aspx?EventId=1"&gt;https://registration.sftsrc.com/Register.aspx?EventId=1&lt;/a&gt;&lt;br /&gt;
There is also a &lt;span style="font-weight: bold;"&gt;Bellevue &lt;/span&gt;event you can attend &lt;a href="https://registration.sftsrc.com/Register.aspx?EventId=382"&gt;here&lt;/a&gt;: &lt;a href="https://registration.sftsrc.com/Register.aspx?EventId=382"&gt;https://registration.sftsrc.com/Register.aspx?EventId=382&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Spots are limited, so sign up early to ensure that you get yours.&lt;/div&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/122.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>Walking in other shoes</title><link>http://blogs.sftsrc.com/stuart/archive/2009/01/21/121.aspx</link><pubDate>Wed, 21 Jan 2009 17:37:10 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2009/01/21/121.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/121.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/121.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2009/01/21/121.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/121.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Walking in other shoes</source><description>Your l33t sk1llz are so bad ass that if given an open canvas you could write software to solve all the world's problems and still be home in time for tea.  Unfortunately for you, a thousand and one project managers feel the need to get in the way and provide direction, appoint technical leads with no clue what they are doing, and generally hamper your ability to kick ass at every turn.&lt;br /&gt;
&lt;br /&gt;
However, the thought of you stepping into those shoes and "showing them how it is done" has you saying "No way man!"  This article is a great review of why their shoes might provide a very informative journey that will help you apply your mad skills more effectively than ever before: &lt;br /&gt;
&lt;a href="http://www.thousandtyone.com/blog/WhyKickAssDevelopersShouldBecomeManagersIfYouDontRunYourProjectsTheyWill.aspx"&gt;Why Kick Ass Developers Should Become Managers - If You Dont Run Your Projects They Will&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Thanks to &lt;a href="http://www.thousandtyone.com/blog/"&gt;Rajiv&lt;/a&gt; for putting this great article together.&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/121.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>Web 2.0</title><link>http://blogs.sftsrc.com/stuart/archive/2009/01/12/120.aspx</link><pubDate>Mon, 12 Jan 2009 16:53:46 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2009/01/12/120.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/120.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/120.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2009/01/12/120.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/120.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Web 2.0</source><description>I think this is the best description I've come across for Web 2.0.  I found this in the monthly &lt;a href="javascript:void(0);/*1231779215962*/"&gt;dreamhosts.com&lt;/a&gt; newsletter:&lt;br /&gt;
&lt;br /&gt;
"Ajaxy-Javascript-Web 2.0-itude"&lt;br /&gt;
&lt;br /&gt;
Yeah baby...hail to the king!&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/120.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>Visual Studio 2010 CTP</title><link>http://blogs.sftsrc.com/stuart/archive/2009/01/07/119.aspx</link><pubDate>Wed, 07 Jan 2009 18:06:23 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2009/01/07/119.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/119.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/119.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2009/01/07/119.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/119.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Visual Studio 2010 CTP</source><description>Have you downloaded your copy yet?&lt;br /&gt;
&lt;a href="javascript:void(0);/*1231351568676*/"&gt;&lt;br /&gt;
http://www.microsoft.com/downloads/details.aspx?FamilyId=922B4655-93D0-4476-BDA4-94CF5F8D4814&amp;amp;displaylang=en#filelist&lt;/a&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/119.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>The Secret to Organizational Agility</title><link>http://blogs.sftsrc.com/stuart/archive/2008/12/08/118.aspx</link><pubDate>Mon, 08 Dec 2008 21:23:08 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2008/12/08/118.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/118.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/118.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2008/12/08/118.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/118.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">The Secret to Organizational Agility</source><description>Mike Cottmeyer wrote an excellent article about the importance of eliminating dependencies in agile projects:&lt;br /&gt;
&lt;a href="javascript:void(0);/*1228771232703*/"&gt;http://www.leadingagile.com/2008/12/secret-to-organizational-agility.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
How many times have the following been true:&lt;br /&gt;
&lt;ul style="font-style: italic;"&gt;
    &lt;li&gt;"Many teams are trying to sprint through product development using a traditional MRD or PRD."&lt;/li&gt;
    &lt;li&gt;"Many teams are working with traditional project managers who are doing their best to be agile, but have been trained to manage dependencies and tell people what to do."&lt;/li&gt;
    &lt;li&gt;"Teams are trying to be agile with tightly coupled software architectures, insufficient test coverage, legacy code bases, and unable to do a daily build."&lt;/li&gt;
&lt;/ul&gt;
Removing dependencies is a key step that can be taken towards a truly agile development environment.&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/118.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>Be careful with your online brand...</title><link>http://blogs.sftsrc.com/stuart/archive/2008/12/08/117.aspx</link><pubDate>Mon, 08 Dec 2008 19:17:40 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2008/12/08/117.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/117.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/117.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2008/12/08/117.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/117.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Be careful with your online brand...</source><description>As the popularity of Web 2.0 is growing, so is the ability for others to observe and evaluate your story and your personal online brand.  &lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;&lt;a href="javascript:void(0);/*1228762305907*/"&gt;This article from&lt;/a&gt; JASE marketing reports that a &lt;span style="font-style: italic;"&gt;"survey of 500 top colleges found that 10 percent of admissions officers said they look at  &lt;/span&gt;&lt;a target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.myspace.com/jaselabs');" href="http://www.myspace.com/" title="JASE Group MySpace" style="font-style: italic;"&gt;MySpace&lt;/a&gt;&lt;span style="font-style: italic;"&gt; and &lt;/span&gt;&lt;a target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.new.facebook.com/pages/Norfolk-VA/JASE-Group-LLC/36541607437');" href="http://www.facebook.com/" title="JASE Group Facebook" style="font-style: italic;"&gt;Facebook&lt;/a&gt;&lt;span style="font-style: italic;"&gt; to evaluate applicants."&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I've always lived by two golden rules with regards to blogging:&lt;br /&gt;
1) Blog only something you would wish to see printed and cited at any time in the future.&lt;br /&gt;
2) Do not edit or update a blog assuming that a printed/archived/cached copy of the original does not exist.&lt;br /&gt;
&lt;br /&gt;
It's a general faux pas to update a blog post for any reason.  The web is alive with caches and indexes so the chances are that the original is still out there for people to compare.  Spelling errors are generally ok, but if the content of an article is to be updated it is good form to list at &lt;span style="font-style: italic;"&gt;Updated: [description of update]&lt;/span&gt; at the top or bottom of the post.  If an opinion is being revised, be clear about why there is a change in stance.  Comments are a great way to revise an opinion after learning new information as it allows readers to see the thought processes and perhaps benefit from the same line of thinking that provoked your own turn around.&lt;br /&gt;
&lt;br /&gt;
Web 2.0 means we are all ultra-connected.  This can be great not only for staying in touch with friends but also for business networking and establishing a reputation and a brand in the online world.  However, remember that this "permanent record" can go both ways: and this one is for the world to see.&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/117.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>FireFox 3.x Unstable</title><link>http://blogs.sftsrc.com/stuart/archive/2008/12/02/116.aspx</link><pubDate>Tue, 02 Dec 2008 17:22:29 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2008/12/02/116.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/116.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/116.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2008/12/02/116.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/116.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">FireFox 3.x Unstable</source><description>&lt;div style="text-align: justify;"&gt;I'm not sure what changed.  FireFox used to be one of the most stable browsers I'd ever used.  However, since the upgrade to the 3.x track I've had nothing but problems.  The browser is still functionally great, but the stability has taken a nose-dive.  I've had crashes and lockups on both XP and Vista and despite getting the latest updates and fixes in both environments, the problems continue.  I'd switch to Chrome if it weren't for &lt;a href="javascript:void(0);/*1228238536050*/"&gt;concerns over security vulnerabilities&lt;/a&gt;.  It's a new browser that's still in beta so I'm not surprised there are a few kinks to iron out; but I'd rather not be the guinea pig that finds the problems.&lt;br /&gt;
&lt;br /&gt;
So for now, I guess it's back to IE.  *sigh*&lt;/div&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/116.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>Ruby on Rails Setup with DreamHost</title><link>http://blogs.sftsrc.com/stuart/archive/2008/10/28/109.aspx</link><pubDate>Tue, 28 Oct 2008 22:29:21 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2008/10/28/109.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/109.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/109.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2008/10/28/109.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/109.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Ruby on Rails Setup with DreamHost</source><description>&lt;p&gt;As step 1 of &lt;a target="_blank" mce_href="http://stuartthompsontech.wordpress.com/2008/10/27/the-aspnet-silverlight-php-rails-experiment/" href="http://stuartthompsontech.wordpress.com/2008/10/27/the-aspnet-silverlight-php-rails-experiment/"&gt;my latest experiment&lt;/a&gt;, I've started by configuring a &lt;a target="_blank" mce_href="http://www.rubyonrails.org" href="http://www.rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; site with &lt;a target="_blank" mce_href="http://www.dreamhost.com" href="http://www.dreamhost.com/"&gt;DreamHost&lt;/a&gt;.  This actually involved quite a bit of setup work, which is not unusual when remotely hosting a new website.  I have documented the steps as fully as I can for anyone else curious about trying development in Rails.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1 - Signup with DreamHost&lt;/strong&gt;&lt;br /&gt;
You can sign up &lt;a target="_blank" mce_href="http://www.dreamhost.com/r.cgi?461119" href="http://www.dreamhost.com/r.cgi?461119"&gt;using this link&lt;/a&gt; or use the promo code LETMETRYRAILS and receive $50 off (i.e. no setup fee).&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;&lt;strong&gt;Step 2 - Configure your domain&lt;/strong&gt;&lt;br /&gt;
The next step is to configure your domain.   We'll start at the &lt;a target="_blank" mce_href="http://panel.dreamhost.com" href="http://panel.dreamhost.com/"&gt;DreamHost configuration panel&lt;/a&gt;.  Select &lt;em&gt;Domains&lt;/em&gt; and then &lt;em&gt;Manage Domains&lt;/em&gt; from the left-hand sidebar.  This will bring up the list of domains in your account.  Click the &lt;em&gt;Edit &lt;/em&gt;button in the &lt;em&gt;Web Hosting&lt;/em&gt; column.&lt;/p&gt;
&lt;p&gt;&lt;a mce_href="http://stuartthompsontech.files.wordpress.com/2008/10/dreamhost_managedomains2.jpg" href="http://stuartthompsontech.files.wordpress.com/2008/10/dreamhost_managedomains2.jpg"&gt;&lt;img height="228" width="460" alt="" mce_src="http://stuartthompsontech.wordpress.com/files/2008/10/dreamhost_managedomains2.jpg" src="http://stuartthompsontech.wordpress.com/files/2008/10/dreamhost_managedomains2.jpg" title="dreamhost_managedomains2" class="alignnone size-full wp-image-62" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This will open the settings page for that domain.  Check the FastCGI and Passenger (mod_rails) checkboxes.  Finally click the &lt;em&gt;Change fully hosted settings now!&lt;/em&gt; button (note that this button is not at the bottom of the page, rather at the end of the first section).&lt;/p&gt;
&lt;p&gt;&lt;a mce_href="http://stuartthompsontech.files.wordpress.com/2008/10/dreamhost_configuredomain1.jpg" href="http://stuartthompsontech.files.wordpress.com/2008/10/dreamhost_configuredomain1.jpg"&gt;&lt;img height="366" width="460" alt="" mce_src="http://stuartthompsontech.wordpress.com/files/2008/10/dreamhost_configuredomain1.jpg" src="http://stuartthompsontech.wordpress.com/files/2008/10/dreamhost_configuredomain1.jpg" title="dreamhost_configuredomain1" class="alignnone size-full wp-image-63" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;FastCGI support allows your Rails project to run much faster.  The Passenger (mod_rails) option allows your Rails application to be configured much more easily and is the &lt;a target="_blank" mce_href="http://wiki.dreamhost.com/Passenger" href="http://wiki.dreamhost.com/Passenger"&gt;preferred DreamHost method&lt;/a&gt; for hosting Ruby on Rails applications.&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;&lt;strong&gt;Step 3 - Configure your FTP/SSH user&lt;/strong&gt;&lt;br /&gt;
We will be performing much of the setup and configuration of the website via SSH.  We will need to setup a user account for this purpose.  During your initial setup you should have created an ftp account for your domain, probably with the same name as that domain (if you accepted the defaults).  Select the &lt;em&gt;Users&lt;/em&gt; and then &lt;em&gt;Manage Users&lt;/em&gt; options from the left side-bar.  Click the &lt;em&gt;Edit&lt;/em&gt; button next to your user in the &lt;em&gt;Actions &lt;/em&gt;column.&lt;/p&gt;
&lt;p&gt;&lt;a mce_href="http://stuartthompsontech.files.wordpress.com/2008/10/dreamhost_editusers.jpg" href="http://stuartthompsontech.files.wordpress.com/2008/10/dreamhost_editusers.jpg"&gt;&lt;img height="216" width="460" alt="" mce_src="http://stuartthompsontech.wordpress.com/files/2008/10/dreamhost_editusers.jpg" src="http://stuartthompsontech.wordpress.com/files/2008/10/dreamhost_editusers.jpg" title="dreamhost_editusers" class="alignnone size-full wp-image-61" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;This will open the following page where you can edit your user.  Change the User &lt;em&gt;Account Type&lt;/em&gt; to &lt;em&gt;Shell account&lt;/em&gt; and select the &lt;em&gt;/bin/bash&lt;/em&gt; shell type.  Finally, hit the &lt;em&gt;Save Changes&lt;/em&gt; button at the bottom of the page.&lt;/p&gt;
&lt;p mce_style="text-align:left;" style="text-align: left;"&gt;&lt;a mce_href="http://stuartthompsontech.files.wordpress.com/2008/10/dreamhost_editingftpuser.jpg" href="http://stuartthompsontech.files.wordpress.com/2008/10/dreamhost_editingftpuser.jpg"&gt;&lt;img height="297" width="460" alt="" mce_src="http://stuartthompsontech.wordpress.com/files/2008/10/dreamhost_editingftpuser.jpg" src="http://stuartthompsontech.wordpress.com/files/2008/10/dreamhost_editingftpuser.jpg" title="dreamhost_editingftpuser" class="alignnone size-full wp-image-64" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p mce_style="text-align:left;" style="text-align: left;"&gt;This enables the user to connect using a Telnet/SSH client, which is exactly what we are going to do next.&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;&lt;strong&gt;Step 4 - Download some tools&lt;/strong&gt;&lt;br /&gt;
Next we're going to download the tools we'll need to create and configure our rails website.  We'll need the latest release of Ruby, MySQL, HeidiSql, and PuTTY.  HeidiSql is a free gui for maintaining MySQL databases.  PuTTY is a free Telnet/SSH client that we'll use for remote configuration of our site.  Note that you do not need to signup on the MySQL site to get the download.  Click the &lt;em&gt;No thanks, just let me download&lt;/em&gt; link.&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Ruby 1.8.6-27 RC1 can be &lt;a target="_blank" mce_href="http://rubyforge.org/frs/?group_id=167" href="http://rubyforge.org/frs/?group_id=167"&gt;downloaded here&lt;/a&gt;.&lt;/li&gt;
    &lt;li&gt;MySQL 5.0 Community Server can be &lt;a target="_blank" mce_href="http://dev.mysql.com/downloads/mysql/5.0.html#win32" href="http://dev.mysql.com/downloads/mysql/5.0.html#win32"&gt;downloaded here&lt;/a&gt; (select the Windows ZIP/Setup.EXE (x86) option)&lt;/li&gt;
    &lt;li&gt;HeidiSQL 3.2 can be &lt;a target="_blank" mce_href="http://www.heidisql.com/download.php" href="http://www.heidisql.com/download.php"&gt;downloaded here&lt;/a&gt;.&lt;/li&gt;
    &lt;li&gt;PuTTY can be &lt;a target="_blank" mce_href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html" href="http://www.chiark.greenend.org.uk/%7Esgtatham/putty/download.html"&gt;downloaded here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;&lt;strong&gt;Step 5 - Installing Rails&lt;/strong&gt;&lt;br /&gt;
Now that we have the necessary tools installed it is time to setup Rails locally.  Fortunately, Ruby comes with everything we need to get setup and running, including the WEBrick web server that we can use to run and test our site before deployment.  When installing Ruby, be sure to check the &lt;em&gt;Enable RubyGems &lt;/em&gt;option on the first page of the installer.&lt;/p&gt;
&lt;p mce_style="text-align:left;" style="text-align: left;"&gt;&lt;a mce_href="http://stuartthompsontech.files.wordpress.com/2008/10/rubyinstallation.jpg" href="http://stuartthompsontech.files.wordpress.com/2008/10/rubyinstallation.jpg"&gt;&lt;img height="355" width="460" alt="" mce_src="http://stuartthompsontech.wordpress.com/files/2008/10/rubyinstallation.jpg" src="http://stuartthompsontech.wordpress.com/files/2008/10/rubyinstallation.jpg" title="rubyinstallation" class="alignnone size-full wp-image-66" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p mce_style="text-align:left;" style="text-align: left;"&gt;Once the installer completes, open up a command window and execute the following commands:&lt;/p&gt;
&lt;p mce_style="text-align:left;padding-left:30px;" style="text-align: left; padding-left: 30px;"&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;cd ruby/bin&lt;br /&gt;
gem update --system&lt;br /&gt;
gem install rails --version 2.1.2&lt;/span&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;This will use the gem system to install rails locally.  If everything is successful, your command window should look something like this:&lt;/p&gt;
&lt;p mce_style="text-align:left;" style="text-align: left;"&gt;&lt;a mce_href="http://stuartthompsontech.files.wordpress.com/2008/10/installrails1.jpg" href="http://stuartthompsontech.files.wordpress.com/2008/10/installrails1.jpg"&gt;&lt;img height="294" width="460" alt="" mce_src="http://stuartthompsontech.wordpress.com/files/2008/10/installrails1.jpg" src="http://stuartthompsontech.wordpress.com/files/2008/10/installrails1.jpg" title="installrails1" class="alignnone size-full wp-image-69" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;You may need to restart your system at this point.  Ughh.  This is because Windows Vista and XP sometimes struggle to detect that new environment variables were added to the $PATH.  Unless you relish fully qualifying the &lt;em&gt;C:/Ruby/bin&lt;/em&gt; directory on the next few commands, I'd advise you restart now.  It's also not a bad idea since we did just install four new programs.  I've found Windows seems to run more smoothly if you reboot after installing new things.&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;&lt;strong&gt;Step 6 - Create your Rails site locally&lt;/strong&gt;&lt;br /&gt;
Now that we have Rails setup, let's create a simple site locally.  I created a new directory on C:\ called &lt;em&gt;projects&lt;/em&gt; in which to develop the site.  Open a command prompt and type the following:&lt;/p&gt;
&lt;p mce_style="padding-left:30px;" style="padding-left: 30px;"&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;cd \&lt;br /&gt;
md projects&lt;br /&gt;
cd projects&lt;br /&gt;
rails MyRailsSite&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This will create your rails site in &lt;em&gt;C:\projects\MyRailsSite&lt;/em&gt;.  Before we add our first view and controller, let's quickly check that everything wired up properly.  To do this we need to start the WEBrick server:&lt;/p&gt;
&lt;p mce_style="padding-left:30px;" style="padding-left: 30px;"&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;cd C:\projects\MyRailsSite&lt;br /&gt;
ruby script/server&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Vista may ask if you wish to &lt;em&gt;unblock&lt;/em&gt; Ruby, which you do.  Your command prompt should look something like the following:&lt;/p&gt;
&lt;p&gt;&lt;a mce_href="http://stuartthompsontech.files.wordpress.com/2008/10/rails_webrickserver.jpg" href="http://stuartthompsontech.files.wordpress.com/2008/10/rails_webrickserver.jpg"&gt;&lt;img height="141" width="460" alt="" mce_src="http://stuartthompsontech.wordpress.com/files/2008/10/rails_webrickserver.jpg" src="http://stuartthompsontech.wordpress.com/files/2008/10/rails_webrickserver.jpg" title="rails_webrickserver" class="alignnone size-full wp-image-71" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can now navigate to &lt;a target="_blank" mce_href="http://127.0.0.1:3000" href="http://127.0.0.1:3000/"&gt;http://127.0.0.1:3000&lt;/a&gt; to see your site.  If everything is configured correctly you should see the Ruby on Rails welcome page:&lt;/p&gt;
&lt;p&gt;&lt;a mce_href="http://stuartthompsontech.files.wordpress.com/2008/10/rubyonrails_welcomescreen.jpg" href="http://stuartthompsontech.files.wordpress.com/2008/10/rubyonrails_welcomescreen.jpg"&gt;&lt;img height="336" width="460" alt="" mce_src="http://stuartthompsontech.wordpress.com/files/2008/10/rubyonrails_welcomescreen.jpg" src="http://stuartthompsontech.wordpress.com/files/2008/10/rubyonrails_welcomescreen.jpg" title="rubyonrails_welcomescreen" class="alignnone size-full wp-image-72" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We can shutdown the WEBrick server by pressing Ctrl-C in the command prompt window.&lt;/p&gt;
&lt;p&gt;Now let's create our first controller and view.  We're going to keep it simple and put up a page that displays the message "Hello World!".  At the command prompt type the following:&lt;/p&gt;
&lt;p mce_style="padding-left:30px;" style="padding-left: 30px;"&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;cd projects\MyRailsSite&lt;br /&gt;
ruby script/generate controller HelloWorld&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;&lt;a mce_href="http://stuartthompsontech.files.wordpress.com/2008/10/rails_createcontroller.jpg" href="http://stuartthompsontech.files.wordpress.com/2008/10/rails_createcontroller.jpg"&gt;&lt;img height="167" width="460" alt="" mce_src="http://stuartthompsontech.wordpress.com/files/2008/10/rails_createcontroller.jpg" src="http://stuartthompsontech.wordpress.com/files/2008/10/rails_createcontroller.jpg" title="rails_createcontroller" class="alignnone size-full wp-image-73" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;This will generate a new controller for you as well as a new view.  If you aren't familiar with MVC development, just follow along for now until the sample becomes clear.  The rest will come in time and with additional reading and practice.  For now it is suffice to say that a controller will perform the work for a web page request where the view will display the results of that work.&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;Let's edit the controller that was generated.  To do this, open up an explorer window, navigate to &lt;em&gt;C:\projects\MyRailsSite\app\controllers&lt;/em&gt;, right-click over the &lt;em&gt;hello_world_controller.rb&lt;/em&gt; file and select &lt;em&gt;Edit&lt;/em&gt; from the context menu.  This should open the controller file in the SciTE editor.  We need to add lines to the class to respond to the &lt;em&gt;index&lt;/em&gt; action.  The &lt;em&gt;index&lt;/em&gt; action is the default action that will be performed for a controller.  To do this, edit the file to look like the following:&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;&lt;a mce_href="http://stuartthompsontech.files.wordpress.com/2008/10/rails_editcontroller.jpg" href="http://stuartthompsontech.files.wordpress.com/2008/10/rails_editcontroller.jpg"&gt;&lt;img height="186" width="442" alt="" mce_src="http://stuartthompsontech.wordpress.com/files/2008/10/rails_editcontroller.jpg" src="http://stuartthompsontech.wordpress.com/files/2008/10/rails_editcontroller.jpg" title="rails_editcontroller" class="alignnone size-full wp-image-74" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;This &lt;em&gt;controller&lt;/em&gt; will now set the variable &lt;em&gt;@message&lt;/em&gt; to the literal "Hello World"; when the index &lt;em&gt;action&lt;/em&gt; is requested.  Controllers perform actions.&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;Save the file and close it.  Now we will create a view to display the message.  Navigate to the &lt;em&gt;C:\projects\MyRailsSite\app\views\hello_world&lt;/em&gt; directory in explorer (notice how Rails created the view directory for us).  Right-click in the directory and create a new file called &lt;em&gt;index.html.erb&lt;/em&gt;.  Now right-click this file and open it in your favorite editor (Notepad will suffice).  Add the following to the file:&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;&lt;a mce_href="http://stuartthompsontech.files.wordpress.com/2008/10/rails_createview.jpg" href="http://stuartthompsontech.files.wordpress.com/2008/10/rails_createview.jpg"&gt;&lt;img height="194" width="347" alt="" mce_src="http://stuartthompsontech.wordpress.com/files/2008/10/rails_createview.jpg" src="http://stuartthompsontech.wordpress.com/files/2008/10/rails_createview.jpg" title="rails_createview" class="alignnone size-full wp-image-75" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;Save the file and close the editor.  We're almost ready to test out our new controller and view.  First, however, we need to configure a &lt;em&gt;route&lt;/em&gt; for our site.  A &lt;em&gt;route&lt;/em&gt; is a mapping from an end-point (url) in our site to an actual controller and view that will fulfil the request.  In explorer, navigate to &lt;em&gt;C:\projects\MyRailsSite\config&lt;/em&gt;, right-click the file &lt;em&gt;routes.rb&lt;/em&gt; and select &lt;em&gt;Edit&lt;/em&gt; from the context-menu.  This will open your routes file in the SciTE editor.  Almost the entire file is commented out.  Most of this file contains instructions for configuring custom routes.  We're going to comment out the last two lines of the file and insert a single mapped route of our own.  Edit the end of the file to look like the following:&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;&lt;a mce_href="http://stuartthompsontech.files.wordpress.com/2008/10/rails_editroutes.jpg" href="http://stuartthompsontech.files.wordpress.com/2008/10/rails_editroutes.jpg"&gt;&lt;img height="105" width="460" alt="" mce_src="http://stuartthompsontech.wordpress.com/files/2008/10/rails_editroutes.jpg" src="http://stuartthompsontech.wordpress.com/files/2008/10/rails_editroutes.jpg" title="rails_editroutes" class="alignnone size-full wp-image-76" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;This line connects the &lt;em&gt;helloworld&lt;/em&gt; route to the &lt;em&gt;hello_world&lt;/em&gt; controller for the &lt;em&gt;index&lt;/em&gt; action.  The action specification isn't actually necessary as the index action is assumed by default if none is specified, but I prefer to be explicit.&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;There is one final thing we'll need to do before we can browse to our page locally.  We need to install and configure MySQL.&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;&lt;strong&gt;Step 7 - Install and configure MySQL&lt;/strong&gt;&lt;br /&gt;
This is a very short step.  Run the MySQL setup package you downloaded earlier and select the &lt;em&gt;Typical&lt;/em&gt; installation option.  Then hit Next-&amp;gt;Next-&amp;gt;Finish all the way to the end.  When the configuration wizard runs, choose &lt;em&gt;Detailed Configuration&lt;/em&gt;, then &lt;em&gt;Developer Machine, &lt;/em&gt;then&lt;em&gt; &lt;/em&gt;&lt;em&gt;Multifunctional Database&lt;/em&gt;.  When asked for a location for the Inno files, I used &lt;em&gt;C:\projects\MySQL&lt;/em&gt;.  Choose &lt;em&gt;Decision Support (DSS)/OLAP&lt;/em&gt; then leave both boxes checked on the next dialog with 3306 as the port number.  Choose &lt;em&gt;Standard Character Set&lt;/em&gt;, then check &lt;em&gt;Install As Windows Service&lt;/em&gt; and leave &lt;em&gt;Include Bin Directory in Windows PATH&lt;/em&gt; unchecked.  Enter a new root password, leave &lt;em&gt;Create An Anonymous Account&lt;/em&gt; unchecked.  Finally, hit &lt;em&gt;Execute&lt;/em&gt; to finish the configuration wizard.  MySQL is now installed and configured.&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;&lt;strong&gt;Step 8 - Create a database for our project&lt;/strong&gt;&lt;br /&gt;
We'll need to create a database for our project.  To do this we'll need to install HeidiSql.  Let's run that installer now.  I use the defaults from the installer except on the &lt;em&gt;Select Additional Tasks&lt;/em&gt; dialog where I uncheck &lt;em&gt;Associate .SQL Files with HeidiSQL. &lt;/em&gt;When the installer completes it will launch the HeidiSQL gui.  Click the New button at the top of the first dialog.  Name the connection &lt;em&gt;MyRailsSite&lt;/em&gt;, click OK, and then enter the password you selected during your MySQL installation into the password box provided.  The first thing we're going to do is create a new database.  Right-click over root@127.0.0.1 in the left side-bar and select &lt;em&gt;Create database&lt;/em&gt; from the context menu.  Enter &lt;em&gt;MyRailsSite&lt;/em&gt; as the database name and click ok.  Now select Tools-&amp;gt;User-Manager from the top menu.  We're going to create a new user to avoid using the root user in our application.  For the &lt;em&gt;Username&lt;/em&gt; type myrailsdbuser, set&lt;em&gt; From Host &lt;/em&gt;to&lt;em&gt; localhost&lt;/em&gt;, and type a password for your new user.  Don't use the same password you used for root.  In the &lt;em&gt;Allow access to&lt;/em&gt; list, left-click over the &lt;em&gt;myrailssite&lt;/em&gt; database (it will turn yellow).  Now click &lt;em&gt;Add User&lt;/em&gt;.  Then click &lt;em&gt;Close&lt;/em&gt; to close the user manager dialog.  Now we've created a database and a specific user for our Rails application to use.&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;&lt;strong&gt;Step 9 - Configure Rails to use the database&lt;/strong&gt;&lt;br /&gt;
Finally we need to configure our Rails site to use our new database.  In an Explorer window, navigate to &lt;em&gt;C:\projects\MyRailsSite\config&lt;/em&gt;, right-click the &lt;em&gt;database.yml&lt;/em&gt; file and edit it in your favorite editor (I use &lt;a target="_blank" mce_href="http://www.textpad.com/" href="http://www.textpad.com/"&gt;TextPad&lt;/a&gt; but NotePad will suffice).  Edit your file to look like the following:&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;&lt;a mce_href="http://stuartthompsontech.files.wordpress.com/2008/10/rails_dbconfig2.jpg" href="http://stuartthompsontech.files.wordpress.com/2008/10/rails_dbconfig2.jpg"&gt;&lt;img height="380" width="285" alt="" mce_src="http://stuartthompsontech.wordpress.com/files/2008/10/rails_dbconfig2.jpg" src="http://stuartthompsontech.wordpress.com/files/2008/10/rails_dbconfig2.jpg" title="rails_dbconfig2" class="alignnone size-full wp-image-83" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt; &lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt; &lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;&lt;strong&gt;Step 10 - Testing the site locally&lt;/strong&gt;&lt;br /&gt;
We're finally ready to test the site locally!  Open up a command window are run the following to start the WEBrick server:&lt;/p&gt;
&lt;p mce_style="text-align:justify;padding-left:30px;" style="text-align: justify; padding-left: 30px;"&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;cd c:\projects\myrailssite&lt;br /&gt;
ruby script/server&lt;/span&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;Then open a browser and navigate to &lt;a target="_blank" mce_href="http://127.0.0.1:3000/" href="http://127.0.0.1:3000/"&gt;http://127.0.0.1:3000/&lt;/a&gt;.  You'll notice that the Rails welcome page still displays.  However, change the url in the browser to point to &lt;a target="_blank" mce_href="http://127.0.0.1:3000/helloworld" href="http://127.0.0.1:3000/helloworld"&gt;http://127.0.0.1:3000/helloworld&lt;/a&gt;.  You should now see your view displaying the message "Hello World!".  Let's remove the default index page now and then make your default route point to your &lt;em&gt;helloworld&lt;/em&gt; view.  To do this, open up Explorer and navigate to &lt;em&gt;c:\projects\myrailssite\public&lt;/em&gt;.  This is your site's public directory.  From here, delete the &lt;em&gt;index.html&lt;/em&gt; file.  That's the welcome page gone; we don't need it anymore.  Now navigate to &lt;em&gt;c:\projects\myrailssite\config&lt;/em&gt; and open the &lt;em&gt;routes.rb&lt;/em&gt; file again.  Add the following line just before the map.connect line we added earlier:&lt;/p&gt;
&lt;p mce_style="text-align:justify;padding-left:30px;" style="text-align: justify; padding-left: 30px;"&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;map.root :controller=&amp;gt;"hello_world"&lt;/span&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;This configures the &lt;em&gt;root&lt;/em&gt; route to point to our hello world controller.  As we stated earlier, there is no need to specify the &lt;em&gt;index&lt;/em&gt; action as it is assumed by default.  Save and close the file, then browse to &lt;a target="_blank" mce_href="http://127.0.0.1:3000" href="http://127.0.0.1:3000/"&gt;http://127.0.0.1:3000&lt;/a&gt; once more.  Your site should now be displaying your "Hello World!" message.  Note how the url is just &lt;a target="_blank" mce_href="http://127.0.0.1:3000" href="http://127.0.0.1:3000/"&gt;http://127.0.0.1:3000&lt;/a&gt; and doesn't have helloworld at the end.  This is an important point about routes.  You aren't navigating a particular directory structure on the site, you are simply navigating routes and actions.  The controller could be named anything you like as long as the route for a particular end-point correctly routed requests for that end-point to your controller.  For now, let's stop the WEBrick server and close the command window.  The final task is to get your Rails site up to &lt;a mce_href="http://www.dreamhost.com" href="http://www.dreamhost.com/"&gt;DreamHost&lt;/a&gt; and serve your "Hello World!" request remotely.&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;&lt;strong&gt;Step 11 - Configuring DreamHost for your site&lt;/strong&gt;&lt;br /&gt;
This final configuration step may seem a little confusing at first, but only if you aren't familiar with Linux and BASH.  It doesn't take very long and it isn't important to understand how it works because you'll only need to do it once.  We're going to install version 2.1.2 of rails to your remote host because that's the version that Passenger (mod_rails) needs in order to run your site.  This is where we'll need PuTTY.  Fortunately there is no installation step with PuTTY.  It is simply an executable that you download and run.&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;When you run PuTTY, you will need to supply the username and password of the user we configured in step 3.  This will connect you to the server that will host your site.  The following instructions are commands to enter into the BASH shell as well as instructions on editing your ~/.bash_profile file (which is similar to environment settings for the command shell in Windows).  The first part of these instructions is about editing your ~/.bash_profile file to ensure that some paths and other required settings are configured before beginning installation.  These instructions have been adapted from the &lt;a target="_blank" mce_href="http://wiki.dreamhost.com/RubyGems" href="http://wiki.dreamhost.com/RubyGems"&gt;DreamHost wiki article on this topic&lt;/a&gt;.&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;Before we update rails, let's first create our Rails site remotely.  To do this, first run PuTTY.  For the &lt;em&gt;Host Name&lt;/em&gt; you will supply your domain name in the form www.MyDomainName.com.  Then click &lt;em&gt;Open&lt;/em&gt;.  I choose &lt;em&gt;No&lt;/em&gt; from the next dialog as I don't want to store anything in the registry.  You will now enter the username and password for the user we created in step 3.  When you connect, type &lt;em&gt;ls&lt;/em&gt; and hit enter.  This is the BASH command to list the contents of the current directory.  You should see &lt;em&gt;MyDomainName.com&lt;/em&gt; listed in the output.  We are going to navigate to that folder and then create a rails site inside that folder.&lt;/p&gt;
&lt;p mce_style="text-align:justify;padding-left:30px;" style="text-align: justify; padding-left: 30px;"&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;cd MyDomainName.com&lt;br /&gt;
rails MyRailsSite&lt;/span&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;This will create a Rails site on the DreamHost server, the same way we did it locally earlier.  We're going to create the site like this and then upload our site files from our local machine to the remote site.  To upload our files, we'll use an Explorer window and ftp.  First, however, we need to create a copy of our database.yml and environment.rb files.  This is because those files will be different on our remote host than they are locally.  Create a copy of each of those files called database.yml.live and environment.rb.live now.  Now edit the database.yml.live file to look like the following:&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;&lt;a mce_href="http://stuartthompsontech.files.wordpress.com/2008/10/rails_dbconfiglive2.jpg" href="http://stuartthompsontech.files.wordpress.com/2008/10/rails_dbconfiglive2.jpg"&gt;&lt;img height="134" width="281" alt="" mce_src="http://stuartthompsontech.wordpress.com/files/2008/10/rails_dbconfiglive2.jpg" src="http://stuartthompsontech.wordpress.com/files/2008/10/rails_dbconfiglive2.jpg" title="rails_dbconfiglive2" class="alignnone size-full wp-image-87" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt; &lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;Edit your environment.rb.live file and uncomment the following line (its on line 5):&lt;/p&gt;
&lt;p mce_style="text-align:justify;padding-left:30px;" style="text-align: justify; padding-left: 30px;"&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;ENV['RAILS_ENV'] ||= 'production'&lt;/span&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;This is important because running in development mode under FastCGI will cause memory leaks on the DreamHost server.  They will catch them and clean them up but it's better to run in full production mode and not cause problems.&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;One final change we need to make locally is to update the &lt;em&gt;c:\projects\myrailssite\config\environments\production.rb&lt;/em&gt; file.  Comment out the &lt;em&gt;config.action_view.cache_template_loading = true&lt;/em&gt; line as it causes problems with the Passenger product that will host our site.&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;Now we're ready to install Rails 2.1.2 remotely.  Switch back to your PuTTY session (or log in again if you &lt;em&gt;exit&lt;/em&gt;ed).  Let's first edit the ~/.bash_profile file.  To do this we will be using the &lt;em&gt;nano&lt;/em&gt; text editor.  To open the ~/.bash_profile file in nano, type the following:&lt;/p&gt;
&lt;p mce_style="text-align:justify;padding-left:30px;" style="text-align: justify; padding-left: 30px;"&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;nano ~/.bash_profile&lt;/span&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;Now you can use the cursor keys to navigate the file.  We need to add the following lines to the end of the file:&lt;/p&gt;
&lt;p mce_style="text-align:justify;padding-left:30px;" style="text-align: justify; padding-left: 30px;"&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;# Path settings&lt;br /&gt;
export GEM_HOME="$HOME/.gems"&lt;br /&gt;
export GEM_PATH="$GEM_HOME:/usr/lib/ruby/gems/1.8"&lt;br /&gt;
export PATH="$HOME/bin:$HOME/.gems/bin:$PATH"&lt;br /&gt;
export RUBYLIB="$HOME/lib:$RUBYLIB"&lt;/span&gt;&lt;/p&gt;
&lt;p mce_style="padding-left:30px;" style="padding-left: 30px;"&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;# Stops the DreamHost processes from killing the gem install process&lt;br /&gt;
alias gem="nice -n19 ~/bin/gem"&lt;/span&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;To save your changes press Ctrl-O then hit enter.  Press Ctrl-X to exit the editor and return to the shell.  You can now type &lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;cat ~/.bash_profile&lt;/span&gt; and the contents of the file should be printed out.  This is a good way to check that your changes were saved and that you typed everything correctly.&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;Now we need to perform the installation.  The following commands will achieve this:&lt;/p&gt;
&lt;p mce_style="text-align:justify;padding-left:30px;" style="text-align: justify; padding-left: 30px;"&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;cd ~&lt;br /&gt;
mkdir .gems&lt;/span&gt;&lt;/p&gt;
&lt;p mce_style="padding-left:30px;" style="padding-left: 30px;"&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;mkdir bin lib src&lt;/span&gt;&lt;/p&gt;
&lt;p mce_style="padding-left:30px;" style="padding-left: 30px;"&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;cd ~/src&lt;br /&gt;
wget http://rubyforge.org/frs/download.php/43985/rubygems-1.3.0.tgz&lt;br /&gt;
tar xzvf rubygems-1.3.0.tgz&lt;br /&gt;
cd rubygems-1.3.0&lt;br /&gt;
ruby setup.rb --prefix=$HOME&lt;/span&gt;&lt;/p&gt;
&lt;p mce_style="padding-left:30px;" style="padding-left: 30px;"&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;cd ~/bin&lt;br /&gt;
ln -s gem1.8 gem&lt;/span&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;For more information on what each of these steps is doing check the &lt;a target="_blank" mce_href="http://wiki.dreamhost.com/RubyGems" href="http://wiki.dreamhost.com/RubyGems"&gt;DreamHost wiki article&lt;/a&gt;.  We can check that the path and gem versions are correct by typing the following:&lt;/p&gt;
&lt;p mce_style="text-align:justify;padding-left:30px;" style="text-align: justify; padding-left: 30px;"&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;which gem&lt;br /&gt;
gem -v&lt;/span&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;These commands should return &lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;/home/USERNAME/bin/gem&lt;/span&gt; and &lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;1.3.0&lt;/span&gt; respectively.  Now we can execute the command to install Rails 2.1.2, which is:&lt;/p&gt;
&lt;p mce_style="text-align:justify;padding-left:30px;" style="text-align: justify; padding-left: 30px;"&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;gem install rails --version 2.1.2&lt;/span&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;What we've accomplished here is to install RubyGems and Rails 2.1.2 to our hosted server.  The last thing we need to do to make everything work is to use rake to &lt;em&gt;freeze&lt;/em&gt; our version of Rails to 2.1.2 so that Passenger will use our Rails installation when running our site.  The commands to do this are as follows.  Please note that you need to supply your domain name in the format MyDomainName.com and the name of your Rails site in place of MyRailsSite in the first command.  This simply changes the current directory so that we're running rake in the right place.&lt;/p&gt;
&lt;p mce_style="text-align:justify;padding-left:30px;" style="text-align: justify; padding-left: 30px;"&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;cd ~/MyDomainName.com/MyRailsSite/&lt;br /&gt;
rake rails:freeze:edge TAG=rel_2-1-2&lt;/span&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;That's it!  Phew.  That felt like a lot of work, but at least you only have to do it once.&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;&lt;strong&gt;Step 12 - Deploying and testing your site remotely&lt;/strong&gt;&lt;br /&gt;
Now that we've set up the environment with &lt;a target="_blank" mce_href="http://www.dreamhost.com" href="http://www.dreamhost.com/"&gt;DreamHost&lt;/a&gt;, the only task left is to deploy the site remotely and test it out.  Before we do that though, we are going to check one last configuration setting in the DreamHost control panel, just to be sure that everything is setup correctly.  If you navigate to Domains-&amp;gt;Manage Domains in the left side-bar and then click the &lt;em&gt;Edit&lt;/em&gt; button again (see step 2), then check out the &lt;em&gt;Specify your web directory&lt;/em&gt; setting.  This is where &lt;a target="_blank" mce_href="http://www.dreamhost.com" href="http://www.dreamhost.com/"&gt;DreamHost&lt;/a&gt; will send requests to &lt;em&gt;MyDomainName.com&lt;/em&gt;.  It should be set to:&lt;/p&gt;
&lt;p mce_style="text-align:justify;padding-left:30px;" style="text-align: justify; padding-left: 30px;"&gt;&lt;span mce_style="color:#000080;" style="color: rgb(0, 0, 128);"&gt;/home/username/MyDomainName.com/MyRailsSite/public&lt;/span&gt;&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;By setting the directory to the &lt;em&gt;public&lt;/em&gt; directory of your Rails site, it means that users cannot navigate outside of that directory and browse places that they aren't supposed to be.&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;Let's finish up and deploy our Rails site from the local machine to the remote server.  We'll use Explorer and ftp to do this.  Open up Explorer and type &lt;em&gt;ftp://ftp.MyDomainName.com&lt;/em&gt; into the address bar.  Now open up the &lt;em&gt;MyDomainName.com&lt;/em&gt; and then &lt;em&gt;MyRailsSite&lt;/em&gt; folders.  You will need to copy your app directory from your local machine at &lt;em&gt;c:\projects\myrrailssite\app&lt;/em&gt; up to the remote server.  When you have copied these files, navigate to the &lt;em&gt;pubilc &lt;/em&gt;directory on the remote server and delete the index.html file.  We don't need the Rails welcome page on live anymore either!  Then navigate to the &lt;em&gt;config&lt;/em&gt; directory and copy the &lt;em&gt;routes.rb&lt;/em&gt;, &lt;em&gt;environment.rb.live&lt;/em&gt; and &lt;em&gt;database.yml.live&lt;/em&gt; files up to the corresponding folder on the server.  Don't forget to rename these to &lt;em&gt;environment.rb&lt;/em&gt; and &lt;em&gt;database.yml&lt;/em&gt; on the remote server.  We only renamed them so that we could have two different files locally.  Finally, navigate to the &lt;em&gt;config/environments&lt;/em&gt; folder and copy the &lt;em&gt;production.rb&lt;/em&gt; file that we edited up to the corresponding location on the remote server.  From now on, when you deploy your site, you will only have to copy the &lt;em&gt;app&lt;/em&gt; folder to the remote server (unless you change config settings that is).&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;The final step before we can test our site on live is to setup the MySQL database on the DreamHost side to match the one we set up locally.  Since we didn't create any database tables, this is fairly simple to do through the DreamHost interface.  Go to Goodies-&amp;gt;Manage MySQL and repeat the same steps here as we did in step 8.  You can also use HeidiSQL if you want to manage your database remotely that way.  However, for now I recommend using the DreamHost web interface to do this work.  All you need to ensure is that the database name and username/password for that database match the settings you specified in your database.yml file.  I'm going to cover using databases in Rails in more detail in a future article.  For now we just need to get an empty database and a user that has access to keep Rails happy.&lt;/p&gt;
&lt;p mce_style="text-align:left;" style="text-align: left;"&gt;Congratulations!  Assuming that everything was wired up correctly, you should now be able to open a browser and navigate to &lt;em&gt;http://www.MyDomainName.com&lt;/em&gt; to see your site being hosted remotely.&lt;/p&gt;
&lt;p mce_style="text-align:justify;" style="text-align: justify;"&gt;Hopefully this article will help you get up and running with a basic Rails site that is hosted remotely.  The focus of this article was understanding the relationship between running a Rails site locally and hosting it on a remote server.  Setting up your development in this way from day one will save a lot of headaches later when it comes to deployment time.  Developing and testing locally, then deploying to a live host means that problems can be identified early and that changes can be tested locally rather than on a live site.  I'm going to expand upon this article as part of my ongoing experiement with ASP.NET, Silverlight, PHP, and Ruby on Rails.  Next we're going to develop a database, understand models using ActiveRecord, and dig a little deeper into Rails.  For now: happy hosting!&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/109.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>The ASP.NET, Silverlight, PHP, Rails Experiment</title><link>http://blogs.sftsrc.com/stuart/archive/2008/10/27/108.aspx</link><pubDate>Mon, 27 Oct 2008 20:06:37 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2008/10/27/108.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/108.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/108.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2008/10/27/108.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/108.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">The ASP.NET, Silverlight, PHP, Rails Experiment</source><description>&lt;p style="text-align: justify;"&gt;I've been working with &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/default.aspx"&gt;Microsoft technologies&lt;/a&gt; for over ten years, specifically &lt;a target="_blank" href="http://www.asp.net/"&gt;Microsoft's web development technologies&lt;/a&gt;.  During that time I have built a variety sites ranging in scope from e-commerce, educational, service provision, &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Software_as_a_Service"&gt;SaaS&lt;/a&gt;, to dashboards, portals, internal tools, and even SAP-migration.  While I praise the technology stack for what it allows me to do, it also comes with a whole host of limitations that make it hard for me to deliver the experience my clients would like.  Throughout this decade of web development I have heard a lot from those around me about alternative technology stacks that promise all manner of improvements and experiences.  Unfortunately there is a lot of resistance from any one technology stack to listen to and learn from the stacks around them, most of the cross-platform feedback comes in the form of "Microsoft sucks" or "PHP is for fan-boy script kiddies".  The truth is that a large number of successful business are hosted on a wide variety of platforms.  Each technology stack has to at least be viable for that to be true.  The problem is getting at the truth without the zealous noise of "my stacks better than your stack" getting in the way.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;I decided that it was time for me to branch out and become more informed on these technologies myself so that I could truly understand the differences and what made each of them unique.  I'm hoping that as part of this experience I can not only become a better developer but also learn the problems that Ruby on Rails or PHP addresses.  I'll like to be able to speak from an informed standpoint about the differences between the Microsoft and open-source approaches as well as better understand the problems each of those development worlds faces on a daily basis.  Either way, it's going to be a heck of a lot of fun.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;The experiment I have in mind is to build the same web-site using four different technologies.  From the Microsoft camp I have chosen &lt;a target="_blank" href="http://www.asp.net"&gt;ASP.NET&lt;/a&gt; and &lt;a target="_blank" href="http://silverlight.net/"&gt;Silverlight&lt;/a&gt;.  From the open-source perspective I have chosen &lt;a target="_blank" href="http://www.php.net/"&gt;PHP&lt;/a&gt; and &lt;a target="_blank" href="http://www.rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt;.  I chose PHP and RoR because they are two technologies that I have always wanted to learn.  Learning both of those will also require some digging into &lt;a target="_blank" href="http://httpd.apache.org/"&gt;Apache&lt;/a&gt; and &lt;a target="_blank" href="http://www.linux.org"&gt;Linux&lt;/a&gt;, another two areas that I have too little direct experience with to effectively participate in an informed conversation.&lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;a href="http://www.asp.net"&gt;&lt;img height="44" width="108" alt="" src="http://stuartthompsontech.wordpress.com/files/2008/10/logo.png" title="ASP.NET" class="alignnone size-full wp-image-48" /&gt; &lt;/a&gt; &lt;a href="http://www.silverlight.net"&gt;&lt;img height="45" width="131" alt="" src="http://stuartthompsontech.wordpress.com/files/2008/10/silverlightlogo.jpg" title="silverlightlogo" class="alignnone size-full wp-image-49" /&gt; &lt;/a&gt;&lt;a href="http://www.php.net"&gt;&lt;img height="49" width="86" alt="" src="http://stuartthompsontech.wordpress.com/files/2008/10/php.gif" title="php" class="alignnone size-full wp-image-50" /&gt; &lt;/a&gt;&lt;a href="http://www.rubyonrails.org"&gt;&lt;img height="54" width="42" alt="" src="http://stuartthompsontech.wordpress.com/files/2008/10/rails.png?w=74" title="rails" class="alignnone size-thumbnail wp-image-51" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;Our horses are ready to race.  In terms of hosting, I have selected &lt;a target="_blank" href="http://www.dreamhost.com"&gt;DreamHost&lt;/a&gt; for the PHP and Rails sites, and I'm going to use &lt;a target="_blank" href="http://www.stormhosts.com"&gt;StormHosts&lt;/a&gt; for the &lt;a target="_blank" href="http://www.asp.net"&gt;ASP.NET&lt;/a&gt; and &lt;a target="_blank" href="http://www.silverlight.net"&gt;Silverlight&lt;/a&gt; projects (assuming that SH can do .NET 3.5, which I believe I saw at some point).  The reason I'm using remote hosting services for this experiment is that I don't believe you get the true experience of a technology stack until you host it in this way.  It is very easy to get a Rails site up and running using &lt;a target="_blank" href="http://www.webrick.org"&gt;WEBrick&lt;/a&gt; and a local installation of Ruby.  Similarly, it is easy to get an ASP.NET site running on the personal web server that ships with &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/vstudio/default.aspx"&gt;Visual Studio 2008&lt;/a&gt;.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;The first phase of the experiment is to get a "Hello World!" site up and running for each of the four environments.  The specifications are that a single end-point be accessible that displays the text "Hello World!" and that this end-point is accessible in both &lt;a target="_blank" href="http://www.microsoft.com/windows/products/winfamily/ie/default.mspx"&gt;Internet Explorer&lt;/a&gt; 7 and &lt;a target="_blank" href="http://www.mozilla.com/en-US/firefox/"&gt;FireFox&lt;/a&gt; 3.&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/108.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>Reflector to go to RedGate</title><link>http://blogs.sftsrc.com/stuart/archive/2008/08/20/107.aspx</link><pubDate>Wed, 20 Aug 2008 16:21:13 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2008/08/20/107.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/107.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/107.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2008/08/20/107.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/107.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Reflector to go to RedGate</source><description>&lt;p&gt;
Lutz Roeder has decided to move on from Reflector.  &lt;a href="http://www.red-gate.com/index.htm?gclid=CNj46_jonJUCFRhhnAod-Cqrfw"&gt;RedGate&lt;/a&gt; will be taking over the project from now on.  Fortunately, they have agreed to maintain the &lt;i&gt;community&lt;/i&gt; edition of the software.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.lutzroeder.com/2008/08/future-of-net-reflector.html"&gt;http://blog.lutzroeder.com/2008/08/future-of-net-reflector.html&lt;/a&gt;
&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/107.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>NDepend Part II - Beginning CQL</title><link>http://blogs.sftsrc.com/stuart/archive/2008/08/19/106.aspx</link><pubDate>Tue, 19 Aug 2008 18:25:12 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2008/08/19/106.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/106.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/106.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2008/08/19/106.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/106.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">NDepend Part II - Beginning CQL</source><description>&lt;p&gt; In my continuing use of &lt;a href="http://www.ndepend.com"&gt;NDepend&lt;/a&gt; on both my work and home projects, I have been investigating CQL more and more, especially from the perspective of use in continuous integration.  NDepend provides some incredibly powerful analysis features and I find the idea that constraints can be applied and warnings reported as part of day 1 builds to be extremely appealing.  I'm all about keeping code clean, constrained, and consistent.  NDepend provides another great tool in my kit to ensure that my own code is marshalled to my standards from the very first line that is written.  As David Muhondro put so eloquently in his blog post, NDepend is &lt;a href="http://www.mohundro.com/blog/2008/03/26/NDependStaticAnalysisOnSteroids.aspx"&gt;static analysis on steroids&lt;/a&gt;.  When most users encounter CQL for the first time, the response is "wow, this looks really powerful, now what does it mean?".  I've started by taking the stock queries that are included in a basic NDepend project and understanding what they mean and the warnings that they are expected to generate.  By understanding the warnings and their purpose in the project, I began to understand how I could tweak those queries and even write my own to enforce the rules I'd like my code to live by. &lt;/p&gt;
&lt;p&gt; Let's start by looking at an example.  After creating a new NDepend project and pointing it at a list of assemblies to analyze, the default CQL queries that are included are grouped into the following categories: &lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Code Quality&lt;/li&gt;
    &lt;li&gt;Design&lt;/li&gt;
    &lt;li&gt;Unused Code / Dead Code&lt;/li&gt;
    &lt;li&gt;Encapsulation&lt;/li&gt;
    &lt;li&gt;Diff / Changes / Evolution&lt;/li&gt;
    &lt;li&gt;Test Coverage&lt;/li&gt;
    &lt;li&gt;Purity / Immutability / Side-Effects&lt;/li&gt;
    &lt;li&gt;Naming Conventions&lt;/li&gt;
    &lt;li&gt;.NET Framework Usage&lt;/li&gt;
    &lt;li&gt;Statistics&lt;/li&gt;
    &lt;li&gt;Samples of Custom Constraints&lt;/li&gt;
    &lt;li&gt;Constraints extracted from Source Code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; &lt;a href="http://www.stuartthompson.net/SubTextBlog/Images/stuartthompson_net/SubTextBlog/08-19-2008-DefaultCQLQueries/08-19-2008-DefaultCQLQueries.JPG"&gt;&lt;img border="0" src="http://www.stuartthompson.net/SubTextBlog/Images/stuartthompson_net/SubTextBlog/08-19-2008-DefaultCQLQueries/08-19-2008-DefaultCQLQueries_Thumbnail.JPG" alt="" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt; I started by looking at the &lt;em&gt;Unused Code / Dead Code&lt;/em&gt; queries, specifically at the &lt;em&gt;Potentially unused methods&lt;/em&gt; query.  By double-clicking on the query it is opened in the CQL query editor and displays the following: &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div style="border: medium none rgb(136, 136, 136); padding: 3px; background-color: rgb(255, 255, 221); font-family: Courier Sans MS;"&gt; // &amp;lt;Name&amp;gt;Potentially unused methods&amp;lt;/Name&amp;gt;&lt;br /&gt;
WARN IF Count &amp;gt; 0 IN SELECT TOP 10 METHODS WHERE&lt;br /&gt;
MethodCa == 0 AND            // Ca=0 -&amp;gt; No Afferent Coupling -&amp;gt; The method is not used in the context of this application.&lt;br /&gt;
!IsPublic AND                // Public methods might be used by client applications of your assemblies.&lt;br /&gt;
!IsEntryPoint AND            // Main() method is not used by-design.&lt;br /&gt;
!IsExplicitInterfaceImpl AND // The IL code never explicitely calls explicit interface methods implementation.&lt;br /&gt;
!IsClassConstructor AND      // The IL code never explicitely calls class constructors.&lt;br /&gt;
!IsFinalizer                 // The IL code never explicitely calls finalizers.&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt; &lt;strong&gt;Breaking it Down&lt;/strong&gt;&lt;br /&gt;
Let's break this down a little.  First of all it is important to realize that this is not SQL, despite any similarities in the syntax.  The first line selects the top 10 methods that satisfy the query and then raises a warning if the total number of methods is greater than 0.  The reason for the seemingly superfluous top 10 selection is that if the count is greater than zero then those top 10 will be displayed as the results of the query.  To avoid swamping with noise the query is restricting to only the first ten offenders.  The next line is the first part of the WHERE clause and looks for methods with an &lt;a ccnet="" display="" confluence.public.thoughtworks.org="" http:="" href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET"&gt;CruiseControl&lt;/a&gt; to bring these warning and reports into the daily life of your projects.  While static analysis en masse isn't for everyone (not even for me), a small list of CQL queries can help you perform necessary housekeeping without having to do the hard hunting work yourself.  The inevitable question is whether or not this overlaps with FxCop.  There is some overlap, but they are both just tools from which you should pluck the best of the functionality you like and strike down the cruft that gets in the way.  There are some cases where writing an FxCop rule specific to your application is a good thing, however I'm finding that writing CQL queries for warnings lends itself a little better to how I think about static analysis in the first place.  The key is finding that sweet spot in the middle. &lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/106.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>Designing for Testability</title><link>http://blogs.sftsrc.com/stuart/archive/2008/07/30/105.aspx</link><pubDate>Wed, 30 Jul 2008 19:56:41 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2008/07/30/105.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/105.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/105.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2008/07/30/105.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/105.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Designing for Testability</source><description>&lt;p&gt;Automotive manufactures have long been on the vaunted TDD bandwagon.  For years they have harnessed the amazing potential of unit testing, verifying components individually prior to the expensive and time-consuming exercise of assembling them to make a completed vehicle.  Integration testing in the automotive world is very expensive and to find that a single component failure has wasted a fleet of test vehicles as well as many months of construction and fabrication is close to unacceptable.  However, they have also long faced the question of when and where to design for testability; a line still not clearly defined in any industry.&lt;/p&gt;
&lt;p&gt;It makes perfect sense that if a component is to be tested in isolation from the system it will eventually be integrated with that a certain amount of planning is necessary in order to facilitate that testing.  This means that certain designs, while technically and functionally brilliant, may need to be modified if they are ever to be tested.  The question is where to draw the line.  All too often in software engineering the line is drawn firmly on one side or the other, rarely in a position of balance.&lt;/p&gt;
&lt;p&gt;I can understand on a modern motor vehicle with multiple on-board computers performing a variety of related tasks that there is a need to interface with and test those computers thoroughly.  I'm sure that to the component manufacturers the need for extra diagnostic access ports and programmable interfaces is a hindrance to their development; after all they are working in a very closed system.  However, to the test engineers the ability to simulate all manner of failures and receive highly detailed information about everything the computer is doing is absolutely indispensible.  They cannot guarantee the component functions correctly without it.&lt;/p&gt;
&lt;p&gt;Unfortunately this desire for components to be testable can easily get out of hand.  Consider that a test engineer is tasked with ensuring that the onboard computer functions at various speeds.  Unforuntately his equipment is bulky and doesn't fit inside the vehicle.  Even at low speeds he finds that keeping up with a car in motion requires him to run alongside pretty quickly.  Should he require that the car not go faster than 8mph in order to ensure that he can completely guarantee the functionality of the computer for the legal range of speeds he is able to test?  Something tells me that the manufacturer wouldn't be able to sell too many of that particular model.&lt;/p&gt;
&lt;p&gt;Instead the test engineer must find other ways to test the car at high speeds.  Custom models of the car are constructed that allow a connected rig to be tethered to the car, carrying all of the the test equipment alongside even at high speeds.  At even higher speeds, motion simulations and car treadmills are employed to allow for testing that the tethered rig is unsafe for.  The design of the car wasn't limited to a maximum speed of 8mph, rather a compromise was found to allow the right balance of functionality and testing.&lt;/p&gt;
&lt;p&gt;In software engineering, we have a variety of tools and frameworks at our disposal to accomplish similar testing of software.  Unit testing frameworks, mock frameworks, dependency injection containers; they are tools.  Each plays a specific role and solves a particular flavor of problem, however none of them are all-encompassing and all of them require thought before use.&lt;/p&gt;
&lt;p&gt;There is a growing epidemic of code grown out of the desire for "high coverage" unit testing.  However, some of the motivations behind this testing appear to have taken an 8mph turn somewhere; for the worse.  In an effort to improve code quality, the initiatives towards testing have started to build 8mph cars with 6 wheels and no doors.  In terms of test coverage the cars are truly superb, but from the outside many consumers are left scratching their heads and wondering where it all went wrong.&lt;/p&gt;
&lt;p&gt;I usually find that if a particular design decision is inhibiting the testability of a component, one of three things is happening:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The design is so tightly coupled and stable that no testing could hope to penetrate the darkness of the black box surrounding it.  (i.e. a dll with one 5,000 line method inside that does "something")&lt;/li&gt;
&lt;li&gt;The design is so abstract that is doesn't actually do anything.  (i.e. a dll containing only interfaces - test that suckas!)&lt;/li&gt;
&lt;li&gt;The testing tool being applied is the wrong one for the job.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;As a software engineer, I can fix 1 and 2.  Fortunately with good design and architecture we can actually prevent 1 and 2 from ever reaching QA in the first place.&lt;/p&gt;
&lt;p&gt;There isn't much I can do about number 3.  This is where I ask for the line to be moved a little with regards to the tool that is being employed.  Here are a few examples of hammering screws and screwing nails.&lt;/p&gt;
&lt;p&gt;Static methods, unless invoked through reflection, attract coupling from consumers.  That is to say that if an assembly contains a static method, there is a good chance that something calling that static method has a strong reference to the assembly that exposes it.  This is not a bad thing and there are many places where such a design makes perfect sense.  However, in certain situations, this can cause mocking frameworks to perform more work than necessary to set up the premise for a unit test because they can't mock away the reference the exposed assembly that performs work.  This is because mocking frameworks are ideal for mocking abstract implementations and poor for mocking tightly coupled components.  There is nothing to mock because everything is explicitly stated.  See screw, swing hammer.  Static methods are perfect for unit testing thanks to the magic of reflection.  Inspect the method contract (the logical contract not the physical source code - i.e. what, in English, does it do) and based upon that contract construct a suite of tests to affirm that the method is indeed doing what it promised it would.&lt;/p&gt;
&lt;p&gt;Service assemblies, such as configuration loaders or proxies, tend to operate more upon interfaces than implementations.  That is because the value they add is an operation upon some implementation of an interface rather than a concrete process defined up front.  This is the provider model.  We write a set of interfaces describing the kinds of things a provider can do.  We also write a set of services than help those providers achieve some work.  We don't write the actual providers themselves because this is a plugin model.  Well, how do we test a provider that hasn't been written yet?  Wait, this could be hard in unit testing.  We call a method on an interface but have no way to know what the "as yet unwritten" provider will do in that method call and have no way of knowing whether the result is correct.  NTemporalDisplacementUnit 1.0 hasn't been released yet so we can't do it in a state of temporal flux either...panic!  But wait, in thinking about the problem further we realise that we don't care what the provider does.  The contract we are providing is that we will interact with a provider in a predictable and documented fashion.  As long as we interact with the interface in the correct way and at the correct time, our part of the contract is fulfilled.  Woohoo!  That's what a mock framework is for.  We mock up a provider and check that our service correctly interacts with the provider.  Mock frameworks are great for this.  Finally, a nail that we can hit with our hammer.&lt;/p&gt;
&lt;p&gt;If you find that such thinking manifests itself in dogmatic emails that state "static methods shouldn't be used because they inhibit testability" or "interfaces are bad because we can't get coverage with them." then it might be time to inspect both the situation and the tools and see that the two are being correctly paired.&lt;/p&gt;
&lt;p&gt;The goal of testing is to improve the quality of the end product, not to turn lots of lights a pretty shade of green.  8mph cars with lots of green LEDs and no doors for great dogmatic case study's and really awful consumer responses.&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/105.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>Planning for the worst</title><link>http://blogs.sftsrc.com/stuart/archive/2008/07/25/104.aspx</link><pubDate>Fri, 25 Jul 2008 20:28:28 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2008/07/25/104.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/104.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/104.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2008/07/25/104.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/104.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Planning for the worst</source><description>&lt;p&gt;&lt;em&gt;"The status page we use to report service disruptions in progress is suffering a temporary misconfiguration."&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Brilliance!&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/104.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>Technorati Blog Claim</title><link>http://blogs.sftsrc.com/stuart/archive/2008/07/15/103.aspx</link><pubDate>Tue, 15 Jul 2008 21:19:20 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2008/07/15/103.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/103.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/103.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2008/07/15/103.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/103.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Technorati Blog Claim</source><description>I claim this blog in the name of Stuart Thompson for my new &lt;a href="http://technorati.com/claim/s9wmqqvsia"&gt;Technorati Profile&lt;/a&gt;.&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/103.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>LINQ to Coffee</title><link>http://blogs.sftsrc.com/stuart/archive/2008/07/15/102.aspx</link><pubDate>Tue, 15 Jul 2008 19:55:41 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2008/07/15/102.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/102.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/102.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2008/07/15/102.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/102.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">LINQ to Coffee</source><description>&lt;p&gt;Nice!  A perfect addition to the reference material you keep within reach.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.cafepress.com/linq.225122905"&gt;http://www.cafepress.com/linq.225122905&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/102.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>Debugging Into .NET Source Code</title><link>http://blogs.sftsrc.com/stuart/archive/2008/07/14/101.aspx</link><pubDate>Mon, 14 Jul 2008 20:04:31 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2008/07/14/101.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/101.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/101.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2008/07/14/101.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/101.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Debugging Into .NET Source Code</source><description>&lt;p&gt;Many have “heard” that you can now step into .NET source code when debugging in Visual Studio 2008.  For those who have not been doing this since the start of the year, you can find excellent instructions for configuring Visual Studio to get the necessary symbols &lt;a href="http://blogs.msdn.com/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I highly recommend understanding this process and making it a part of your debugging routine.  It often becomes necessary to understand why the .NET framework is behaving in a certain fashion while developing.  By stepping into the source code and using the watch window, I’ve saved myself a lot of hours of head-scratching.  More often than not it’s as simple as understanding why an exception was thrown and the hidden meaning behind the message.  Within minutes I can usually pinpoint how I was incorrectly using one of the libraries, fix the bug, and be on my way.&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/101.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>LINQ'd In #1 - Behavior Injection</title><link>http://blogs.sftsrc.com/stuart/archive/2008/07/14/100.aspx</link><pubDate>Mon, 14 Jul 2008 18:51:44 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2008/07/14/100.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/100.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/100.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2008/07/14/100.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/100.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">LINQ'd In #1 - Behavior Injection</source><description>&lt;p&gt;As part of a continuing set of articles on LINQ, I want to first take a moment to look at how the "natural" syntax of LINQ is turned into executable code.  Once we understand how those expressions and compiled we can investigate ways to extend the code that is being executed.&lt;/p&gt;
&lt;p&gt;First of all let’s consider a very simple LINQ expression:&lt;/p&gt;
&lt;div style="BORDER-RIGHT: #444444 1px solid; PADDING-RIGHT: 3px; BORDER-TOP: #444444 1px solid; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; BORDER-LEFT: #444444 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #444444 1px solid; BACKGROUND-COLOR: #ffffdd"&gt;&lt;font face="Courier New" color="#0000ff"&gt;from&lt;/font&gt;&lt;font face="Courier New"&gt; num &lt;/font&gt;&lt;font face="Courier New" color="#0000ff"&gt;in&lt;/font&gt;&lt;font face="Courier New"&gt; Enumerable.Range(&lt;/font&gt;&lt;font face="Courier New" color="#c81efa"&gt;1&lt;/font&gt;&lt;font face="Courier New"&gt;,&lt;/font&gt;&lt;font face="Courier New" color="#c81efa"&gt;9&lt;/font&gt;&lt;font face="Courier New"&gt;)&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" color="#0000ff"&gt;where&lt;/font&gt;&lt;font face="Courier New"&gt; num % &lt;/font&gt;&lt;font face="Courier New" color="#c81efa"&gt;2&lt;/font&gt;&lt;font face="Courier New"&gt; == &lt;/font&gt;&lt;font face="Courier New" color="#c81efa"&gt;0&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" color="#0000ff"&gt;select&lt;/font&gt;&lt;font face="Courier New"&gt; num&lt;/font&gt;&lt;/div&gt;
&lt;p&gt;This expression selects the even numbers in the series 1–9.  Let’s first break this down into the actual code that is being executed.  Behind the scenes LINQ is viewing this expression as a series of lambda expressions and extension methods.  Our example is actually being run as:&lt;/p&gt;
&lt;div style="BORDER-RIGHT: #444444 1px solid; PADDING-RIGHT: 3px; BORDER-TOP: #444444 1px solid; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; BORDER-LEFT: #444444 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #444444 1px solid; BACKGROUND-COLOR: #ffffdd"&gt;&lt;font face="Courier New"&gt;Enumerable.Range(&lt;font color="#993300"&gt;1&lt;/font&gt;,&lt;font color="#993300"&gt;9&lt;/font&gt;).Where(n =&amp;gt; n % &lt;font color="#993300"&gt;2&lt;/font&gt; == &lt;font color="#993300"&gt;0&lt;/font&gt;)&lt;/font&gt;&lt;/div&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;Enumerable.Range(1,9) &lt;/font&gt;yields an &lt;font face="Courier New"&gt;IEnumerable&amp;lt;int&amp;gt;&lt;/font&gt;.  By using &lt;a href="http://www.aisto.com/roeder/dotnet/"&gt;Reflector&lt;/a&gt; we can discover that the signature of the Where method looks like the following:&lt;/p&gt;
&lt;div style="BORDER-RIGHT: #444444 1px solid; PADDING-RIGHT: 3px; BORDER-TOP: #444444 1px solid; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; BORDER-LEFT: #444444 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #444444 1px solid; BACKGROUND-COLOR: #ffffdd"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;public static&lt;/font&gt; IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(&lt;br /&gt;&lt;font color="#0000ff"&gt;    this&lt;/font&gt; IEnumerable&amp;lt;TSource&amp;gt; source, &lt;br /&gt;    Func&amp;lt;TSource, bool&amp;gt; predicate)&lt;/font&gt;&lt;/div&gt;
&lt;p&gt;This is clearly an extension method on &lt;font face="Courier New"&gt;IEnumerable&amp;lt;TSource&amp;gt;&lt;/font&gt; that takes a &lt;font face="Courier New"&gt;Func&amp;lt;TSource, bool&amp;gt;&lt;/font&gt; as its only parameter.  While the actual internals of the Where method are actually a little more complex due to the way in which iterators have been abstracted, we could theorize that the behavior is roughly similar to the following:&lt;/p&gt;
&lt;div style="BORDER-RIGHT: #444444 1px solid; PADDING-RIGHT: 3px; BORDER-TOP: #444444 1px solid; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; BORDER-LEFT: #444444 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #444444 1px solid; BACKGROUND-COLOR: #ffffdd"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;public static&lt;/font&gt; IEnumerable&amp;lt;TSource&amp;gt; Where&amp;lt;TSource&amp;gt;(&lt;br /&gt;    &lt;font color="#0000ff"&gt;this&lt;/font&gt; IEnumerable&amp;lt;TSource&amp;gt; source, &lt;br /&gt;    Func&amp;lt;TSource, &lt;font color="#0000ff"&gt;bool&lt;/font&gt;&amp;gt; predicate)&lt;br /&gt;{&lt;br /&gt;    &lt;font color="#0000ff"&gt;foreach&lt;/font&gt; (TSource t &lt;font color="#0000ff"&gt;in&lt;/font&gt; source)&lt;br /&gt;    {&lt;br /&gt;       &lt;font color="#0000ff"&gt; if&lt;/font&gt; (predicate.Invoke(t) == &lt;font color="#0000ff"&gt;true&lt;/font&gt;)&lt;br /&gt;            &lt;font color="#0000ff"&gt;yield return&lt;/font&gt; t;&lt;br /&gt;    }&lt;br /&gt;}&lt;/font&gt;&lt;/div&gt;
&lt;p&gt;“For each item in the supplied &lt;font face="Courier New"&gt;IEnumerable&lt;/font&gt;, invoke the supplied &lt;em&gt;predicate&lt;/em&gt; and add the item to the returned collection if that predicate returned true.”&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: If you haven’t encountered keyword yield before, check out &lt;/em&gt;&lt;a href="http://www.stuartthompson.net/SubTextBlog/softwareengineering/archive/2008/06/16/93.aspx"&gt;&lt;em&gt;this post about how it works&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Now that we understand how the statement is working internally, lets look at ways in which we can extend it.  To understand the following trick we need to think for a second about how extension methods are implemented, or more importantly about how they are resolved.&lt;/p&gt;
&lt;p&gt;When the compiler encounters a statement of the form:&lt;/p&gt;
&lt;div style="BORDER-RIGHT: #444444 1px solid; PADDING-RIGHT: 3px; BORDER-TOP: #444444 1px solid; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; BORDER-LEFT: #444444 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #444444 1px solid; BACKGROUND-COLOR: #ddffdd"&gt;&lt;font face="Courier New"&gt;&amp;lt;type&amp;gt;.&amp;lt;method&amp;gt;()&lt;/font&gt;         (e.g. &lt;font face="Courier New"&gt;IEnumerable&amp;lt;int&amp;gt;.Where(…)&lt;/font&gt;)&lt;/div&gt;
&lt;p&gt;for which there is no explicitly defined method, it searches the current list of scoped namespaces for an extension method that matches the implied signature.  The System.Linq namespace defines the extension method we’ve been examining above.  However, what if we wanted to use our own method instead of the System.Linq version of &lt;font face="Courier New"&gt;Where()?&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;We might want to add in some logging statements when the predicate finds a match.  Let’s do this right now by adding our own extension method for the &lt;font face="Courier New"&gt;IList&amp;lt;T&amp;gt;&lt;/font&gt; generic.  To do this we need to define a static class that contains a static &lt;font face="Courier New"&gt;Where&lt;/font&gt; method that has this &lt;font face="Courier New"&gt;IList&amp;lt;T&amp;gt;&lt;/font&gt; as its first parameter:&lt;/p&gt;
&lt;div style="BORDER-RIGHT: #444444 1px solid; PADDING-RIGHT: 3px; BORDER-TOP: #444444 1px solid; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; BORDER-LEFT: #444444 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #444444 1px solid; BACKGROUND-COLOR: #ffffdd"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;public static class&lt;/font&gt; ListExtensions&lt;br /&gt;{&lt;br /&gt;    &lt;font color="#0000ff"&gt;public static&lt;/font&gt; IEnumerable&amp;lt;T&amp;gt; Where&amp;lt;T&amp;gt;(&lt;br /&gt;        this IList&amp;lt;T&amp;gt; source, Func&amp;lt;T, &lt;font color="#0000ff"&gt;bool&lt;/font&gt;&amp;gt; predicate)&lt;br /&gt;    {&lt;br /&gt;        &lt;font color="#0000ff"&gt;foreach&lt;/font&gt; (T t &lt;font color="#0000ff"&gt;in&lt;/font&gt; source)&lt;br /&gt;        {&lt;br /&gt;            &lt;font color="#0000ff"&gt;if&lt;/font&gt; (predicate.Invoke(t) == &lt;font color="#0000ff"&gt;true&lt;/font&gt;)&lt;br /&gt;            {&lt;br /&gt;                Console.WriteLine(&lt;br /&gt;                    String.Format&lt;font color="#993300"&gt;("Predicate indicated success for value: {0}"&lt;/font&gt;, t));&lt;br /&gt;                &lt;font color="#0000ff"&gt;yield return&lt;/font&gt; t;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/font&gt;&lt;/div&gt;
&lt;p&gt;This method is almost identical to the theoretical version of Where we built above.  The only differences are that it extends &lt;font face="Courier New"&gt;IList&amp;lt;T&amp;gt;&lt;/font&gt; instead of &lt;font face="Courier New"&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/font&gt; and that it logs when the predicate finds a match prior to yielding the matched item.&lt;/p&gt;
&lt;p&gt;Now let’s put together a little snippet that will exercise this extension method.  We can actually use the first sample we used in this post and by simply adding &lt;font face="Courier New"&gt;ToList()&lt;/font&gt; to the end of &lt;font face="Courier New"&gt;Enumerable.Range(1,9)&lt;/font&gt; we’ll be calling our extension method for &lt;font face="Courier New"&gt;Where()&lt;/font&gt; instead of the built-in System.Linq version.  Let’s look at that sample:&lt;/p&gt;
&lt;div style="BORDER-RIGHT: #444444 1px solid; PADDING-RIGHT: 3px; BORDER-TOP: #444444 1px solid; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; BORDER-LEFT: #444444 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #444444 1px solid; BACKGROUND-COLOR: #ffffdd"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;from&lt;/font&gt; num &lt;font color="#0000ff"&gt;in&lt;/font&gt; Enumerable.Range(&lt;font color="#c81efa"&gt;1&lt;/font&gt;,&lt;font color="#c81efa"&gt;9&lt;/font&gt;).ToList()&lt;br /&gt;&lt;font color="#0000ff"&gt;where&lt;/font&gt; num % &lt;font color="#c81efa"&gt;2&lt;/font&gt; == &lt;font color="#c81efa"&gt;0&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;select&lt;/font&gt; num&lt;/font&gt;&lt;/div&gt;
&lt;p&gt;By simply adding the &lt;font face="Courier New"&gt;ToList()&lt;/font&gt; to the sample above we’ve caused the compiler to call our new &lt;font face="Courier New"&gt;Where()&lt;/font&gt; method.  This gives a pretty clear idea of how LINQ is working internally and what’s actually going on when we use the new C# 3.0 language keywords.  There is a lot less voodoo involved in the process that one might first believe!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example Listing&lt;/strong&gt;&lt;br /&gt;The following is a complete example suitable for pasting into &lt;a href="http://www.sliver.com/dotnet/SnippetCompiler/"&gt;snippet compiler&lt;/a&gt;:&lt;/p&gt;
&lt;div style="BORDER-RIGHT: #444444 1px solid; PADDING-RIGHT: 3px; BORDER-TOP: #444444 1px solid; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; BORDER-LEFT: #444444 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #444444 1px solid; BACKGROUND-COLOR: #ffffdd"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt; System;&lt;br /&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt; System.Collections.Generic;&lt;br /&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt; System.Linq;&lt;/font&gt; 
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;public class&lt;/font&gt; MyClass&lt;br /&gt;{&lt;br /&gt;    &lt;font color="#0000ff"&gt;public static void&lt;/font&gt; RunSnippet()&lt;br /&gt;    {&lt;br /&gt;        Console.WriteLine(&lt;font color="#993300"&gt;"Results using the IEnumerable&amp;lt;T&amp;gt;.Where() method from System.Linq."&lt;/font&gt;);&lt;br /&gt;        &lt;font color="#0000ff"&gt;var&lt;/font&gt; enumResults = &lt;br /&gt;            &lt;font color="#0000ff"&gt;from&lt;/font&gt; n &lt;font color="#0000ff"&gt;in&lt;/font&gt; Enumerable.Range(&lt;font color="#993300"&gt;1&lt;/font&gt;,&lt;font color="#993300"&gt;9&lt;/font&gt;)&lt;br /&gt;            &lt;font color="#0000ff"&gt;where&lt;/font&gt; n % 2 == 0&lt;br /&gt;            &lt;font color="#0000ff"&gt;select&lt;/font&gt; n;&lt;br /&gt;        &lt;font color="#0000ff"&gt;foreach&lt;/font&gt; (&lt;font color="#0000ff"&gt;int&lt;/font&gt; n &lt;font color="#0000ff"&gt;in&lt;/font&gt; enumResults)&lt;br /&gt;            Console.WriteLine(n);&lt;br /&gt;        &lt;br /&gt;        Console.WriteLine(&lt;font color="#993300"&gt;"Results using the custom IList&amp;lt;T&amp;gt;.Where() method from this sample."&lt;/font&gt;);&lt;br /&gt;        &lt;font color="#0000ff"&gt;var&lt;/font&gt; listResults = &lt;br /&gt;            &lt;font color="#0000ff"&gt;from&lt;/font&gt; n &lt;font color="#0000ff"&gt;in&lt;/font&gt; Enumerable.Range(&lt;font color="#993300"&gt;1&lt;/font&gt;,&lt;font color="#993300"&gt;9&lt;/font&gt;).ToList()&lt;br /&gt;            &lt;font color="#0000ff"&gt;where&lt;/font&gt; n % 2 == 0&lt;br /&gt;            &lt;font color="#0000ff"&gt;select&lt;/font&gt; n;&lt;br /&gt;        &lt;font color="#0000ff"&gt;foreach&lt;/font&gt; (&lt;font color="#0000ff"&gt;int&lt;/font&gt; n &lt;font color="#0000ff"&gt;in&lt;/font&gt; listResults)&lt;br /&gt;            Console.WriteLine(n);&lt;br /&gt;    }&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;    &lt;br /&gt;    &lt;br /&gt;    &lt;font color="#0000ff"&gt;#region&lt;/font&gt; Helper methods&lt;br /&gt;    &lt;br /&gt;    &lt;font color="#0000ff"&gt;public static void&lt;/font&gt; Main()&lt;br /&gt;    {&lt;br /&gt;        &lt;font color="#0000ff"&gt;try&lt;/font&gt;&lt;br /&gt;        {&lt;br /&gt;            RunSnippet();&lt;br /&gt;        }&lt;br /&gt;        &lt;font color="#0000ff"&gt;catch&lt;/font&gt; (Exception e)&lt;br /&gt;        {&lt;br /&gt;            &lt;font color="#0000ff"&gt;string&lt;/font&gt; error = &lt;font color="#0000ff"&gt;string&lt;/font&gt;.Format(&lt;font color="#993300"&gt;"---\nThe following error occurred while executing the snippet:\n{0}\n---"&lt;/font&gt;, e.ToString());&lt;br /&gt;            Console.WriteLine(error);&lt;br /&gt;        }&lt;br /&gt;        &lt;font color="#0000ff"&gt;finally&lt;/font&gt;&lt;br /&gt;        {&lt;br /&gt;            Console.Write(&lt;font color="#993300"&gt;"Press any key to continue..."&lt;/font&gt;);&lt;br /&gt;            Console.ReadKey();&lt;br /&gt;        }&lt;br /&gt;    }&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;    &lt;font color="#0000ff"&gt;private static void&lt;/font&gt; WL(&lt;font color="#0000ff"&gt;object&lt;/font&gt; text, &lt;font color="#0000ff"&gt;params&lt;/font&gt; &lt;font color="#0000ff"&gt;object&lt;/font&gt;[] args)&lt;br /&gt;    {&lt;br /&gt;        Console.WriteLine(text.ToString(), args);    &lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;font color="#0000ff"&gt;private static void&lt;/font&gt; RL()&lt;br /&gt;    {&lt;br /&gt;        Console.ReadLine();    &lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;font color="#0000ff"&gt;private static void&lt;/font&gt; Break() &lt;br /&gt;    {&lt;br /&gt;        System.Diagnostics.Debugger.Break();&lt;br /&gt;    }&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;    &lt;font color="#0000ff"&gt;#endregion&lt;br /&gt;&lt;/font&gt;}&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;public static class&lt;/font&gt; ListExtensions&lt;br /&gt;{&lt;br /&gt;    &lt;font color="#0000ff"&gt;public static&lt;/font&gt; IEnumerable&amp;lt;T&amp;gt; Where&amp;lt;T&amp;gt;(&lt;font color="#0000ff"&gt;this&lt;/font&gt; IList&amp;lt;T&amp;gt; source, Func&amp;lt;T, &lt;font color="#0000ff"&gt;bool&lt;/font&gt;&amp;gt; predicate)&lt;br /&gt;    {&lt;br /&gt;        &lt;font color="#0000ff"&gt;foreach&lt;/font&gt; (T t &lt;font color="#0000ff"&gt;in&lt;/font&gt; source)&lt;br /&gt;        {&lt;br /&gt;            &lt;font color="#0000ff"&gt;if&lt;/font&gt; (predicate.Invoke(t) == &lt;font color="#0000ff"&gt;true&lt;/font&gt;)&lt;br /&gt;            {&lt;br /&gt;                Console.WriteLine(String.Format(&lt;font color="#993300"&gt;"Predicate indicated success for value: {0}"&lt;/font&gt;, t));&lt;br /&gt;                &lt;font color="#0000ff"&gt;yield return&lt;/font&gt; t;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/100.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>Bluetooth Retro Handset</title><link>http://blogs.sftsrc.com/stuart/archive/2008/07/10/99.aspx</link><pubDate>Thu, 10 Jul 2008 19:45:19 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2008/07/10/99.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/99.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/99.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2008/07/10/99.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/99.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Bluetooth Retro Handset</source><description>&lt;p&gt;Here’s one for all the folks who had a hard time letting go of “the way things used to be”:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.thinkgeek.com/gadgets/cellphone/8928/"&gt;ThinkGeek Bluetooth Retro Handset&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/99.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>Deeper Project Visibility - with NDepend</title><link>http://blogs.sftsrc.com/stuart/archive/2008/07/10/98.aspx</link><pubDate>Thu, 10 Jul 2008 18:21:54 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2008/07/10/98.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/98.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/98.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2008/07/10/98.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/98.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Deeper Project Visibility - with NDepend</source><description>&lt;p&gt;Software projects, by nature, have a propensity for getting out of hand.  No matter how tightly we adhere to our carefully crafted development processes, despite diligent and methodical software designing and refactoring, the elusive software project always seems to manage to get away from us and mask its true nature from our prying eyes.  Something close to a bajillion dollars has probably already been spent in attempts to tame the software project and convince it to open up and reveal its inner secrets and with increasing success.  It has certainly been my experience that the software projects I’ve worked on in the last five years are much more transparent than they were fifteen years ago.  This is in no small part due to the fact that I am no longer a teenager banging out Win32 applications in Borland C++, stumbling my way through APIs until an acceptable solution to the problem in hand somehow occurred.  However, the view that software projects are becoming increasingly transparent is also shared by my peers.  The general consensus is that the tools and development environments have played a significant role in this, a significantly larger role than the maturity or structure of the code being developed.&lt;/p&gt;
&lt;p&gt;This is the key observation that I have made in thinking about the problem of software project wrangling.  Despite advancement in the languages, environments, and tool-set, the code itself doesn’t seem to have become &lt;em&gt;significantly&lt;/em&gt; more transparent.  Bear in mind also that I am not describing the “API of complete awesomeness” that represents years of careful labor and also accounts for about 0.1% of the code developed each year.  I’m talking about the other 99.9% of “copy/paste/tweak/pray” code that represents the bulk of what you and I will be maintaining, supporting, and extending for a notable portion of your software development career.  Given this (rather lofty, sweeping, and completely personal-opinion-based) assumption, thought moves again to the area in which our wrangling efforts have advanced: the tools.  If we can’t get people to architect more elegant solutions, perhaps we can find less painful ways to pry open Pandora’s box and examine the gifts our coding predecessors have left for us.&lt;/p&gt;
&lt;p&gt;&lt;img alt="7-10-2008_NDepend_Logo" src="http://stuartthompson.net/SubTextBlog/images/stuartthompson_net/SubTextBlog/softwareengineering/7_2D10_2D2008_NDepend_Logo_small.jpg" border="0" /&gt;&lt;/p&gt;
&lt;p&gt;One tool in my arsenal for this task is &lt;a href="http://www.ndepend.com/"&gt;NDepend&lt;/a&gt;.  Tools and development styles will always be very personal.  There are tools that I use for which others find no benefit and similarly there are those tools that have been recommended to me that just don’t seem to do what I need.  However, I can highly recommend that any developer at least evaluate NDepend for their own use as it brings a rather unique perspective to the problem of analyzing even the most elusive of software projects.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What does NDepend do?&lt;/strong&gt;&lt;br /&gt;Arguably one of the most important questions to ask when evaluating any new piece of software is what it does.  Put simply, NDepend analyzes your project and tells you stuff about it that might otherwise be difficult to discover.  It breaks down a software project into its most basic components and then lets you query and visualize the sum of those components in extremely powerful ways.  NDepend provides a wide variety of features for software analysis but undoubtedly the majority of its value lies in the power of CQL.  The &lt;strong&gt;C&lt;/strong&gt;ode &lt;strong&gt;Q&lt;/strong&gt;uery &lt;strong&gt;L&lt;/strong&gt;anguage is not unlike traditional T-SQL in both syntax and the type of problem it is trying to solve.  However, where SQL is designed to query data stores, the CQL language is designed to query software project information.  This has several applications from code navigation and searching to coding quality evaluation and a whole host of standards metrics calculations.&lt;/p&gt;
&lt;p&gt;In short, NDepend provides an incredible amount of information about how your project is glued together and how every field, method, type, and assembly is structured as well as how each of those elements relates to one another.  When you first run NDepend upon a solution or set of assemblies, the amount of information that is presented can feel a little overwhelming.  However, as you start to present small problems for NDepend to solve it quickly becomes clear why all of this information is very necessary.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where do I start?&lt;/strong&gt;&lt;br /&gt;The best way to start working with NDepend is to point it at an existing set of assemblies and run an analysis.  Then we can start to pick through the individual parts of the analysis and start to benefit from the information that is presented.  For this purpose I have down-loaded the source code for an open source project called &lt;a href="http://sourceforge.net/projects/narrange/"&gt;NArrange&lt;/a&gt;.  This provides a nice publicly available solution on which to test NDepend such that the samples in this article can easily be reproduced.&lt;/p&gt;
&lt;div style="BORDER-RIGHT: #444444 1px solid; PADDING-RIGHT: 3px; BORDER-TOP: #444444 1px solid; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; BORDER-LEFT: #444444 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #444444 1px solid; BACKGROUND-COLOR: #ddddff"&gt;&lt;em&gt;&lt;font size="1"&gt;NOTE: I also recommend viewing the video tutorials on the NDepend web-site.  The getting started tutorial covers a lot of the information I present here in much more detail (and very probably with higher accuracy).  The getting started tutorial video is located &lt;/font&gt;&lt;/em&gt;&lt;a href="http://s3.amazonaws.com/NDependOnlineDemos/GettingStarted_viewlet_swf.html"&gt;&lt;em&gt;&lt;font size="1"&gt;here&lt;/font&gt;&lt;/em&gt;&lt;/a&gt;&lt;em&gt;&lt;font size="1"&gt;.&lt;/font&gt;&lt;/em&gt;&lt;/div&gt;
&lt;p&gt;&lt;u&gt;Step 1 – Download and Install NDepend Trial&lt;/u&gt;&lt;br /&gt;You can download a trial version of NDepend &lt;a href="http://www.ndepend.com/NDependDownload.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;Step 2 – Analyzing a Solution&lt;/u&gt;&lt;br /&gt;&lt;em&gt;First make sure that you build your solution, either using Visual Studio or via MSBuild or another tool.  NDepend analyses a set of assemblies rather than a project or solution.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;From the NDepend start page, select “Analyze: a set of .NET assemblies”.  This will display a file selection dialog which we will use to browse to the NArrange libraries.  I navigated to the NArrange.Tests.ConsoleApplication bin/Debug directory as this contains many of the solution assemblies that we wish to analyze.  Once we have selected a set of assemblies, NDepend will being to run its initial analysis.  This should take about 30 to 60 seconds depending upon system load and performance.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://stuartthompson.net/SubTextBlog/images/stuartthompson_net/SubTextBlog/softwareengineering/7_2D10_2D2008_NDependStartPage.jpg"&gt;&lt;img alt="7-10-2008_NDependStartPage" src="http://stuartthompson.net/SubTextBlog/images/stuartthompson_net/SubTextBlog/softwareengineering/7_2D10_2D2008_NDependStartPage_thumb.jpg" border="0" /&gt;&lt;/a&gt;   &lt;a href="http://stuartthompson.net/SubTextBlog/images/stuartthompson_net/SubTextBlog/softwareengineering/7_2D10_2D2008_NDepend_AssemblySelection.jpg"&gt;&lt;img alt="7-10-2008_NDepend_AssemblySelection" src="http://stuartthompson.net/SubTextBlog/images/stuartthompson_net/SubTextBlog/softwareengineering/7_2D10_2D2008_NDepend_AssemblySelection_thumb.jpg" border="0" /&gt;&lt;/a&gt;&lt;a href="http://stuartthompson.net/SubTextBlog/softwareengineering/7_2D10_2D2008_NDepend_SolutionSelection.jpg"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once the analysis has completed, NDepend will display the current project in its main window as well as opening a browser that contains a full analysis report.&lt;/p&gt;
&lt;p&gt;There is a tremendous amount of information in this report and it will take a while to become familiar with all of the data that is being presented.  To that end we will look at each of the sections in turn and adopt a step by step approach to understanding why this information is useful.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Analyzing the Analysis&lt;/strong&gt;&lt;br /&gt;Let’s first look at the project map (or &lt;em&gt;VisualNDepend View&lt;/em&gt;).  If you close the browser that contains the &lt;em&gt;NDepend Report&lt;/em&gt; you’ll see that the NDepend gui has been updated.  At the top is a section containing this view.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://stuartthompson.net/SubTextBlog/images/stuartthompson_net/SubTextBlog/softwareengineering/7_2D10_2D2008_ProjectMap.jpg"&gt;&lt;img alt="7-10-2008_ProjectMap" src="http://stuartthompson.net/SubTextBlog/images/stuartthompson_net/SubTextBlog/softwareengineering/7_2D10_2D2008_ProjectMap_thumb.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This looks a little like a topographical analysis of the moon with yellow writing on it.  In truth this is a lot like a lunar map except instead of showing the peaks and troughs of the moon’s surface it is showing the topography of our project.  The NArrange solution is split into several different projects, each of which compiles into an individual assembly.  The thin yellow lines separating sections of the map represent the boundaries between these assemblies.  Each of the little gray circles that fill in those yellow squares represents a group of code within that assembly.  In essence you are looking at the project as though it were arranged into states and counties.  Each county represents a type whereas each state represents an assembly that contains several of those types.  You can run your mouse over the project map and see that each gray area will turn red as you mouse over it.  Additionally, the name that gray area represents is displayed.  The purpose of this project map is to give you a visualization of the layout of the whole solution.  It also plays into a lot of the deeper analysis functions that NDepend has to offer and becomes a center-point for visualizing the &lt;strong&gt;location&lt;/strong&gt; of code in the project.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://stuartthompson.net/SubTextBlog/images/stuartthompson_net/SubTextBlog/softwareengineering/7_2D10_2D2008_NavigatingTheVisualView.jpg"&gt;&lt;img alt="7-10-2008_NavigatingTheVisualView" src="http://stuartthompson.net/SubTextBlog/images/stuartthompson_net/SubTextBlog/softwareengineering/7_2D10_2D2008_NavigatingTheVisualView_thumb.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Start by clicking on one of the gray areas.  Note how the class browser window to the left is updated when an area is clicked.  This allows you to navigate your code visually while seeing the familiar class browser tree-view for the selected code element.  Alternatively you can click on a method or type in the class browser and see the visual view update by highlighting the appropriate area of the map.  Selecting an assembly in the class browser will highlight that entire assembly in the visual view pane.  The class browser gives a very zoomed in perspective of your project, whereas the visual view gives a fully zoomed out view of how a particular element relates to the other elements in the full solution.  I find a combination of the two to be a very powerful and expedient way to navigate a solution.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Abstractness vs Instability&lt;/strong&gt;&lt;br /&gt;Lets open the report that was generated after the initial analysis again.  To do this we can click the &lt;img alt="7-10-2008_ViewReportButton" src="http://stuartthompson.net/SubTextBlog/images/stuartthompson_net/SubTextBlog/softwareengineering/7_2D10_2D2008_ViewReportButton.jpg" border="0" /&gt; button at the top of the &lt;em&gt;Home&lt;/em&gt; ribbon.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://stuartthompson.net/SubTextBlog/images/stuartthompson_net/SubTextBlog/softwareengineering/7_2D10_2D2008_ViewReport.jpg"&gt;&lt;img alt="7-10-2008_ViewReport" src="http://stuartthompson.net/SubTextBlog/images/stuartthompson_net/SubTextBlog/softwareengineering/7_2D10_2D2008_ViewReport_thumb.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The set of links at the top of the report allow you to navigate the report contents.  Click the &lt;em&gt;Assemblies Abstractness vs. Instability&lt;/em&gt; link to be taken to a graph that pinpoints this information for each assembly that was analyzed.  This graph contains two major zones of pain and uselessness, leaving a sweet spot in the middle.  Assemblies that are both abstract and unstable live at the top-right of the graph, in the zone of uselessness.  This is to indicate that pairing abstractness with instability serves little purpose.  Assemblies in the bottom-left of the graph are very stable and tightly concrete.  This can lead to significant pain when they are maintained or extended as they are so tightly coupled and interwoven that making even small changes can require significant effort.  The sweet spot in the middle represents the correct balance between abstraction and stability.  This can be a good visual aid when learning new code or revisiting code you haven’t touched for a long time.  The pain points and potential pitfalls are identified quickly.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://stuartthompson.net/SubTextBlog/images/stuartthompson_net/SubTextBlog/softwareengineering/7_2D10_2D2008_AbstractnessVsInstability.jpg"&gt;&lt;img alt="7-10-2008_AbstractnessVsInstability" src="http://stuartthompson.net/SubTextBlog/images/stuartthompson_net/SubTextBlog/softwareengineering/7_2D10_2D2008_AbstractnessVsInstability_thumb.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In this graph we can see that the NArrange assemblies are sitting firmly in the green zone.  The &lt;em&gt;NArrange.Core&lt;/em&gt; assembly is the most abstract of the bunch but is also just stable enough to balance that level of abstraction.  It is expected that most test assemblies will cluster in the bottom right area of the graph, which is not a bad place to be.  Most test assemblies are fairly unstable and employ no abstraction as they are intended only for the purpose of testing a single type or set of known methods.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Additional Resources&lt;/strong&gt;&lt;br /&gt;This &lt;strong&gt;very&lt;/strong&gt; brief overview was intended to scratch the surface of NDepend and give a feel for what this tool is trying to accomplish.  I’m working on more articles around the excellent CQL language and deeper features of NDepend.  These articles will be the basis of a training for some brown bags as well as the source material for more blog posts on this topic.  Meanwhile, here are some resources that are other great starting points for learning more about this great tool.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://visualstuart.net/blog/"&gt;Stuart Celarier&lt;/a&gt; put together an excellent cheat sheet for NDepend that can be found &lt;a href="http://www.hanselman.com/blog/content/binary/NDepend%20metrics%20placemats%201.1.pdf"&gt;here&lt;/a&gt;.  This is one of those sheets you just want to print out, laminate and either hang on the wall or find a place on your desk, perhaps even as a mouse mat.&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://www.ndepend.com/"&gt;NDepend&lt;/a&gt; website contains a great series of videos and articles to help &lt;a href="http://www.ndepend.com/GettingStarted.aspx"&gt;get started.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Other than that, one of the best ways to learn the tool is to simply install it and then start poking around with the analysis and learning by using.  Analyze your current project assemblies and then start navigating using the NDepend interface.  Play with some of the CQL queries (it will make reading future articles on CQL simpler because you’ll be more familiar).  Make sure to install the VisualStudio and Reflector addons as these make full circle integration a part of your life.  Other than that, I look forward to putting together my next NDepend article on using CQL to really understand and learn about how your code is put together and where it can be improved.&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/98.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>HttpRequest</title><link>http://blogs.sftsrc.com/stuart/archive/2008/07/09/97.aspx</link><pubDate>Wed, 09 Jul 2008 18:21:20 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2008/07/09/97.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/97.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/97.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2008/07/09/97.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/97.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">HttpRequest</source><description>&lt;p&gt;Have you ever wondered how an HttpRequest ends up returning a particular header code such as &lt;em&gt;500 Internal Server Error&lt;/em&gt; or &lt;em&gt;401 Unauthorized&lt;/em&gt;?  This handy chart walks you through the entire request flow:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://thoughtpad.net/alan-dean/http-headers-status.jpg"&gt;HttpRequest Flow Diagram - (Courtesy Thoughtpad)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I think I’m going to print this out and hang it on the wall.&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/97.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>New Array of Anonymous Objects</title><link>http://blogs.sftsrc.com/stuart/archive/2008/07/09/96.aspx</link><pubDate>Wed, 09 Jul 2008 18:08:57 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2008/07/09/96.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/96.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/96.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2008/07/09/96.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/96.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">New Array of Anonymous Objects</source><description>&lt;p&gt;While coding up a couple of prototype LINQ queries this morning I came across a rather interesting syntax using anonymous types and object initializers.  I wanted to show an example of using a where clause upon a property of an object but didn’t want to put a bunch of plumbing around it just to set up the example.  In my head an array containing three &lt;em&gt;Person&lt;/em&gt; objects would suffice, with each person object having &lt;em&gt;Name &lt;/em&gt;and &lt;em&gt;Age&lt;/em&gt; properties that I could use in my query.  I wasn’t sure if this would compile but dropped it into the wonderful &lt;a href="http://www.linqpad.net/"&gt;LinqPad&lt;/a&gt; and sure enough found that it compiled right away, giving me exactly the results I was looking for.&lt;/p&gt;
&lt;p style="BORDER-RIGHT: #444444 1px solid; PADDING-RIGHT: 3px; BORDER-TOP: #444444 1px solid; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; BORDER-LEFT: #444444 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #444444 1px solid; BACKGROUND-COLOR: #ffffdd"&gt;&lt;font color="#0000ff"&gt;from&lt;/font&gt; person &lt;font color="#0000ff"&gt;in new&lt;/font&gt; [] {&lt;br /&gt;    &lt;font color="#0000ff"&gt;new&lt;/font&gt; { Name=&lt;font color="#993300"&gt;"Bob"&lt;/font&gt;, Age=&lt;font color="#993300"&gt;28&lt;/font&gt; }, &lt;br /&gt;    &lt;font color="#0000ff"&gt;new&lt;/font&gt; { Name=&lt;font color="#993300"&gt;"Ted"&lt;/font&gt;, Age=&lt;font color="#993300"&gt;22&lt;/font&gt; } &lt;br /&gt;    &lt;font color="#0000ff"&gt;new&lt;/font&gt; { Name=&lt;font color="#993300"&gt;"Sally"&lt;/font&gt;, Age=&lt;font color="#993300"&gt;25&lt;/font&gt; } }&lt;br /&gt;&lt;font color="#0000ff"&gt;where&lt;/font&gt; person.Age &amp;lt; &lt;font color="#993300"&gt;26&lt;/font&gt; &lt;br /&gt;&lt;font color="#0000ff"&gt;select&lt;/font&gt; person &lt;/p&gt;I can declare a &lt;font color="#0000ff"&gt;new&lt;/font&gt; [] { &lt;em&gt;&lt;font color="#808080"&gt;&amp;lt;set of anonymous types&amp;gt;&lt;/font&gt;&lt;/em&gt; } right there in the query, saving me the job of creating all of the plumbing around it just for the sake of the sample.  Cool!&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/96.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item><item><title>Snippet Compiler</title><link>http://blogs.sftsrc.com/stuart/archive/2008/07/07/95.aspx</link><pubDate>Mon, 07 Jul 2008 19:24:31 GMT</pubDate><guid isPermaLink="true">http://blogs.sftsrc.com/stuart/archive/2008/07/07/95.aspx</guid><wfw:comment>http://blogs.sftsrc.com/stuart/comments/95.aspx</wfw:comment><wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/95.aspx</wfw:commentRss><comments>http://blogs.sftsrc.com/stuart/archive/2008/07/07/95.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blogs.sftsrc.com/stuart/services/trackbacks/95.aspx</trackback:ping><source url="http://blogs.sftsrc.com/stuart/rss.aspx">Snippet Compiler</source><description>&lt;p&gt; If you haven't used Snippet Compiler before, I highly recommend you take the 60 seconds necessary to download and evaluate it.  If you're anything like me it will instantly become an indispensable part of your development toolbox.  I've been using Snippet Compiler for over three years now and can't imagine development life without it. &lt;/p&gt;
&lt;p style="color: rgb(0, 0, 255);"&gt; &lt;a href="http://www.sliver.com/dotnet/SnippetCompiler/"&gt;You can download Snippet Compiler here.&lt;/a&gt; &lt;/p&gt;
&lt;p&gt; For those skeptics out there who would prefer to know what they are downloading first, just imagine a tool where you could type out snippets of C# to test a certain idea and have it compile into a simple wrapper app that executes your snippet.  Every time you've created a throw away web application or web form to test out a certain idea you've experienced a need for Snippet Compiler.  It does the framework piece for you so that you can do that test with try catch finally you've always wanted the answer to. :) &lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/95.aspx" width="1" height="1" /&gt;</description><dc:creator>Stuart Thompson</dc:creator></item></channel></rss>