<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-2370549018150398400</atom:id><lastBuildDate>Thu, 05 Nov 2009 18:30:21 +0000</lastBuildDate><title>This Code Goes to Eleven</title><description>Refactoring 10 to be louder just didn't cut it.</description><link>http://codeeleven.blogspot.com/</link><managingEditor>noreply@blogger.com (Jonathan Holland)</managingEditor><generator>Blogger</generator><openSearch:totalResults>31</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/ThisCodeGoesToEleven" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-6928571404226290034</guid><pubDate>Tue, 27 Jan 2009 14:37:00 +0000</pubDate><atom:updated>2009-01-27T06:38:41.748-08:00</atom:updated><title>Moving from Blogger to my own server</title><description>I have relocated the blog to my own custom server.&lt;br /&gt;&lt;br /&gt;From now on, you will be able to follow this blog at:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.gfilter.net/"&gt;http://www.gfilter.net&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-6928571404226290034?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2009/01/moving-from-blogger-to-my-own-server.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">9</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-6295132006130471515</guid><pubDate>Sun, 11 Jan 2009 21:01:00 +0000</pubDate><atom:updated>2009-01-11T20:13:21.242-08:00</atom:updated><title>Graphing Reddit Language Preferences</title><description>&lt;a href="http://www.reddit.com/r/programming"&gt;Programming Reddit&lt;/a&gt; recently had a &lt;a href="http://www.reddit.com/r/programming/comments/7oxgv/proggit_what_"&gt;survey of "favorite" languages&lt;/a&gt; with some surprising results.&lt;br /&gt;&lt;br /&gt;I took the time to enter each "positive mention" of a language into Google Spreadsheet (I also wanted to play with that, I'm mildly impressed though its charting ability is weak at best.)&lt;br /&gt;&lt;br /&gt;Results (Click for large image):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://spreadsheets.google.com/pub?key=pjAsAf-oAfr1RYx7HBUu7YA&amp;oid=1&amp;output=image"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 500px; height: 300px;" src="http://spreadsheets.google.com/pub?key=pjAsAf-oAfr1RYx7HBUu7YA&amp;oid=1&amp;output=image" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;An interesting trend has developed here. I found that the the most maligned languages on Reddit had surprisingly high showings in this thread. C#, Java, C++, and Perl all ranked much higher than the more esoteric languages that are often advocated there.&lt;br /&gt;&lt;br /&gt;Pythons current place at 2nd place is no surprise, and it is well deserved, but I was very surprised by the large showing of C# developers. They seemed to come out of the woodwork. The usual anti C# trolls actually made no showing at all, further convincing me that they aren't actually serious programmers regardless.&lt;br /&gt;&lt;br /&gt;When you remove all of the languages that received less than 3 honorable mentions, It is easy to see that the massive majority of Reddit users prefer C#, Python, and C.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://spreadsheets.google.com/pub?key=pjAsAf-oAfr1RYx7HBUu7YA&amp;oid=2&amp;output=image"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 500px; height: 308px;" src="http://spreadsheets.google.com/pub?key=pjAsAf-oAfr1RYx7HBUu7YA&amp;oid=2&amp;output=image" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Not the often praised Haskell, Erlang, Scala or Lisp, but regular "get work done" languages. &lt;del&gt;This is a great thing, and shows a resurgence of actual developers to Reddit, and not head-in-the-clouds academics.&lt;/del&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Edit:&lt;/b&gt; The above sentence appeared to be misinterpreted by all, so I thought I'd clarify.&lt;br /&gt;&lt;br /&gt;I'm happy to see other people with similar interests as me, people who actually write the software the world uses, as opposed to the people who invent the tools necessary to write the software. Huge respect to academics, but as a software developer, and not computer scientist, I am happy to find others of a like mind.&lt;br /&gt;&lt;br /&gt;In my world, I don't have 15 years to invent a compiler, I have 6 months to get from business case to shipped. I sometimes consider academics as out of touch with the realities of commercial business, hence the "head-in-the-clouds" statement.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-6295132006130471515?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2009/01/graphing-reddit-language-trends.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">13</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-4617841045882709078</guid><pubDate>Sat, 26 Jul 2008 18:42:00 +0000</pubDate><atom:updated>2008-07-26T12:01:41.309-07:00</atom:updated><title>Benchmarking the CLR vrs the JVM</title><description>I've found that there are lots of flame wars regarding JVM/CLR performance, but very little solid data, so I thought I'd try running a benchmark of my own.&lt;br /&gt;&lt;br /&gt;I decided the first benchmark would be sorting using a bubble sort. The bubble sort is highly inefficient, so it is a good demonstration of memory management and integer arithmetic.&lt;br /&gt;&lt;br /&gt;I also wanted to see how well the JIT's would handle method by method optimization, so I wrote a version that used methods for each runtime, as well as a version that was entirely inline.&lt;br /&gt;&lt;br /&gt;My theory was that the inline version would prove to be slower than the method invoking versions due to JIT optimizations when calling methods. In reality, it was even more apparent. However, when I did disable the JIT optimizations on the CLR by using a debug build, the inline CLR version was much faster than the method version. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.gfilter.net/junk/BubblesortBenchmark.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px;" src="http://www.gfilter.net/junk/BubblesortBenchmark.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This data was generated on my 2.4ghz laptop running Windows XP. I used the .NET 2.0 CLR, and JRE 1.6.0.5 (Which just happened to be the one that came with Eclipse). The Y axis is milliseconds. &lt;br /&gt;&lt;br /&gt;The benchmark is performing a bubblesort on a 10,000 integer set, 100 times.&lt;br /&gt;&lt;br /&gt;It shows that the CLR is a slight winner, at least in doing these operations. The big surprise was the speed difference the JVM JIT makes when optimizing methods. &lt;br /&gt;&lt;br /&gt;Even the unoptimized CLR version was only slightly slower than the JVM.&lt;br /&gt;&lt;br /&gt;The surprising lesson learned here is that premature optimization by inlining methods and unrolling loops may actually result in slower performance on the JVM.&lt;br /&gt;&lt;br /&gt;If anyone wants to run these benchmarks on their machine, the full source is &lt;a href="http://www.gfilter.net/junk/Benchmark.zip"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-4617841045882709078?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2008/07/benchmarking-clr-vrs-jvm.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">16</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-3730510624507856391</guid><pubDate>Tue, 15 Jul 2008 16:43:00 +0000</pubDate><atom:updated>2008-07-15T10:15:04.386-07:00</atom:updated><title>Normalize First</title><description>Sometimes Jeff Atwood does more harm than good. I wonder how many people will misunderstand his &lt;a href="http://www.codinghorror.com/blog/archives/001152.html"&gt;latest post.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'm not positive that even he understands his latest post.&lt;br /&gt;&lt;br /&gt;Take a look at his example query:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;select * from Users u&lt;br /&gt;inner join UserPhoneNumbers upn&lt;br /&gt;on u.user_id = upn.user_id&lt;br /&gt;inner join UserScreenNames usn&lt;br /&gt;on u.user_id = usn.user_id&lt;br /&gt;inner join UserAffiliations ua&lt;br /&gt;on u.user_id = ua.user_id&lt;br /&gt;inner join Affiliations a&lt;br /&gt;on a.affiliation_id = ua.affiliation_id&lt;br /&gt;inner join UserWorkHistory uwh&lt;br /&gt;on u.user_id = uwh.user_id&lt;br /&gt;inner join Affiliations wa&lt;br /&gt;on uwh.affiliation_id = wa.affiliation_id&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;He argues that using 6 joins to pull together data on users is excessive, while missing the true point that 3NF (Then again, his "normalized schema" isn't even 2NF) enforces data integrity and ease of maintenance, not performance.&lt;br /&gt;&lt;br /&gt;(Also, his join returns a boatload of duplicate data)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Normalize first. Denormalize only when its the last resort.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The scary thing is that people are going to read Atwood and then decide that their 200 column mega table is a good idea.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-3730510624507856391?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2008/07/normalize-first.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">11</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-6616964449135782177</guid><pubDate>Thu, 24 Apr 2008 18:02:00 +0000</pubDate><atom:updated>2008-04-24T12:10:10.208-07:00</atom:updated><title>Its always Windows fault!</title><description>&lt;a href="http://www.codinghorror.com/blog/archives/001105.html"&gt;Jeff Atwood&lt;/a&gt; has been providing me with a lot of blogging material lately, I want to revisit his article that I talked about yesterday to study something that amused me greatly.&lt;br /&gt;&lt;br /&gt;The common knee jerk reaction to Jeff's abysmal PHP/Wordpress statistics was that it was Windows fault, because he was running the site on a virtualized Server 2008 using IIS7.&lt;br /&gt;&lt;br /&gt;As everyone knows, IIS is a horrible web server, the worst ever made, and Windows Server is really just a desktop OS with a fancy name and a higher price tag...Right?&lt;br /&gt;&lt;br /&gt;This sort of knee jerk reaction is dangerous, because not only is it incorrect (How would the platform affect the number of queries being performed), but it also makes the commenter look, to put it nicely...stupid.&lt;br /&gt;&lt;br /&gt;But, I was curious. I wanted to see how fast PHP was on IIS7, and I wanted to see some benchmarks of mySQL running on Windows versus mySQL running Linux.&lt;br /&gt;&lt;br /&gt;However, I couldn't find any good benchmark results on mySQL. I found some interesting comparisons of mySQL versus SQLServer running on Windows (Guess who wins by a mile?), but it seems like nobody wants to run benchmarks between platforms. If you have or know of a benchmark, post it.&lt;br /&gt;&lt;br /&gt;As far as PHP's performance on IIS7, it is actually very fast, when configured correctly.&lt;br /&gt;&lt;br /&gt;I'm lifting some benchmarks from &lt;a href="http://blogs.iis.net/bills/archive/2006/10/31/PHP-on-IIS.aspx"&gt;Bills IIS blog&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Here is PHP running through ISAPI, which means that IIS will multi thread it like it does ASP.NET. This can be somewhat unstable because a lot of PHP code is not written to be ran on multiple threads. This is pretty much how PHP runs on IIS6.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_I914lDmRUzA/SBDYfESc6DI/AAAAAAAAAA4/ynbHxV3jVq4/s1600-h/phpIsapiPerf.jpg.img.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_I914lDmRUzA/SBDYfESc6DI/AAAAAAAAAA4/ynbHxV3jVq4/s400/phpIsapiPerf.jpg.img.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5192888398596859954" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can see that on Bills Vista laptop, he is getting about 60 requests per second. Not bad for just running on a dev box considering he is running the client software and the server on the same box. I'd say its safe to double every number he produces for a "in the wild" benchmark.&lt;br /&gt;&lt;br /&gt;However, IIS7 now supports fastCGI, so lets rerun that benchmark using fastCGI. This will also be more stable, because it will be running on a single fastCGI thread.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_I914lDmRUzA/SBDZZ0Sc6FI/AAAAAAAAABI/h7gOSHCTz9g/s1600-h/fastCGIPerf.JPG.img.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_I914lDmRUzA/SBDZZ0Sc6FI/AAAAAAAAABI/h7gOSHCTz9g/s400/fastCGIPerf.JPG.img.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5192889407914174546" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;With fastCGI setup, Bills little dev laptop is now pushing over 100 RPS. Not bad at all (again considering he is running the client software on the same CPU as the server), but we can do a LOT better.&lt;br /&gt;&lt;br /&gt;IIS7 has kernel level caching abilities, so lets go ahead and enable that:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_I914lDmRUzA/SBDaIUSc6GI/AAAAAAAAABQ/yEEQwEXM5rc/s1600-h/kernelCache.jpg.img.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_I914lDmRUzA/SBDaIUSc6GI/AAAAAAAAABQ/yEEQwEXM5rc/s400/kernelCache.jpg.img.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5192890206778091618" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Notice that the scale of the graph has changed. This little laptop is now handling 6,000 RPS. I'm a little impressed with IIS7, you should be to :)&lt;br /&gt;&lt;br /&gt;So we can rule out PHP/Windows as being the slow culprit, and we are on the fence if mySQL is slower on windows. I'm waiting for proof on that.&lt;br /&gt;&lt;br /&gt;All this said, it will do nothing to prevent the knee jerk reaction of nonsense that is so prevalent on online communities. You can fight ignorance all you want, but I guess you can't fix stupid.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-6616964449135782177?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2008/04/its-always-windows-fault.html</link><author>noreply@blogger.com (Jonathan Holland)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_I914lDmRUzA/SBDYfESc6DI/AAAAAAAAAA4/ynbHxV3jVq4/s72-c/phpIsapiPerf.jpg.img.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-5878834035101416152</guid><pubDate>Wed, 23 Apr 2008 17:24:00 +0000</pubDate><atom:updated>2008-04-23T14:25:21.808-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">FOSS at its finest</category><title>Why Relational Databases end up being the bottleneck</title><description>These days it is all the rage to diss on RDBMS. Just surf over to Digg or Reddit and you'll see lots of the following:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;They don't scale well&lt;/li&gt;&lt;br /&gt;&lt;li&gt;There is relational/object impedance problems&lt;/li&gt;&lt;br /&gt;&lt;li&gt;They use massive amounts of CPU time&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Performing table joins is slow&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;The list could go on and on. All of the cool kids are hyping new non relational databases such as SimpleDB and CouchDB, or even Googles BigTable.&lt;br /&gt;&lt;br /&gt;I'm not in that camp. I do understand the shortcomings of a relational database, but I also know its strengths. &lt;br /&gt;&lt;br /&gt;Personally, I don't use mySQL, and use SQL Server for my projects, and I have yet to have a scaling issue with it, so I didn't understand why people always claim that the database is the bottleneck in their application.&lt;br /&gt;&lt;br /&gt;However, I finally understood because today Jeff Atwood &lt;a href="http://www.codinghorror.com/blog/archives/001105.html"&gt;blogged&lt;/a&gt; about Wordpress (One of the flagship LAMP products).&lt;br /&gt;&lt;br /&gt;Wordpress in its unpatched and default state performs &lt;b&gt;20&lt;/b&gt; queries to retrieve the posts on the front page.&lt;br /&gt;&lt;br /&gt;In comparison, &lt;a href="http://codeeleven.blogspot.com/2007/12/hidden-orm-tax-and-why-profiling-is.html"&gt;Codeblog performs &lt;b&gt;4&lt;/b&gt;&lt;/a&gt;, and I was unhappy with that, but that was due to trying SubSonic out instead of hand rolling my own database layer.&lt;br /&gt;&lt;br /&gt;So, I gave Wordpress the benefit of the doubt, those 20 queries must be important right?&lt;br /&gt;&lt;br /&gt;Wrong again, take this example from WordPress.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SELECT SQL_CALC_FOUND_ROWS  wp_posts.* &lt;br /&gt;FROM wp_posts  &lt;br /&gt;WHERE 1=1  &lt;br /&gt;AND wp_posts.post_type = 'post' &lt;br /&gt;AND (wp_posts.post_status = 'publish')  &lt;br /&gt;ORDER BY wp_posts.post_date DESC LIMIT 0, 10&lt;br /&gt;&lt;br /&gt;And then:&lt;br /&gt;&lt;br /&gt;SELECT FOUND_ROWS()&lt;br /&gt;&lt;br /&gt;And then:&lt;br /&gt;&lt;br /&gt;SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE &lt;br /&gt;post_id IN (3,1) ORDER BY post_id, meta_key&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Can you count the WTF's there? Did the authors have no clue about normalization and writing efficient joins? There are no relationships between posts, comments and authors, instead they just keep mindlessly querying away. &lt;br /&gt;&lt;br /&gt;Of course, the saddest part is that the solution is not to fix their database, its to instead install a caching plug in to hide the fact that their database and supporting code &lt;b&gt;SUCKS&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;The bottom line is don't tell me RDMBS can't scale if you can't write a decent query or design a normalized database schema. &lt;br /&gt;&lt;br /&gt;Unless you are performing a complex 10 table join, its will still be cheaper than opening 10 database connections and then sorting it all out in your code.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Relational databases are not the bottleneck.&lt;/b&gt; Crappy programmers are, which is what I suspected all along.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-5878834035101416152?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2008/04/why-relational-databases-end-up-being.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">50</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-1123633479044797353</guid><pubDate>Fri, 11 Apr 2008 02:33:00 +0000</pubDate><atom:updated>2008-04-10T19:38:16.900-07:00</atom:updated><title>GFilter open beta</title><description>GFilter has been a small project that I began this week, and I am now opening up for beta. Please drop any bug reports as a comment here.&lt;br /&gt;&lt;br /&gt;The concept behind GFilter is simple. GFilter allows you to create a personal blacklist of sites that you do not want to show up when you search the internet. This means no more Experts Exchange when you are trying to find a handy regular expression etc...&lt;br /&gt;&lt;br /&gt;Additionally, sites that are especially unpopular across users will be automatically removed from any search, so the collective force of GFilter users will sanitize the web.&lt;br /&gt;&lt;br /&gt;Try it out, stick as your homepage for a few days and drop me a note with any defects/suggestions. This is an experimental project designed just for fun!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.gfilter.net"&gt;http://www.gfilter.net&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As a side note, I desperately need a designer to come up with a good logo for this, the cliche web 2.0 logo works fine as a placeholder, but it needs to go now :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-1123633479044797353?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2008/04/gfilter-open-beta.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-1535922297871167754</guid><pubDate>Mon, 24 Mar 2008 19:58:00 +0000</pubDate><atom:updated>2008-03-24T13:42:36.755-07:00</atom:updated><title>Domain Objects and DataReaders</title><description>Its been a very long time since I've written on this page, but it has not been because I am lazy.&lt;br /&gt;&lt;br /&gt;Being a .NET developer, I try to give back to the community as much as I can, but the internet as a whole is rather critical of us .NET developers, and sometimes maintaining a blog can be a rather thankless and frustrating experience.&lt;br /&gt;&lt;br /&gt;I decided to take some time off from blogging, to tackle a handful of difficult programming projects and to come back when I was feeling more refreshed.&lt;br /&gt;&lt;br /&gt;I have been working on an application framework for some time, and I thought that a small snippet from that would be beneficial to my readers.&lt;br /&gt;&lt;br /&gt;A common practice when designing a N-tiered framework is to create custom domain (or business) objects that are responsible for populating themselves from raw datareaders.&lt;br /&gt;&lt;br /&gt;For example, you may have a database table that represents a "Customer". This approach would create an object that models the table schema as a strongly typed class. My usual technique to populate such a class is to pass a database row in the form of a IDataReader to the class constructor.&lt;br /&gt;&lt;br /&gt;However, you almost always end up in a scenario where the stored procedure that is ultimately responsible for the creation of the IDataReader may only return a portion of the columns that the domain object expects.&lt;br /&gt;&lt;br /&gt;Because of this, people advocate "defensive" coding techniques, where you validate the existence of each column before attempting to read and assign it to a class property.&lt;br /&gt;&lt;br /&gt;Because IDataReader (and its derivatives, such as SQLDataReader and ODBCDataReader) do not expose a "HasColumn" property, I have witnessed some creative and horrible approaches to this technique:&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red0\green0\blue0;\red163\green21\blue21;\red43\green145\blue175;}??\fs20 \cf1 try\par ??\cf0 \{\par ??    \cf1 this\cf0 .CustomerName = reader[\cf4 "CustomerName"\cf0 ].ToString();\par ??\}\par ??\cf1 catch\cf0  (\cf5 IndexOutOfRangeException\cf0 )\par ??\{\par ??    \cf1 this\cf0 .CustomerName = \cf1 string\cf0 .Empty;\par ??\}}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;try&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;{&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.CustomerName = reader[&lt;span style="color: #a31515;"&gt;"CustomerName"&lt;/span&gt;].ToString();&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;}&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;catch&lt;/span&gt; (&lt;span style="color: #2b91af;"&gt;IndexOutOfRangeException&lt;/span&gt;)&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;{&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.CustomerName = &lt;span style="color: blue;"&gt;string&lt;/span&gt;.Empty;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;}&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;Imagine this code, repeated for each column that may have been returned in the DataReader. Not only is it excessively verbose, but it violates a cardinal rule: Utilizing exceptions to control program flow. &lt;br /&gt;&lt;br /&gt;Exceptions are a good thing, but using them in this fashion is a poor design choice. Each time an exception is thrown and caught, the call stack must traversed and a great deal of overhead is added on a per column basis.&lt;br /&gt;&lt;br /&gt;Lets see if we can do better.&lt;br /&gt;&lt;br /&gt;The first order of business is to refractor the column checking logic into a static helper method. There is no need to repeat this code for each column. I already had a static Utility class in my database namespace, so I placed this method there.&lt;br /&gt;&lt;br /&gt;The second order of business is to take a page out of the TryParse notebook, and utilize an output parameter to pass our domain object variable. The new methods signature is quite obvious as to how this method will work:&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red0\green0\blue0;\red43\green145\blue175;}??\fs20 \cf1 public\cf0  \cf1 static\cf0  \cf1 void\cf0  ReadColumn(\cf1 ref\cf0  \cf4 SqlDataReader\cf0  reader, \cf1 string\cf0  columnName, \cf1 out\cf0  \cf1 string\cf0  column)}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; ReadColumn(&lt;span style="color: blue;"&gt;ref&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;SqlDataReader&lt;/span&gt; reader, &lt;span style="color: blue;"&gt;string&lt;/span&gt; columnName, &lt;span style="color: blue;"&gt;out&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; column)&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;The current SqlDataReader will be passed by reference to this method in addition to passing the desired column name and finally the actual variable used within the domain object.&lt;br /&gt;&lt;br /&gt;I created overloaded versions of this method to handle boolean, integer, string, and DateTime data types, to simplify even more the logic required in the population method.&lt;br /&gt;&lt;br /&gt;Here is an example of the string method:&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red0\green0\blue0;\red43\green145\blue175;}??\fs20 \cf1 public\cf0  \cf1 static\cf0  \cf1 void\cf0  ReadColumn(\cf1 ref\cf0  \cf4 SqlDataReader\cf0  reader, \cf1 string\cf0  columnName, \cf1 out\cf0  \cf1 string\cf0  column)\par ??\{\par ??    column = \cf1 string\cf0 .Empty;    \par ??    \cf1 if\cf0  (checkColumn(\cf1 ref\cf0  reader, columnName))\par ??    \{                \par ??        column = reader[columnName].ToString();\par ??    \}\par ??\}}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; ReadColumn(&lt;span style="color: blue;"&gt;ref&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;SqlDataReader&lt;/span&gt; reader, &lt;span style="color: blue;"&gt;string&lt;/span&gt; columnName, &lt;span style="color: blue;"&gt;out&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; column)&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;{&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; column = &lt;span style="color: blue;"&gt;string&lt;/span&gt;.Empty;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (checkColumn(&lt;span style="color: blue;"&gt;ref&lt;/span&gt; reader, columnName))&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; column = reader[columnName].ToString();&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;}&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;As you can see, this is a very simple method, and the other overloaded methods are just as simple, containing an additional TryParse call in them to ensure that they can successfully cast the columns contents into the desired data type. &lt;br /&gt;&lt;br /&gt;This leaves just one snippet of code remaining, the private helper method "checkColumn". &lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red0\green0\blue0;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf1 private\cf0  \cf1 static\cf0  \cf1 bool\cf0  checkColumn(\cf1 ref\cf0  \cf4 SqlDataReader\cf0  reader, \cf1 string\cf0  columnName)\par ??\{\par ??    reader.GetSchemaTable().DefaultView.RowFilter = \cf5 "ColumnName='"\cf0  + columnName + \cf5 "'"\cf0 ;\par ??    \cf1 return\cf0  (reader.GetSchemaTable().DefaultView.Count &amp;gt; 0);\par ??\}}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; checkColumn(&lt;span style="color: blue;"&gt;ref&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;SqlDataReader&lt;/span&gt; reader, &lt;span style="color: blue;"&gt;string&lt;/span&gt; columnName)&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;{&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; reader.GetSchemaTable().DefaultView.RowFilter = &lt;span style="color: #a31515;"&gt;"ColumnName='"&lt;/span&gt; + columnName + &lt;span style="color: #a31515;"&gt;"'"&lt;/span&gt;;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; (reader.GetSchemaTable().DefaultView.Count &amp;gt; 0);&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;}&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;IDataReader exposes a method that can return its schema in the form of a DataView object. Since DataView objects can be filtered using RowFilter, this method is able to create and filter the view by the desired column name. Finally, I check to see if there are any rows in the filtered view. This ensures that this column does exist in the DataReader.&lt;br /&gt;&lt;br /&gt;Finally, jumping back to our domain objects populate code, we can replace all of the heavy duty defensive coding code with a simple and clean method call:&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;\red0\green0\blue255;\red163\green21\blue21;}??\fs20 SQLServer.\cf3 Utility\cf0 .ReadColumn(\cf4 ref\cf0  reader, \cf5 "CustomerName"\cf0 , \cf4 out\cf0  \cf4 this\cf0 ._customerName);}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;SQLServer.&lt;span style="color: #2b91af;"&gt;Utility&lt;/span&gt;.ReadColumn(&lt;span style="color: blue;"&gt;ref&lt;/span&gt; reader, &lt;span style="color: #a31515;"&gt;"CustomerName"&lt;/span&gt;, &lt;span style="color: blue;"&gt;out&lt;/span&gt; &lt;span style="color: blue;"&gt;this&lt;/span&gt;._customerName);&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;If anyone knows of a more efficient way to do this, please let me know. I am always a fan of optimizing out inefficiencies.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-1535922297871167754?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2008/03/domain-objects-and-datareaders.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-29598421273581072</guid><pubDate>Mon, 31 Dec 2007 18:56:00 +0000</pubDate><atom:updated>2007-12-31T11:37:12.137-08:00</atom:updated><title>Software, Cellphones, and Upgrading</title><description>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.tripmywire.net/blog/wp-content/uploads/2007/09/nokia5190.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px;" src="http://www.tripmywire.net/blog/wp-content/uploads/2007/09/nokia5190.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;The wireless telecom industry has mastered marketing.&lt;br /&gt;&lt;br /&gt;They are one of the few industries that can convince people throw out a perfectly functional product every year or so, for the next years model, all the while rarely adding "must have" features, and usually shortening battery life in the process.&lt;br /&gt;&lt;br /&gt;The phone at the right, the Nokia 5190, was one of the first massively adopted cell phones. It featured digital and analog calling, good battery life, and if my memory serves me right, even text messaging.&lt;br /&gt;&lt;br /&gt;Cell Phones have a fairly singular purpose, they should make and receive phone calls, and do it well.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://cache.gizmodo.com/assets/resources/2006/10/tmobiledash.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px;" src="http://cache.gizmodo.com/assets/resources/2006/10/tmobiledash.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;Yet the Cell Industry has convinced the world that we should shell out several hundred dollars every year or so for the latest and greatest model.&lt;br /&gt;&lt;br /&gt;I tried it, I switched the Windows Mobile powered T-Mobile Dash PDA phone for a few weeks, but eventually I went back to using my old standby, a simple Samsung flip phone, because the feature bloat of the PDA phone made doing what I really wanted to do (actually calling people) more difficult than my old phone.&lt;br /&gt;&lt;br /&gt;How is it, that the wireless industry can charge more for phones that add features that most people don't use, and still be as popular as rock stars? &lt;br /&gt;&lt;br /&gt;What is the secret?&lt;br /&gt;&lt;br /&gt;Software upgrades are very similar to cell phone upgrades. Upgrading software is usually a somewhat apprehensive experience. The new version often runs slower, takes up twice the hard drive space, and adds few new features to make the upgrade worthwhile at all.&lt;br /&gt;&lt;br /&gt;Winamp and Paint Shop Pro are great examples of this.&lt;br /&gt;&lt;br /&gt;However, with a few rare exceptions (I.E. Anything produced by Apple), people only upgrade software when they absolutely have to. &lt;br /&gt;&lt;br /&gt;So I ask my readers, what is it that compels people to upgrade, and why has the software industry not figured this out?&lt;br /&gt;&lt;br /&gt;If someone does, they have the potential to be very successful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-29598421273581072?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2007/12/software-cellphones-and-upgrading.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-4068319944262489754</guid><pubDate>Thu, 27 Dec 2007 18:54:00 +0000</pubDate><atom:updated>2007-12-27T12:02:15.128-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Steve Yegge</category><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">Rhino</category><category domain="http://www.blogger.com/atom/ns#">Dynamic Languages</category><category domain="http://www.blogger.com/atom/ns#">C#</category><category domain="http://www.blogger.com/atom/ns#">Static Languages</category><title>What exactly do you save with Dynamic Languages?</title><description>Steve Yegge recently published a &lt;a href="http://steve-yegge.blogspot.com/2007/12/codes-worst-enemy.html"&gt;manifesto&lt;/a&gt; that claims that design patterns and refactoring only bloat Java code to the point of being unmaintainable. He cited his 500k LoC Java game as an example.&lt;br /&gt;&lt;br /&gt;He has since decided to rewrite his game in Rhino (Which is a JVM driven version of EcmaScript), attributing the dynamic nature of Ecmascript as superior for keeping the code base small, over a rigorously typed static language such as Java.&lt;br /&gt;&lt;br /&gt;I would never argue that Java is not a verbose language full of boilerplate code, I work with .NET, which suffers from the same phenomena.&lt;br /&gt;&lt;br /&gt;However, I will argue that Yegge is flawed when he compares total lines of code with both maintainability and complexity.&lt;br /&gt;&lt;br /&gt;Comparing snippets of Java or C# to snippets of Ruby/Perl/Python etc are decieving. Sure the dynamic languages may accomplish in one line what a static language takes 5 lines, but the static language is instantly apparent on its purpose, while the dynamic language works by using behind the scenes framework magic.&lt;br /&gt;&lt;br /&gt;Besides, if you find yourself repeating that same 5 lines over and over, then its time to apply the DRY principle and refractor it into a method. Now your static language can do exactly what the dynamic language can, and as an added advantage, you can always grok the method to see what exactly is going on. From a maintenance standpoint, this is a huge advantage.&lt;br /&gt;&lt;br /&gt;Dynamic languages are not a magic bullet that instantly solves maintenance woes, in fact, I believe they are the complete opposite. One only has to look back 5 years to classic ASP and Dynamic VBScript to see the complete frustration that dynamic development causes on large projects.&lt;br /&gt;&lt;br /&gt;A properly designed application using a static language such as Java or C# might easily hit the 500k LoC mark, but with proper design and abstraction, the actual code base can easily be split into manageable 10k LoC assemblies.&lt;br /&gt;&lt;br /&gt;At that point you are only maintaining small libraries that reference each other, instead of a super massive black hole of spaghetti code.&lt;br /&gt;&lt;br /&gt;I believe that both forms of languages have their purpose, but I do not buy into the recent dynamic language hype. I have been developing in various languages long enough to remember previous dynamic language hype, and the resulting messy applications that came from it.&lt;br /&gt;&lt;br /&gt;A final note that I do not believe Yegge touched on (mostly because I didn't read all of his 400 page rant) is that dynamic languages must be developed using test driven methodologies. Applying TDD to static languages is great as well, but the compiler adds an additional level of checks.&lt;br /&gt;&lt;br /&gt;What this means in the real world is that a properly designed application will need to have unit tests to ensure that all runtime functionality is carefully checked. The end result is thousands of lines of test code that must be written to replicate the functionality of a compilers type checker*.&lt;br /&gt;&lt;br /&gt;&lt;sup&gt;* I still advocate TDD when using statically typed languages, you just don't need to do as much.&lt;/sup&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-4068319944262489754?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2007/12/what-exactly-do-you-save-with-dynamic.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">32</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-8904837953934668751</guid><pubDate>Thu, 20 Dec 2007 18:07:00 +0000</pubDate><atom:updated>2007-12-20T10:40:24.344-08:00</atom:updated><title>How to find local Data Sources on your server</title><description>In between preparing for the holidays and taking care of my new son (Who turned one month old yesterday), I have been working on writing an installation wizard for CodeBlog.&lt;br /&gt;&lt;br /&gt;Part of the difficulty of installing custom database driven sites onto remote servers is the unpredictability of the server configuration. I am trying to ease that pain by automating as much as possible the initial configuration.&lt;br /&gt;&lt;br /&gt;One major hurdle is coming up with the correct connection string to SQL Server. I am attempting to make this a easy process by allowing the user to select the data source and database from drop down menu's.&lt;br /&gt;&lt;br /&gt;I thought I'd share a handful of code snippets that makes this possible:&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red0\green0\blue0;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf1 private\cf0  \cf4 DataTable\cf0  GetDataSources()\par ??\{\par ??    \cf4 DbProviderFactory\cf0  factory =\par ??        \cf4 DbProviderFactories\cf0 .GetFactory \par ??        (\cf5 "System.Data.SqlClient"\cf0 );\par ??    \par ??    \cf4 DbDataSourceEnumerator\cf0  dataSourceEnumerator = \par ??        factory.CreateDataSourceEnumerator();\par ??\par ??    \cf1 if\cf0  (dataSourceEnumerator != \cf1 null\cf0 )\par ??    \{        \par ??        \cf4 DataTable\cf0  dataSources = dataSourceEnumerator.GetDataSources();\par ??        \cf1 return\cf0  dataSources;\par ??    \}\par ??    \cf1 else\par ??\cf0     \{\par ??        \cf1 throw\cf0  \cf1 new\cf0  \cf4 Exception\cf0 (\cf5 "Something bad happened"\cf0 );\par ??    \}\par ??\}}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: 1px solid black; padding: 5px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;DataTable&lt;/span&gt; GetDataSources()&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;{&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;DbProviderFactory&lt;/span&gt; factory =&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;DbProviderFactories&lt;/span&gt;.GetFactory &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;span style="color: #a31515;"&gt;"System.Data.SqlClient"&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;DbDataSourceEnumerator&lt;/span&gt; dataSourceEnumerator = &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; factory.CreateDataSourceEnumerator();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (dataSourceEnumerator != &lt;span style="color: blue;"&gt;null&lt;/span&gt;)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;DataTable&lt;/span&gt; dataSources = dataSourceEnumerator.GetDataSources();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; dataSources;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;14&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;15&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;16&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;17&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;throw&lt;/span&gt; &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Exception&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"Something bad happened"&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;18&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;19&lt;/span&gt;&amp;nbsp;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;This method returns all available data sources on the local server. Obviously, if the SQL Server is located on a different box, this won't work, so I have implemented a manual entry text box as well.&lt;br /&gt;&lt;br /&gt;The method returns a data table that can be bound to a drop down list. However, because you need to concatenate the value of two columns, you cannot use regular data binding, instead use a method similar to this:&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red0\green0\blue0;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf1 private\cf0  \cf1 void\cf0  BindDataSource()\par ??\{\par ??    \cf4 DataTable\cf0  dt = GetDataSources();\par ??    \cf1 foreach\cf0  (\cf4 DataRow\cf0  dr \cf1 in\cf0  dt.Rows)\par ??    \{   \par ??        \cf4 ListItem\cf0  currentItem = \cf1 new\cf0  \cf4 ListItem\cf0 ();\par ??        currentItem.Value = dr[\cf5 "ServerName"\cf0 ] + \cf5 "\\\\"\cf0  + dr[\cf5 "InstanceName"\cf0 ];\par ??        currentItem.Text = dr[\cf5 "ServerName"\cf0 ] + \cf5 "\\\\"\cf0  + dr[\cf5 "InstanceName"\cf0 ];\par ??        ddlDataSources.Items.Add(currentItem);\par ??    \}\par ??    \cf1 if\cf0  (ddlDataSources.Items.Count &amp;gt; 0)\par ??    \{\par ??        BindDatabaseList();\par ??    \}\par ??    \cf1 else\par ??\cf0     \{\par ??        ddlDataSources.Items.Add(\cf5 "No DataSources found."\cf0 );\par ??    \}\par ??\}}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: 1px solid black; padding: 5px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; BindDataSource()&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;{&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;DataTable&lt;/span&gt; dt = GetDataSources();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af;"&gt;DataRow&lt;/span&gt; dr &lt;span style="color: blue;"&gt;in&lt;/span&gt; dt.Rows)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp; &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;ListItem&lt;/span&gt; currentItem = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;ListItem&lt;/span&gt;();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; currentItem.Value = dr[&lt;span style="color: #a31515;"&gt;"ServerName"&lt;/span&gt;] + &lt;span style="color: #a31515;"&gt;"\\"&lt;/span&gt; + dr[&lt;span style="color: #a31515;"&gt;"InstanceName"&lt;/span&gt;];&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; currentItem.Text = dr[&lt;span style="color: #a31515;"&gt;"ServerName"&lt;/span&gt;] + &lt;span style="color: #a31515;"&gt;"\\"&lt;/span&gt; + dr[&lt;span style="color: #a31515;"&gt;"InstanceName"&lt;/span&gt;];&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ddlDataSources.Items.Add(currentItem);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (ddlDataSources.Items.Count &amp;gt; 0)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; BindDatabaseList();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;14&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;15&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;16&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;17&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ddlDataSources.Items.Add(&lt;span style="color: #a31515;"&gt;"No DataSources found."&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;18&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;19&lt;/span&gt;&amp;nbsp;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;Once the user has selected the proper data source, I wanted to populate a second drop down list with all available databases. The following snippet creates a list of available databases on the data source:&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red0\green0\blue0;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf1 private\cf0  \cf1 void\cf0  BindDatabaseList()\par ??\{\par ??    \cf4 SqlConnectionStringBuilder\cf0  builder = BuildConnectionString();\par ??\par ??    builder.InitialCatalog = \cf5 "master"\cf0 ;\par ??    \par ??    \cf4 SqlConnection\cf0  connection = \cf1 new\cf0  \cf4 SqlConnection\cf0 (builder.ConnectionString);\par ??    \cf4 SqlCommand\cf0  command = \cf1 new\cf0  \cf4 SqlCommand\cf0 ();\par ??    \cf4 SqlDataReader\cf0  dataReader;\par ??    \par ??    connection.Open();\par ??            \par ??    command.CommandText = \cf5 "SELECT NAME FROM master..sysdatabases ORDER BY NAME ASC"\cf0 ;\par ??    command.Connection = connection;\par ??    dataReader = command.ExecuteReader();\par ??\par ??    ddlDataBase.Items.Clear();\par ??    \par ??    \cf1 while\cf0  (dataReader.Read())\par ??    \{\par ??        \cf1 string\cf0  dbName = (\cf4 String\cf0 )dataReader[\cf5 "name"\cf0 ];\par ??        \cf1 if\cf0  (dbName != \cf1 null\cf0 )\par ??        \{\par ??            \cf1 if\cf0  (dbName != \cf5 "master"\cf0  &amp;amp;&amp;amp;\par ??                dbName != \cf5 "msdb"\cf0  &amp;amp;&amp;amp;\par ??                dbName != \cf5 "tempdb"\cf0  &amp;amp;&amp;amp;\par ??                dbName != \cf5 "model"\cf0 )\par ??            \{\par ??                ddlDataBase.Items.Add(dbName);                        \par ??            \}                    \par ??        \}\par ??    \}\par ??    connection.Close();                        \par ??\}\par ??}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: 1px solid black; padding: 5px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; BindDatabaseList()&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;{&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;SqlConnectionStringBuilder&lt;/span&gt; builder = BuildConnectionString();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; builder.InitialCatalog = &lt;span style="color: #a31515;"&gt;"master"&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;SqlConnection&lt;/span&gt; connection = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;SqlConnection&lt;/span&gt;(builder.ConnectionString);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;SqlCommand&lt;/span&gt; command = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;SqlCommand&lt;/span&gt;();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;SqlDataReader&lt;/span&gt; dataReader;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; connection.Open();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; command.CommandText = &lt;span style="color: #a31515;"&gt;"SELECT NAME FROM master..sysdatabases ORDER BY NAME ASC"&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;14&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; command.Connection = connection;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;15&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dataReader = command.ExecuteReader();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;16&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;17&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ddlDataBase.Items.Clear();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;18&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;19&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;while&lt;/span&gt; (dataReader.Read())&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;20&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;21&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; dbName = (&lt;span style="color: #2b91af;"&gt;String&lt;/span&gt;)dataReader[&lt;span style="color: #a31515;"&gt;"name"&lt;/span&gt;];&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;22&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (dbName != &lt;span style="color: blue;"&gt;null&lt;/span&gt;)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;23&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;24&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (dbName != &lt;span style="color: #a31515;"&gt;"master"&lt;/span&gt; &amp;amp;&amp;amp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;25&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; dbName != &lt;span style="color: #a31515;"&gt;"msdb"&lt;/span&gt; &amp;amp;&amp;amp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;26&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; dbName != &lt;span style="color: #a31515;"&gt;"tempdb"&lt;/span&gt; &amp;amp;&amp;amp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;27&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; dbName != &lt;span style="color: #a31515;"&gt;"model"&lt;/span&gt;)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;28&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;29&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ddlDataBase.Items.Add(dbName);&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;30&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;31&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;32&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;33&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; connection.Close();&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;34&lt;/span&gt;&amp;nbsp;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;All of these little snippets combine to create a intuitive way to setup the initial database connection. It is a lot of work, but the result is a simple configuration screen.&lt;br /&gt;&lt;br /&gt;Normally, I would avoid placing database code directly into front end code, but in the case of a run once installation script, it makes sense. Once the script has ran, the user will have to physically delete it off the server before CodeBlog will run. This is to prevent a malicious person from reconfiguring the database.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-8904837953934668751?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2007/12/in-between-preparing-for-holidays-and.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-455424659787260415</guid><pubDate>Fri, 14 Dec 2007 03:54:00 +0000</pubDate><atom:updated>2007-12-13T20:31:45.248-08:00</atom:updated><title>ASP.NET MVC RouteBuilder HTTPModule released!</title><description>The ASP.NET MVC currently stores all route information in global.asax. One of the first things I did when I began playing with the CTP was moving the routing rules into a HTTPModule.&lt;br /&gt;&lt;br /&gt;However, I do not believe that configuration should ever be stored inside a compiled code file. &lt;br /&gt;&lt;br /&gt;I blogged &lt;a href="http://codeeleven.blogspot.com/2007/12/yesterday-i-finally-installed-visual.html"&gt;yesterday&lt;/a&gt; about my difficulty in building a dynamic route builder due to the Route object only accepting an anonymous type for the "defaults" property.&lt;br /&gt;&lt;br /&gt;However, with the help of &lt;a href="http://weblogs.asp.net/leftslipper/default.aspx"&gt;Eilon Lipton&lt;/a&gt; (One of the principle developers behind ASP.NET MVC), I was able to circumvent this limitation by using a custom class that inherited from CustomTypeDescriptor at the cost of having to write a lot of boilerplate code.&lt;br /&gt;&lt;br /&gt;The final product? A simple HTTPModule that allows you to place your routing rules in web.config where they belong.&lt;br /&gt;&lt;br /&gt;The binary and full source are available on the &lt;a href="http://www.codeplex.com/RouteBuilder"&gt;RouteBuilder CodePlex page&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Download and check it out. There are full (simple) installation and usage instructions in the zip file.&lt;br /&gt;&lt;br /&gt;Huge thanks to Eilon for promptly answering my questions. This speaks volumes about Microsoft's dedication to the development community.&lt;br /&gt;&lt;br /&gt;Please let me know if you have any issues using it, or how it can be improved.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-455424659787260415?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2007/12/aspnet-mvc-routebuilder-httpmodule.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">7</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-5484579697141067263</guid><pubDate>Thu, 13 Dec 2007 00:56:00 +0000</pubDate><atom:updated>2007-12-12T17:33:55.733-08:00</atom:updated><title>ASP.NET MVC makes it impossible to dynamically build RouteTables?</title><description>Yesterday I finally installed Visual Studio 2008, for the sole purpose of studying the new ASP.NET MVC framework.&lt;br /&gt;&lt;br /&gt;As it is currently designed, the MVC framework places all URL Routing rules into global.asax.&lt;br /&gt;&lt;br /&gt;Personally, I feel that many applications will have dozens, if not hundreds of URL routing rules, so the first thing I did was create a HTTPModule and move the URL routing rules out of global.asax.&lt;br /&gt;&lt;br /&gt;This worked great, but I find the concept of hard coding configuration into the source code rather primitive, so I began implementing a custom configuration section into web.config to handle URL routing.&lt;br /&gt;&lt;br /&gt;Initial development went great, and it was not long before I had this in my web.config:&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red255\green0\blue0;\red0\green0\blue0;}??\fs20 \cf1 &amp;lt;\cf3 RouteTable\cf1 &amp;gt;\par ??  &amp;lt;\cf3 Routes\cf1 &amp;gt;\par ??    &amp;lt;\cf3 addRoute\cf1  \cf4 Url\cf1 =\cf0 "\cf1 [controller]/[action]/[postId]\cf0 "\cf1  \cf4 Defaults\cf1 =\cf0 "\cf1 action=Index,postId=(string)null\cf0 "\cf1 /&amp;gt;\par ??    &amp;lt;\cf3 addRoute\cf1  \cf4 Url\cf1 =\cf0 "\cf1 Default.aspx\cf0 "\cf1  \cf4 Defaults\cf1 =\cf0 "\cf1 controller=Home,action=Index,id=(string)null\cf0 "\cf1 /&amp;gt;\par ??  &amp;lt;/\cf3 Routes\cf1 &amp;gt;      \par ??&amp;lt;/\cf3 RouteTable\cf1 &amp;gt;}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: 1px solid black;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;RouteTable&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Routes&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;addRoute&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;Url&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;[controller]/[action]/[postId]&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;Defaults&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;action=Index,postId=(string)null&lt;/span&gt;"&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;addRoute&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;Url&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;Default.aspx&lt;/span&gt;"&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;Defaults&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;controller=Home,action=Index,id=(string)null&lt;/span&gt;"&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Routes&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;RouteTable&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The only caveat? My dynamic route building code did not work.&lt;br /&gt;&lt;br /&gt;I had assumed that because Route.Defaults was an object type, it would be smart enough to let me stuff a key/value Dictionary into it containing the defaults values.&lt;br /&gt;&lt;br /&gt;However, Route.Defaults only accepts an anonymous type, as you can see here in the debugger:&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_I914lDmRUzA/R2CJvc-p6sI/AAAAAAAAAAw/5NukA76O7nA/s1600-h/RouteHandler1.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_I914lDmRUzA/R2CJvc-p6sI/AAAAAAAAAAw/5NukA76O7nA/s400/RouteHandler1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5143262222782950082" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;The C# compiler converts these anonymous types to strongly typed classes during compile time, so the Route class must rely on reflection to figure out what properties were created. In my opinion this is a rather inelegant abuse of a new technology, when a simply dictionary would have sufficed just fine.&lt;br /&gt;&lt;br /&gt;A little googling found a &lt;a href="http://weblogs.asp.net/leftslipper/archive/2007/09/24/using-c-3-0-anonymous-types-as-dictionaries.aspx"&gt;blog post from Eilon Lipton&lt;/a&gt; championing this technique, and why they used in the MVC framework.&lt;br /&gt;&lt;br /&gt;Granted, I am new to C# 3.0, and I don't fully understand all of its new features. But for the life of me, I cannot figure out how to construct an anonymous class during runtime, and if you cannot*, then there is no way to dynamically build route tables with the MVC framework as it is currently designed.&lt;br /&gt;&lt;br /&gt;And that, I must say, is disappointing.&lt;br /&gt;&lt;br /&gt;&lt;sup&gt;* Please tell me how to do this if its possible!&lt;/sup&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-5484579697141067263?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2007/12/yesterday-i-finally-installed-visual.html</link><author>noreply@blogger.com (Jonathan Holland)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_I914lDmRUzA/R2CJvc-p6sI/AAAAAAAAAAw/5NukA76O7nA/s72-c/RouteHandler1.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-2850015811322974492</guid><pubDate>Wed, 12 Dec 2007 17:55:00 +0000</pubDate><atom:updated>2007-12-12T10:15:50.087-08:00</atom:updated><title>Visual Studio 2008 and the "InitializingToolbox" bug.</title><description>With the new &lt;a href="http://go.microsoft.com/fwlink/?LinkID=105029&amp;clcid=0x409"&gt;ASP.NET MVC CTP&lt;/a&gt; released, I finally had a reason to get around to installing the Visual Studio 2008 RTM.&lt;br /&gt;&lt;br /&gt;I was excited to dig into the MVC framework and start blogging about it, except that I found Visual Studio 2008 was borderline unusable.&lt;br /&gt;&lt;br /&gt;Opening a ASPX file would stall my system, spike my CPU/Ram usage and sit there frozen, with the message "Initializing Toolbox" in the status bar.&lt;br /&gt;&lt;br /&gt;Obviously, this was unacceptable, so I searched for a way to fix this issue. I believe it is related to having multiple versions of Visual Studio installed on the same system. In my case, I have 2003,2005 and 2008 for various different projects I work on.&lt;br /&gt;&lt;br /&gt;Regardless of the cause, I finally found the fix:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Navigate to: Documents And Settings\{UserName}\Local Settings\Application Data\Microsoft\VisualStudio.&lt;/li&gt;&lt;li&gt;You should see a directory named 9.0.&lt;/li&gt;&lt;li&gt;Rename or delete this directory.&lt;/li&gt;&lt;li&gt;Start Visual Studio 2008 and open a ASPX page. It should grind away for about 10 minutes.&lt;/li&gt;&lt;li&gt;Eventually it will open, and everything will be good from then on.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;An odd bug for sure, but now that it is fixed, VS 2008 is quite nice. After I have some time to digest the MVC bits, I hope to be able to blog on my opinion of the new framework.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-2850015811322974492?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2007/12/visual-studio-2008-and.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">13</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-2089365407150245084</guid><pubDate>Sat, 08 Dec 2007 06:28:00 +0000</pubDate><atom:updated>2007-12-07T22:55:25.958-08:00</atom:updated><title>Setting up  a SQLEXPRESS Database for use with ASP.NET</title><description>If you set up a database using SQLEXPRESS for use with an ASP.NET site, you may get an error message similar to:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The login failed. Login failed for user 'MACHINENAME\ASPNET'&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The reason for this is because the ASP.NET Worker process runs under the ASPNET User account, and if the database is using Windows Authentication it will deny access to that user.&lt;br /&gt;&lt;br /&gt;Fortunately, the fix is very simple. Since SQLEXPRESS does not have any graphical management tools, you can use osql.exe to setup your database to work with the ASPNET account.&lt;br /&gt;&lt;br /&gt;Fire up your preferred shell and type:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid black; padding: 5px"&gt;&lt;b&gt;osql -E -S [YOURMACHINENAME]\SQLEXPRESS -d [YOURDATABASENAME]&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;This will fire up osql and connect to your database.&lt;br /&gt;&lt;br /&gt;At this point, you should see a prompt. Enter the following lines:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid black; padding: 5px"&gt;&lt;b&gt;EXEC sp_grantdbaccess [MACHINENAME\ASPNET]&lt;/b&gt;&lt;br /&gt;&lt;b&gt;GO&lt;/b&gt;&lt;br /&gt;&lt;b&gt;EXEC sp_addrolemember 'db_owner',[MACHINENAME\ASPNET]&lt;/b&gt;&lt;br /&gt;&lt;b&gt;GO&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;At this point, your ASP.NET site will be able to connect to the database, however it may not be able to perform operations to it. You may need to grant privileges to the account. &lt;br /&gt;&lt;br /&gt;This is done on a table by table basis, so go back to osql and type:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid black; padding: 5px"&gt;&lt;b&gt;GRANT SELECT,INSERT,UPDATE,DELETE ON [TableName] TO [MACHINENAME\ASPNET]&lt;/b&gt;&lt;br /&gt;&lt;b&gt;GO&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Do this for each table in the database, if you have any stored procedures, you will also want to grant execute privileges:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid black; padding: 5px"&gt;&lt;b&gt;GRANT EXECUTE TO [MACHINENAME\ASPNET]&lt;/b&gt;&lt;br /&gt;&lt;b&gt;GO&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;With all that done, you should be completely set up to use SQLEXPRESS with ASP.NET.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-2089365407150245084?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2007/12/setting-up-sqlexpress-database-for-use.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-3375726150642939974</guid><pubDate>Fri, 07 Dec 2007 17:27:00 +0000</pubDate><atom:updated>2007-12-07T10:35:13.652-08:00</atom:updated><title>The hidden ORM Tax and why profiling is a good thing.</title><description>I am a strong believer in not doing premature optimization while programming. Because of this, database performance has been on the back burner for CodeBlog, while I focused on getting the core built.&lt;br /&gt;&lt;br /&gt;At this point, the engine is 99% functional, so I thought I'd step back and look at it from the performance standpoint.&lt;br /&gt;&lt;br /&gt;As I have mentioned before, I used &lt;a href="http://www.subsonicproject.com"&gt;SubSonic&lt;/a&gt; as an Object Relational Mapper (ORM) to speed up the development of this project. In a nutshell, SubSonic employs the &lt;a href="http://en.wikipedia.org/wiki/ActiveRecord"&gt;ActiveRecord pattern&lt;/a&gt; to build strongly typed classes and collections that correspond to tables and rows in the database.&lt;br /&gt;&lt;br /&gt;SubSonic makes development a breeze, allowing me to quickly write a business layer that could manipulate the SubSonic generated objects and never have to worry about the underlying database. If I needed to do something that SubSonic couldn't handle, I  wrote a stored procedure in the database and SubSonic would create a static class to call it. &lt;br /&gt;&lt;br /&gt;Definitely a great tool for rapid development, however it is not without its drawbacks.&lt;br /&gt;&lt;br /&gt;Yesterday, I set up a SQL profiler, interested in seeing how Subsonic was actually hitting the database on each page load. While I expected to see some inefficient queries (The natural by product of using ActiveRecord), what I did find was far worse:&lt;br /&gt;&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green128\blue0;\red255\green255\blue255;\red0\green0\blue255;\red0\green0\blue0;}??\fs20 \cf1 --Main Page:\par ??\par ??-- First Get All Posts that we have, this is to calculate out post paging\par ??\cf3 SELECT COUNT\cf0 ([postID]) \cf3 FROM \cf0 [Post]\par ??\par ??\cf1 -- Grab all the posts????\par ??\cf3 SELECT TOP \cf0 100 PERCENT  [dbo].[Post].[PostID], [dbo].[Post].[CreatedOn], \par ??\tab [dbo].[Post].[CreatedBy], [dbo].[Post].[ModifiedOn], [dbo].[Post].[ModifiedBy], \par ??\tab [dbo].[Post].[Author], [dbo].[Post].[Subject], [dbo].[Post].[Text], [dbo].[Post].[UrlKey] \par ??\tab \cf3 FROM \cf0 [dbo].[Post] \cf3 ORDER BY \cf0 [CreatedOn] \cf3 DESC\cf0 ;\par ??\par ??\cf1 -- Now we grab the post Object again to get the URL to the post page\par ??\cf3 SELECT TOP \cf0 100 PERCENT  [dbo].[Post].[PostID], [dbo].[Post].[CreatedOn], [dbo].[Post].[CreatedBy], \par ??\tab [dbo].[Post].[ModifiedOn], [dbo].[Post].[ModifiedBy], [dbo].[Post].[Author], [dbo].[Post].[Subject], \par ??\tab [dbo].[Post].[Text], [dbo].[Post].[UrlKey] \par ??\tab \cf3 FROM \cf0 [dbo].[Post] \cf3 WHERE \cf0 [Post].[PostID] = @PostID0 \cf3 ORDER BY \cf0 [PostID] \cf3 ASC\cf0 ;\par ??\par ??\cf1 -- Grab the Whole author object, all we really need is first name.\par ??\par ??\cf3 SELECT TOP \cf0 100 PERCENT  \par ??\tab [dbo].[Author].[AuthorID], [dbo].[Author].[CreatedOn], [dbo].[Author].[CreatedBy], \par ??\tab [dbo].[Author].[ModifiedOn], [dbo].[Author].[ModifiedBy], [dbo].[Author].[FullName], \par ??\tab [dbo].[Author].[PassHash], [dbo].[Author].[UserName], [dbo].[Author].[PostCount], \par ??\tab [dbo].[Author].[isAdmin] \par ??\tab \cf3 FROM \cf0 [dbo].[Author] \cf3 WHERE \cf0 [Author].[AuthorID] = @AuthorID0 \cf3 ORDER BY \cf0 [AuthorID] \cf3 ASC\cf0 ;\par ??\par ??\cf1 -- Grab all the comments, all we want is the count\par ??\par ??\cf3 SELECT TOP \cf0 100 PERCENT  [dbo].[Comment].[CommentID], [dbo].[Comment].[CreatedOn], \par ??\tab [dbo].[Comment].[CreatedBy], [dbo].[Comment].[ModifiedOn], [dbo].[Comment].[ModifiedBy], \par ??\tab [dbo].[Comment].[PostID], [dbo].[Comment].[AuthorName], [dbo].[Comment].[AuthorEmail], \par ??\tab [dbo].[Comment].[AuthorWeb], [dbo].[Comment].[Subject], [dbo].[Comment].[Text] \par ??\tab \cf3 FROM \cf0 [dbo].[Comment] \cf3 WHERE \cf0 [Comment].[PostID] = @PostID0 \cf3 ORDER BY \cf0 [CreatedOn] \cf3 ASC\cf0 ;}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: 1px solid black; padding: 5px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: green;"&gt;--Main Page:&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: green;"&gt;-- First Get All Posts that we have, this is to calculate out post paging&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;SELECT COUNT&lt;/span&gt;([postID]) &lt;span style="color: blue;"&gt;FROM &lt;/span&gt;[Post]&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: green;"&gt;-- Grab all the posts????&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;SELECT TOP &lt;/span&gt;100 PERCENT&amp;nbsp; [dbo].[Post].[PostID], [dbo].[Post].[CreatedOn], &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [dbo].[Post].[CreatedBy], [dbo].[Post].[ModifiedOn], [dbo].[Post].[ModifiedBy], &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [dbo].[Post].[Author], [dbo].[Post].[Subject], [dbo].[Post].[Text], [dbo].[Post].[UrlKey] &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;FROM &lt;/span&gt;[dbo].[Post] &lt;span style="color: blue;"&gt;ORDER BY &lt;/span&gt;[CreatedOn] &lt;span style="color: blue;"&gt;DESC&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/span&gt;&amp;nbsp;&lt;span style="color: green;"&gt;-- Now we grab the post Object again to get the URL to the post page&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;SELECT TOP &lt;/span&gt;100 PERCENT&amp;nbsp; [dbo].[Post].[PostID], [dbo].[Post].[CreatedOn], [dbo].[Post].[CreatedBy], &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;14&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [dbo].[Post].[ModifiedOn], [dbo].[Post].[ModifiedBy], [dbo].[Post].[Author], [dbo].[Post].[Subject], &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;15&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [dbo].[Post].[Text], [dbo].[Post].[UrlKey] &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;16&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;FROM &lt;/span&gt;[dbo].[Post] &lt;span style="color: blue;"&gt;WHERE &lt;/span&gt;[Post].[PostID] = @PostID0 &lt;span style="color: blue;"&gt;ORDER BY &lt;/span&gt;[PostID] &lt;span style="color: blue;"&gt;ASC&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;17&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;18&lt;/span&gt;&amp;nbsp;&lt;span style="color: green;"&gt;-- Grab the Whole author object, all we really need is first name.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;19&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;20&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;SELECT TOP &lt;/span&gt;100 PERCENT&amp;nbsp; &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;21&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [dbo].[Author].[AuthorID], [dbo].[Author].[CreatedOn], [dbo].[Author].[CreatedBy], &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;22&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [dbo].[Author].[ModifiedOn], [dbo].[Author].[ModifiedBy], [dbo].[Author].[FullName], &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;23&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [dbo].[Author].[PassHash], [dbo].[Author].[UserName], [dbo].[Author].[PostCount], &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;24&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [dbo].[Author].[isAdmin] &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;25&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;FROM &lt;/span&gt;[dbo].[Author] &lt;span style="color: blue;"&gt;WHERE &lt;/span&gt;[Author].[AuthorID] = @AuthorID0 &lt;span style="color: blue;"&gt;ORDER BY &lt;/span&gt;[AuthorID] &lt;span style="color: blue;"&gt;ASC&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;26&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;27&lt;/span&gt;&amp;nbsp;&lt;span style="color: green;"&gt;-- Grab all the comments, all we want is the count&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;28&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;29&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;SELECT TOP &lt;/span&gt;100 PERCENT&amp;nbsp; [dbo].[Comment].[CommentID], [dbo].[Comment].[CreatedOn], &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;30&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [dbo].[Comment].[CreatedBy], [dbo].[Comment].[ModifiedOn], [dbo].[Comment].[ModifiedBy], &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;31&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [dbo].[Comment].[PostID], [dbo].[Comment].[AuthorName], [dbo].[Comment].[AuthorEmail], &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;32&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [dbo].[Comment].[AuthorWeb], [dbo].[Comment].[Subject], [dbo].[Comment].[Text] &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;33&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;FROM &lt;/span&gt;[dbo].[Comment] &lt;span style="color: blue;"&gt;WHERE &lt;/span&gt;[Comment].[PostID] = @PostID0 &lt;span style="color: blue;"&gt;ORDER BY &lt;/span&gt;[CreatedOn] &lt;span style="color: blue;"&gt;ASC&lt;/span&gt;;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Without running the profiler, I had no idea that I was hitting the database that hard to just load the main page of CodeBlog. &lt;br /&gt;&lt;br /&gt;An interesting note, the query that appears to be grabbing all of the posts actually uses SQL Server 2005 paging to only grab a handful posts, and I believe the SQL Profiler is getting confused. At least, I hope so.&lt;br /&gt;&lt;br /&gt;Right off the bat, I see several improvements that I can make to prevent round trips to the database. For example, I have a helper method for the Post business object that generates a Rewrite Friendly URL. There is no need for this method to go back to the DB to get the UrlKey when we already have the entire post loaded as an object. &lt;br /&gt;&lt;br /&gt;Additionally, there is no need to pull the comments from the database, when all we really need is the count, so I wrote an overloaded Fill method for the Comments as well.&lt;br /&gt;&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green128\blue0;\red255\green255\blue255;\red0\green0\blue255;\red0\green0\blue0;}??\fs20 \cf1 -- Grab the total number of posts\par ??\cf3 SELECT COUNT\cf0 ([postID]) \cf3 FROM \cf0 [Post]\par ??\par ??\cf1 -- Grab a page of posts\par ??\cf3 SELECT TOP \cf0 100 PERCENT  \par ??\tab [dbo].[Post].[PostID], [dbo].[Post].[CreatedOn], [dbo].[Post].[CreatedBy], \par ??\tab [dbo].[Post].[ModifiedOn], [dbo].[Post].[ModifiedBy], [dbo].[Post].[Author], \par ??\tab [dbo].[Post].[Subject], [dbo].[Post].[Text], [dbo].[Post].[UrlKey] \par ??\tab \cf3 FROM \cf0 [dbo].[Post] \cf3 ORDER BY \cf0 [CreatedOn] \cf3 DESC\cf0 ;\par ??\par ??\cf1 -- Grab the Author\par ??\cf3 SELECT TOP \cf0 100 PERCENT  \par ??\tab [dbo].[Author].[AuthorID], [dbo].[Author].[CreatedOn], [dbo].[Author].[CreatedBy], \par ??\tab [dbo].[Author].[ModifiedOn], [dbo].[Author].[ModifiedBy], [dbo].[Author].[FullName], \par ??\tab [dbo].[Author].[PassHash], [dbo].[Author].[UserName], [dbo].[Author].[PostCount], \par ??\tab [dbo].[Author].[isAdmin] \par ??\tab \cf3 FROM \cf0 [dbo].[Author] \cf3 WHERE \cf0 [Author].[AuthorID] = @AuthorID0 \cf3 ORDER BY \cf0 [AuthorID] \cf3 ASC\cf0 ;\par ??\par ??\cf1 -- Grab the number of comments\par ??\cf3 SELECT COUNT\cf0 ([CommentID]) \cf3 FROM \cf0 [Comment] \cf3 WHERE \cf0 [Comment].[PostID] = @PostID0}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: 1px solid black; padding: 5px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: green;"&gt;-- Grab the total number of posts&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;SELECT COUNT&lt;/span&gt;([postID]) &lt;span style="color: blue;"&gt;FROM &lt;/span&gt;[Post]&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: green;"&gt;-- Grab a page of posts&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;SELECT TOP &lt;/span&gt;100 PERCENT&amp;nbsp; &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [dbo].[Post].[PostID], [dbo].[Post].[CreatedOn], [dbo].[Post].[CreatedBy], &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [dbo].[Post].[ModifiedOn], [dbo].[Post].[ModifiedBy], [dbo].[Post].[Author], &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [dbo].[Post].[Subject], [dbo].[Post].[Text], [dbo].[Post].[UrlKey] &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;FROM &lt;/span&gt;[dbo].[Post] &lt;span style="color: blue;"&gt;ORDER BY &lt;/span&gt;[CreatedOn] &lt;span style="color: blue;"&gt;DESC&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: green;"&gt;-- Grab the Author&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;SELECT TOP &lt;/span&gt;100 PERCENT&amp;nbsp; &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [dbo].[Author].[AuthorID], [dbo].[Author].[CreatedOn], [dbo].[Author].[CreatedBy], &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;14&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [dbo].[Author].[ModifiedOn], [dbo].[Author].[ModifiedBy], [dbo].[Author].[FullName], &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;15&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [dbo].[Author].[PassHash], [dbo].[Author].[UserName], [dbo].[Author].[PostCount], &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;16&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [dbo].[Author].[isAdmin] &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;17&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;FROM &lt;/span&gt;[dbo].[Author] &lt;span style="color: blue;"&gt;WHERE &lt;/span&gt;[Author].[AuthorID] = @AuthorID0 &lt;span style="color: blue;"&gt;ORDER BY &lt;/span&gt;[AuthorID] &lt;span style="color: blue;"&gt;ASC&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;18&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;19&lt;/span&gt;&amp;nbsp;&lt;span style="color: green;"&gt;-- Grab the number of comments&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;20&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;SELECT COUNT&lt;/span&gt;([CommentID]) &lt;span style="color: blue;"&gt;FROM &lt;/span&gt;[Comment] &lt;span style="color: blue;"&gt;WHERE &lt;/span&gt;[Comment].[PostID] = @PostID0&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Doing this dropped one call to the database, and cut down heavily on the amount of data returned. It is still less than optimal, but to further optimize would involve me extending the SubSonic methods for my own needs, and at that point, why even bother with using an ORM tool?&lt;br /&gt;&lt;br /&gt;The sad truth of the matter is that everything queried for that page could be pulled with one trip to the database with a well executed JOIN query. Because ORM's prefer multiple trips instead of JOIN's, you end up with this form of inefficiency.&lt;br /&gt;&lt;br /&gt;At the moment I am on the fence about using an ORM. While it has helped me rapidly build my application, I feel that under heavy use, I would have to go back and rewrite my database layer by hand.&lt;br /&gt;&lt;br /&gt;If performance is what you need. Don't use an ORM. If you need rapid development to a small target audience, then ORM's are great, but even if you use one, always profile it to see where you can improve your performance.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-3375726150642939974?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2007/12/hidden-orm-tax-and-why-profiling-is.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">7</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-1416124193237188758</guid><pubDate>Tue, 04 Dec 2007 23:54:00 +0000</pubDate><atom:updated>2007-12-04T18:01:29.808-08:00</atom:updated><title>Are you inadequate?</title><description>&lt;a href="http://www.secretgeek.net/inadequate.asp"&gt;SecretGeek&lt;/a&gt; posted a little morale booster for us developers:&lt;br /&gt;&lt;div style='border: 1px solid black'&gt;&lt;br /&gt;&lt;blockquote&gt;YOU ARE NOT INADEQUATE.&lt;ul&gt;&lt;li&gt;You do NOT have to refactor all your code.&lt;/li&gt;&lt;li&gt;You do NOT have to keep up with the latest news from microsoft, and know everything there is to know about longhorn, whidbey, avalon, XAML, indigo and star wars III.&lt;/li&gt;&lt;li&gt;You do not have to have perfectly de-coupled tiers in your technology independent SOA software.&lt;/li&gt;&lt;li&gt;You do not have to comply to every standard, achieve the perfect balance between maintainability and performance. Usability and familiarity.&lt;/li&gt;&lt;li&gt;You don't have to do "first things first every day"&lt;/li&gt;&lt;li&gt;You DO NOT have to memorize and understand every patten the gang of four have cataloged.&lt;/li&gt;&lt;li&gt;You do NOT have to read every technical blog, print out every technical article and learn every technical thing there is to learn.&lt;/li&gt;&lt;li&gt;You are beautiful just the way you are.&lt;/li&gt;&lt;li&gt;You are brilliant, interesting, wise and fun to be around.&lt;/li&gt;&lt;li&gt;You rock.&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;br /&gt;According to &lt;a href="http://www.codinghorror.com/blog/archives/001002.html"&gt;Jeff Atwoods 80/20 rule&lt;/a&gt;, if you are reading this blog, then you are already in the 20%. I am not saying that I am a top 20% developer, just that anyone who is actively reading programming blogs usually cares enough about their craft to not be inadequate.&lt;br /&gt;&lt;br /&gt;It is easy to feel like a second rate programmer when you read programming blogs. Often I feel like topics go completely over my head when I try to decipher some of the more technologically advanced posts out there. &lt;br /&gt;&lt;br /&gt;But if you are reading about programming, then you are learning...You may not be the worlds greatest programmer, but you are head and shoulders above people who program from 9-5 and then go home and watch TV.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;The more you learn, the more inadequate you should feel&lt;/span&gt;. If you start to feel complacent, then you enter the dangerous stagnation that dooms developers in this fast paced industry.&lt;br /&gt;&lt;br /&gt;My advice on not being inadequate?&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Read blogs from people smarter than you.&lt;/li&gt;&lt;li&gt;Write your own blog.&lt;/li&gt;&lt;li&gt;Learn something new every day. Anything.&lt;/li&gt;&lt;li&gt;Program at home, on the weekends, while sleeping...you get my drift.&lt;/li&gt;&lt;/ul&gt;There are too many inadequate programmers who get by because they have found their niche. Don't fall into that trap. Become a dynamic developer. It is good for your career, and the community as a whole.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-1416124193237188758?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2007/12/are-you-inadequate.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">7</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-5719871700953509237</guid><pubDate>Sun, 02 Dec 2007 19:12:00 +0000</pubDate><atom:updated>2007-12-02T12:00:36.804-08:00</atom:updated><title>Extending your application by creating plugins.</title><description>CodeBlog would have been done long ago if I did not keep thinking of other idea's to stick into it.&lt;br /&gt;&lt;br /&gt;This morning I was wondering on the best way to approach handling custom sidebar widgets, and it struck me that creating a simple plug-in system would not only be fun, but it would allow other people to develop widgets without having to rebuild the inner workings of CodeBlog.&lt;br /&gt;&lt;br /&gt;After a half hour or so of tinkering, I came up with the basic concept for developing a CodeBlog plug-in, though there is a lot more to code out.&lt;br /&gt;&lt;br /&gt;The basic concept:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Each plug-in is stored within its own assembly.&lt;/li&gt;&lt;li&gt; A common interface (ICodeBlogPlugin) is used to reference the plug-in.&lt;/li&gt;&lt;li&gt; A static factory method is used in CodeBlog to load and instantiate the plug-in.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Each Plug-In is a class library that references CodeBlog.Plugin.dll. This library provides an interface ICodeBlogPlugin that must be implemented by the plug-in class.&lt;br /&gt;&lt;br /&gt;For testing, I used a very basic interface, but I will extend this interface to provide all the method signatures needed for an actual plug-in:&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red0\green0\blue0;\red43\green145\blue175;}??\fs20 \cf1 public\cf0  \cf1 interface\cf0  \cf4 ICodeBlogPlugin\par ??\cf0     \{        \par ??        \cf1 string\cf0  PluginName\par ??        \{\par ??            \cf1 get\cf0 ;\par ??            \cf1 set\cf0 ;\par ??        \}\par ??\par ??        \cf1 void\cf0  Render();\par ??    \}}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: 2px solid black; padding: 5px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;interface&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;ICodeBlogPlugin&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; PluginName&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;get&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;set&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Render();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;This interface is to be implemented by any plug-in class. For example, to test my idea, I created a new class library and added CodeBlog.Plugin as a reference:&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red128\green128\blue128;\red0\green128\blue0;\red163\green21\blue21;}??\fs20     \cf3 public\cf0  \cf3 class\cf0  \cf4 TestPlugin\cf0  : \cf4 ICodeBlogPlugin\par ??\cf0     \{\par ??        \par ??        \cf3 private\cf0  \cf3 string\cf0  _pluginName;\par ??\par ??        \cf5 ///\cf6  \cf5 &amp;lt;summary&amp;gt;\par ??\cf0         \cf5 ///\cf6  PluginName Property required by ICodeBlogPlugin\par ??\cf0         \cf5 ///\cf6  \cf5 &amp;lt;/summary&amp;gt;\par ??\cf0         \cf3 public\cf0  \cf3 string\cf0  PluginName\par ??        \{\par ??            \cf3 get\par ??\cf0             \{\par ??                \cf3 return\cf0  _pluginName;\par ??            \}\par ??            \cf3 set\par ??\cf0             \{\par ??                _pluginName = \cf3 value\cf0 ;\par ??            \}\par ??        \}\par ??\par ??        \cf5 ///\cf6  \cf5 &amp;lt;summary&amp;gt;\par ??\cf0         \cf5 ///\cf6  Default Constructor\par ??\cf0         \cf5 ///\cf6  \cf5 &amp;lt;/summary&amp;gt;\par ??\cf0         \cf3 public\cf0  TestPlugin()\par ??        \{\par ??            PluginName = \cf7 "TestPlugin!"\cf0 ;\par ??        \}\par ??\par ??        \cf5 ///\cf6  \cf5 &amp;lt;summary&amp;gt;\par ??\cf0         \cf5 ///\cf6  Render Method required by ICodeBlogPlugin\par ??\cf0         \cf5 ///\cf6  \cf5 &amp;lt;/summary&amp;gt;\par ??\cf0         \cf3 public\cf0  \cf3 void\cf0  Render()\par ??        \{\par ??            \cf4 HttpContext\cf0 .Current.Response.Write(PluginName);\par ??        \}\par ??    \}}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: 2px solid black; padding: 5px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;TestPlugin&lt;/span&gt; : &lt;span style="color: #2b91af;"&gt;ICodeBlogPlugin&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; _pluginName;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; PluginName Property required by ICodeBlogPlugin&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; PluginName&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;get&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; _pluginName;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;14&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;15&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;set&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;16&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;17&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; _pluginName = &lt;span style="color: blue;"&gt;value&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;18&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;19&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;20&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;21&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;22&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; Default Constructor&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;23&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;24&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; TestPlugin()&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;25&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;26&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; PluginName = &lt;span style="color: #a31515;"&gt;"TestPlugin!"&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;27&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;28&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;29&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;30&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; Render Method required by ICodeBlogPlugin&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;31&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;32&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Render()&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;33&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;34&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;HttpContext&lt;/span&gt;.Current.Response.Write(PluginName);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;35&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;36&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;To load the plugin into a class instance in the CodeBlog Core. I also added a static class called PluginFactory into CodeBlog.Plugin:&lt;br /&gt;&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs20     \cf3 public\cf0  \cf3 static\cf0  \cf3 class\cf0  \cf4 PluginFactory\par ??\cf0     \{\par ??        \cf3 public\cf0  \cf3 static\cf0  \cf4 ICodeBlogPlugin\cf0  LoadPlugin(\cf3 string\cf0  pluginName)\par ??        \{\par ??            \cf4 Type\cf0  theType = \cf4 Type\cf0 .GetType(pluginName);\par ??            \cf3 return\cf0  (\cf4 ICodeBlogPlugin\cf0 )\cf4 Activator\cf0 .CreateInstance(theType);\par ??        \}\par ??    \}}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: 2px solid black; padding: 5px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;PluginFactory&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;ICodeBlogPlugin&lt;/span&gt; LoadPlugin(&lt;span style="color: blue;"&gt;string&lt;/span&gt; pluginName)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Type&lt;/span&gt; theType = &lt;span style="color: #2b91af;"&gt;Type&lt;/span&gt;.GetType(pluginName);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; (&lt;span style="color: #2b91af;"&gt;ICodeBlogPlugin&lt;/span&gt;)&lt;span style="color: #2b91af;"&gt;Activator&lt;/span&gt;.CreateInstance(theType);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;Of course, in actual production code, there needs to be exception handling implemented, but this was just some quick test code. Eventually, I will write a plugin loader framework and configuration file, but for now, quickly mocking up some code to test load the plugin was trivial:&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red43\green145\blue175;\red255\green255\blue255;\red0\green0\blue0;\red163\green21\blue21;}??\fs20 \cf1 ICodeBlogPlugin\cf0  TestPlugin;\par ??TestPlugin = \cf1 PluginFactory\cf0 .LoadPlugin(\cf4 "CodeBlog.TestPlugin.TestPluginClass,CodeBlog.TestPlugin"\cf0 );\par ??TestPlugin.Render();}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: 2px solid black; padding: 5px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;ICodeBlogPlugin&lt;/span&gt; TestPlugin;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;TestPlugin = &lt;span style="color: #2b91af;"&gt;PluginFactory&lt;/span&gt;.LoadPlugin(&lt;span style="color: #a31515;"&gt;"CodeBlog.TestPlugin.TestPluginClass,CodeBlog.TestPlugin"&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;TestPlugin.Render();&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;The potential here is great. A developer can implement the ICodeBlogPlugin interface and create a plug-in that will work directly in CodeBlog. A end user will only have to drop the DLL into the /bin directory and add the assembly name to a configuration file and the plug-in will be ready to use.&lt;br /&gt;&lt;br /&gt;This is definitly a fun feature that I hope will be leveraged to its full potential.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-5719871700953509237?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2007/12/extending-your-application-by-creating.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-4833195933726549383</guid><pubDate>Fri, 30 Nov 2007 03:27:00 +0000</pubDate><atom:updated>2007-11-29T21:27:25.027-08:00</atom:updated><title>Microsoft and Innovation</title><description>The commenter's on &lt;a href="http://www.codinghorror.com/blog/archives/001006.html"&gt;Jeff Atwoods latest post&lt;/a&gt; tend to fall into two camps. On one side you have the people who make their living with Microsoft products, most of them are also open source advocates, without being mouth breathing fan boys. &lt;br /&gt;&lt;br /&gt;On the flip side, you have the Anti-Microsoft trolls. These people are often there just to take potshots at Microsoft. Ironically, most of them can not agree on what technology they do endorse, considering the amount of flame that goes around on the popular open source haunts.&lt;br /&gt;&lt;br /&gt;It is the latter camp that prompted Chris Pratley (A project manager for Microsoft Office) to write this on his &lt;a href="http://blogs.msdn.com/chris_pratley/archive/2004/04/27/120944.aspx"&gt;blog&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;I've been a little gun-shy of blogging about Word for fear of being inundated by what are as far as I can tell a gang of "net thugs" who roam the net making outrageous claims about Microsoft and its behavior, motives, etc in every public forum they find (little of which information they are privy to or have evidence for, and which I find personally offensive, not to mention incorrect - since they often are implicitly about me if the talk is about Office and therefore I for one know them to be incorrect). But enough about that - let's just dive in and see what happens. Hopefully the net-dwelling paranoid delusional conspiracy theorists won’t descend upon me… :-)&lt;/blockquote&gt;&lt;br /&gt;It doesn't take much wit to see past the trolls weak arguments, but I was particular struck be a reoccurring theme on Jeff comments.&lt;br /&gt;&lt;br /&gt;This theme in a nutshell was:&lt;br /&gt;&lt;blockquote&gt;"Microsoft does not Innovate, they only copy."&lt;/blockquote&gt;&lt;br /&gt;While this statement is laughably ridiculous, I thought I'd try to think of a handful of innovations that have come directly from Microsoft. Here, in no particular order, are just a few thing that the "evil empire" came up with first.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The Taskbar&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Popularized with Windows 95, the taskbar was actually a feature of Windows 1.0. A crude representation of active tasks laid were represented in a horizontal bar on the bottom of the screen. This was two years early than the Acorn Author operating environment that many Anti-Microsoft people cite as the first task bar. The taskbar was gone from Windows until Windows 95. &lt;br /&gt;&lt;br /&gt;In the early 90's, I had a chance to tour the Microsoft Redmond campus, and play with what was then known as Cairo. While Cairo never saw the light of day, its unique user interface was carried over for Windows 95.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Real Time Spell Checking&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;This was first featured in Microsoft Word 6.0, and has since been incorporated into every word processing program on the planet. &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Rapid Application Development&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;RAD was a hugely popular industry buzzword during the 90's, and it was born with Microsoft Visual Basic. &lt;br /&gt;&lt;br /&gt;Introduced in 1991, Visual Basic was a innovative new way to rapidly develop applications and it turned the programming industry on its head. The closest competitor to Visual Basic (Borland Delphi) was not released until 1995.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;OLE and COM&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;OLE was originally designed by Microsoft in 1990 by the Microsoft Office team out of necessity. It was used to allow real time embedding of Excel documents into Word, and vice versa. This paved the way for what became known as COM (Component Object Model) a technology that allowed any COM compliant object to be used by any application. COM allowed reuse of objects with no knowledge of their internal implementation because it provided interfaces that are separate from implementation. &lt;br /&gt;&lt;br /&gt;COM is heavily adopted and is used in nearly every windows application even to this day and was actually imitated by the open source movement with CORBA.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;.NET and the Microsoft CLR (and DLR)&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The CLR (Common Language Runtime) was not the first JIT compiling virtual machine, but it was innovative because it allowed an application to be built in any .NET language (or a combination of them) with seamless integration. Want to use VB for the front end, C# for the database layer, and C++ for some intensive graphics calculations? No problem!&lt;br /&gt;&lt;br /&gt;The DLR continues this practice by creating a platform for dynamically typed languages such as Ruby and Python.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Active Desktop&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Introduced with IE 4.0 and Windows 98 and powered by COM/ActiveX technology, Active Desktop was Microsoft's vision of integrating desktop applications with web applications.&lt;br /&gt;&lt;br /&gt;Litigation kept Microsoft from fully leveraging the concept, but the idea lives on now in many open source projects :)&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;XMLHTTPRequest and AJAX&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Believe it or not, the radical technology that changed the web and the technology that powers Gmail was stuck into IE 4.0 without any fanfare.&lt;br /&gt;&lt;br /&gt;The Microsoft Outlook team needed a way to communicate behind the scenes on their new Microsoft Web Mail client, so they built an ActiveX component for IE 4.0. This little component remained under the radar for several years, before the rest of the world discovered its power and AJAX was born.&lt;br /&gt;&lt;br /&gt;I wonder if Google has ever said "thank you".&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Windows Powershell&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Powershell is the long awaiting replacement for the default windows shell and is different from any scripting shell environment ever created. &lt;br /&gt;&lt;br /&gt;Scripting is fully object oriented by leveraging the .NET CLR. Objects (known as cmdlets) can have their output piped with a single keystroke. If you have not had a chance to check out PowerShell yet, check it out. It is amazing.&lt;br /&gt;&lt;br /&gt;This is just the tip of the iceberg on Microsoft innovations. Microsoft employs some of the brightest minds in the industry, and they and throw out more innovations every day than any of the Anti-Microsoft trolls have ever come up with.&lt;br /&gt;&lt;br /&gt;So, regardless of what operating system you are reading this post on. Next time you visit an AJAX enabled website, or correct your spelling in a document, remember that Microsoft innovation is the reason you have it, and perhaps give them a the credit they do deserve.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-4833195933726549383?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2007/11/microsoft-and-innovation.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">18</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-8855735845414602067</guid><pubDate>Wed, 28 Nov 2007 03:34:00 +0000</pubDate><atom:updated>2007-11-27T20:20:42.273-08:00</atom:updated><title>Linux killed the One Laptop Per Child project</title><description>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_I914lDmRUzA/R0zlE3JyKEI/AAAAAAAAAAQ/iL5MFwnvATE/s1600-h/olpc.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_I914lDmRUzA/R0zlE3JyKEI/AAAAAAAAAAQ/iL5MFwnvATE/s320/olpc.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5137733146610116674" /&gt;&lt;/a&gt;&lt;br /&gt;Unless you have been living under a rock, you have probably heard of the One Laptop Per Child foundation. &lt;br /&gt;&lt;br /&gt;Their goal was to develop a $100 laptop (Called the XO) and give it to children in developing countries . The project was highly heralded and many governments signed on to buy thousands of these laptops.&lt;br /&gt;&lt;br /&gt;Part of the concept was to use Linux as the base operating system, partially to avoid having to pay licensing costs for Microsoft Windows, and also to develop a custom environment that children who were not familiar with computers would find easy to use.&lt;br /&gt;&lt;br /&gt;The end result was a interface called "Sugar" that was unlike any known computer interface in the developed world. Written in Python, it was definitly unique, though some people find its UI &lt;a href="http://dev.laptop.org/ticket/4908"&gt;strange and counterintuitive&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;After all the fanfare, the foundation was not able to meet the $100 goal, and is now offering the laptop for close to $200. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_I914lDmRUzA/R0zon3JyKFI/AAAAAAAAAAY/mAazEXVTLco/s1600-h/TR-Classmate-3485.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_I914lDmRUzA/R0zon3JyKFI/AAAAAAAAAAY/mAazEXVTLco/s320/TR-Classmate-3485.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5137737046440421458" /&gt;&lt;/a&gt;&lt;br /&gt;At that price, it competes directly with the Intel Classmate. A similar laptop that is available with either Linux or Windows XP.&lt;br /&gt;&lt;br /&gt;It is no surprise that countries are now backtracking on their promises to order large quantities of the XO. Many people are blaming the windows powered Classmate for the XO's demise. I believe it is the opposite, the XO's demise was the fact that it was a proprietary Linux machine with a unusual interface.&lt;br /&gt;&lt;br /&gt;Children are the future of developing countries, and the leaders of these countries want to adopt modern first world ways. &lt;br /&gt;&lt;br /&gt;Dumbing down a laptop does not teach these children any essential skills that they can use in the future. &lt;br /&gt;&lt;br /&gt;A generic laptop running a widely used operating system does. The learning curve may be steeper, but my four year old daughter was able to teach herself how to navigate around a web browser to access her favorite kid sites. If my four year old can, than any kid could.&lt;br /&gt;&lt;br /&gt;Government leaders don't want to hold their country back with a useless and limited device, they want the children to be ready to enter the first world prepared.&lt;br /&gt;&lt;br /&gt;The XO is nothing but a limited and fancy toy. It was an excellent vision, but I believe the zeal of creating a radical new experience was its downfall.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-8855735845414602067?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2007/11/linux-killed-one-laptop-per-child.html</link><author>noreply@blogger.com (Jonathan Holland)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_I914lDmRUzA/R0zlE3JyKEI/AAAAAAAAAAQ/iL5MFwnvATE/s72-c/olpc.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">17</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-655647465167995795</guid><pubDate>Tue, 27 Nov 2007 02:46:00 +0000</pubDate><atom:updated>2007-11-26T19:05:03.241-08:00</atom:updated><title>There is no point in Client Side Hashing</title><description>A while back, &lt;a href="http://www.codinghorror.com/blog/archives/000953.html"&gt;Jeff Atwood&lt;/a&gt; blogged about password security. His post caused a good bit of controversy and the comments and back links highlighted that the concept of password security is poorly understood by most developers.&lt;br /&gt;&lt;br /&gt;I found the chaos somewhat amusing, as I was already been using a technique of Hash(SALT + ClearText) for my projects.&lt;br /&gt;&lt;br /&gt;The reason for using a SALT is to create a long enough hash to make it impossible to break with a rainbow table. The salt does not have to be unique, though that does not hurt. The salt can be public, there is no need to conceal it.&lt;br /&gt;&lt;br /&gt;I was recently examining a Vbulletin forum's Javascript code when I noticed that the login code performs a MD5 hash on the password &lt;span style="font-weight:bold;"&gt;on the client&lt;/span&gt;, before submitting the hashed password back to the server.&lt;br /&gt;&lt;br /&gt;I am sure the original developer who wrote that was concerned about a clear text password being intercepted, and thought his clever scheme of hashing would fix that.&lt;br /&gt;&lt;br /&gt;It didn't. It only made it worse.&lt;br /&gt;&lt;br /&gt;The server side validation code is expecting a hash, if someone were to intercept the hash, they are as home free as having the clear text password sent. It is trivial to use FireBug to override Javascript and submit a form manually.&lt;br /&gt;&lt;br /&gt;So at best, client side hashing does not improve the situation at all, however it also exposes the hashing technique used (And in the case of Vbulletin, uses one of the weakest, most flawed techniques known: MD5).&lt;br /&gt;&lt;br /&gt;This means that even if you are using a server side salt, the attacker now has a good guess towards the hash algorithm used, and won't have to waste time generating rainbow tables for other algorithms.&lt;br /&gt;&lt;br /&gt;Overall, never hash on the client. &lt;span style="font-weight:bold;"&gt;Send your password in clear text*&lt;/span&gt;. If you are concerned about doing that, then the only thing you can do is HTTP Encryption using SSL.&lt;br /&gt;&lt;br /&gt;&lt;sup&gt;*Do hash and salt the password on the server though.&lt;/sup&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-655647465167995795?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2007/11/there-is-no-point-in-client-side.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">7</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-5081996164891512436</guid><pubDate>Sun, 25 Nov 2007 21:04:00 +0000</pubDate><atom:updated>2007-11-25T13:43:24.150-08:00</atom:updated><title>Adding RSS Syndication to CodeBlog</title><description>RSS stands for "Really Simple Syndication" and for once, it is a name that actually delivers.&lt;br /&gt;&lt;br /&gt;RSS has lots of features, however implementing it is dead easy. So easy in fact, that it took less than 10 minutes to add it to CodeBlog, and I had never worked with RSS before.&lt;br /&gt;&lt;br /&gt;The concept behind RSS is to provide a link that feed readers can access to get the latest content from a dynamic site.&lt;br /&gt;&lt;br /&gt;The RSS file is an XML document, with a minimalistic schema:&lt;br /&gt;&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red0\green0\blue0;\red255\green0\blue0;}??\fs20 \cf1 &amp;lt;\cf3 rss\cf0  \cf5 version\cf1 ="2.0"&amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 channel\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 title\cf1 &amp;gt;\cf0 Website Feed Title\cf1 &amp;lt;/\cf3 title\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 link\cf1 &amp;gt;\cf0 Website Feed URL\cf1 &amp;lt;/\cf3 link\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 description\cf1 &amp;gt;\cf0 Website Feed description\cf1 &amp;lt;/\cf3 description\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 ttl\cf1 &amp;gt;\cf0 Time in Minutes to Refresh Cache\cf1 &amp;lt;/\cf3 ttl\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 item\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 title\cf1 &amp;gt;\cf0 Post Subject/Title\cf1 &amp;lt;/\cf3 title\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 description\cf1 &amp;gt;\cf0 Post Description / Full Text of Post\cf1 &amp;lt;/\cf3 description\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 link\cf1 &amp;gt;\cf0 Permalink to Post\cf1 &amp;lt;/\cf3 link\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 pubDate\cf1 &amp;gt;\cf0 Date Published\cf1 &amp;lt;/\cf3 pubDate\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 item\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;/\cf3 channel\cf1 &amp;gt;\par ??&amp;lt;/\cf3 rss\cf1 &amp;gt;}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: 2px solid black; padding: 5px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;rss&lt;/span&gt; &lt;span style="color: red;"&gt;version&lt;/span&gt;&lt;span style="color: blue;"&gt;="2.0"&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;channel&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;title&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Website Feed Title&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;title&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;link&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Website Feed URL&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;link&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;description&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Website Feed description&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;description&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ttl&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Time in Minutes to Refresh Cache&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ttl&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;item&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;title&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Post Subject/Title&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;title&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;description&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Post Description / Full Text of Post&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;description&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;link&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Permalink to Post&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;link&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;pubDate&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Date Published&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;pubDate&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;item&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;channel&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;14&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;rss&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Of course, RSS has much more to it, but this all that is required to syndicate blog posts. For more information, take a look at the &lt;a href="http://cyber.law.harvard.edu/rss/rss.html#ltttlgtSubelementOfLtchannelgt"&gt;full specification&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To implement this in CodeBlog, I created a ASPX page called RSSFeed.aspx and removed all content except the Page directive.&lt;br /&gt;&lt;br /&gt;I used the Page_Load event in the code behind to generate the XML:&lt;br /&gt;&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red0\green0\blue0;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf1 protected\cf0  \cf1 void\cf0  Page_Load(\cf1 object\cf0  sender, \cf4 EventArgs\cf0  e)\par ??\{\par ??    Response.Clear();\par ??    Response.ContentType = \cf5 "text/xml"\cf0 ;\par ??    \cf4 XmlTextWriter\cf0  rssXml = \cf1 new\cf0  \cf4 XmlTextWriter\cf0 (Response.OutputStream,\cf4 Encoding\cf0 .UTF8);\par ??\par ??    rssXml.WriteStartDocument();\par ??\par ??    rssXml.WriteStartElement(\cf5 "rss"\cf0 );\par ??    rssXml.WriteAttributeString(\cf5 "version"\cf0 , \cf5 "2.0"\cf0 );\par ??    rssXml.WriteStartElement(\cf5 "channel"\cf0 );\par ??\par ??    rssXml.WriteElementString(\cf5 "title"\cf0 , CodeBlog.Configuration.\cf4 ConfigurationManager\cf0 .BlogTitle);\par ??    rssXml.WriteElementString(\cf5 "link"\cf0 , CodeBlog.Configuration.\cf4 ConfigurationManager\cf0 .BaseDomain);\par ??    rssXml.WriteElementString(\cf5 "description"\cf0 , CodeBlog.Configuration.\cf4 ConfigurationManager\cf0 .BlogDescription);\par ??    rssXml.WriteElementString(\cf5 "ttl"\cf0 , \cf5 "60"\cf0 );\par ??\par ??    \cf4 PostCollection\cf0  posts;\par ??\par ??    posts = \cf4 PostService\cf0 .GetMostRecentPosts(10);\par ??\par ??    \cf1 foreach\cf0  (\cf4 Post\cf0  post \cf1 in\cf0  posts)\par ??    \{\par ??        rssXml.WriteStartElement(\cf5 "item"\cf0 );\par ??        rssXml.WriteElementString(\cf5 "title"\cf0 , post.Subject);\par ??        rssXml.WriteElementString(\cf5 "description"\cf0 , post.Text);\par ??        rssXml.WriteElementString(\cf5 "link"\cf0 , \cf4 PostService\cf0 .GetPostURL(post.PostID));\par ??        rssXml.WriteElementString(\cf5 "pubDate"\cf0 , post.CreatedOn.ToShortDateString());\par ??        rssXml.WriteEndElement();\par ??    \}\par ??\par ??    rssXml.WriteEndElement();\par ??    rssXml.WriteEndElement();\par ??    rssXml.WriteEndDocument();\par ??    rssXml.Flush();\par ??    rssXml.Close();\par ??    Response.End();\par ??\}}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: 2px solid black; padding: 5px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Page_Load(&lt;span style="color: blue;"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af;"&gt;EventArgs&lt;/span&gt; e)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;{&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Response.Clear();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Response.ContentType = &lt;span style="color: #a31515;"&gt;"text/xml"&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;XmlTextWriter&lt;/span&gt; rssXml = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;XmlTextWriter&lt;/span&gt;(Response.OutputStream,&lt;span style="color: #2b91af;"&gt;Encoding&lt;/span&gt;.UTF8);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rssXml.WriteStartDocument();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rssXml.WriteStartElement(&lt;span style="color: #a31515;"&gt;"rss"&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rssXml.WriteAttributeString(&lt;span style="color: #a31515;"&gt;"version"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"2.0"&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rssXml.WriteStartElement(&lt;span style="color: #a31515;"&gt;"channel"&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rssXml.WriteElementString(&lt;span style="color: #a31515;"&gt;"title"&lt;/span&gt;, CodeBlog.Configuration.&lt;span style="color: #2b91af;"&gt;ConfigurationManager&lt;/span&gt;.BlogTitle);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;14&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rssXml.WriteElementString(&lt;span style="color: #a31515;"&gt;"link"&lt;/span&gt;, CodeBlog.Configuration.&lt;span style="color: #2b91af;"&gt;ConfigurationManager&lt;/span&gt;.BaseDomain);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;15&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rssXml.WriteElementString(&lt;span style="color: #a31515;"&gt;"description"&lt;/span&gt;, CodeBlog.Configuration.&lt;span style="color: #2b91af;"&gt;ConfigurationManager&lt;/span&gt;.BlogDescription);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;16&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rssXml.WriteElementString(&lt;span style="color: #a31515;"&gt;"ttl"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"60"&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;17&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;18&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;PostCollection&lt;/span&gt; posts;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;19&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;20&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; posts = &lt;span style="color: #2b91af;"&gt;PostService&lt;/span&gt;.GetMostRecentPosts(10);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;21&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;22&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af;"&gt;Post&lt;/span&gt; post &lt;span style="color: blue;"&gt;in&lt;/span&gt; posts)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;23&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;24&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; rssXml.WriteStartElement(&lt;span style="color: #a31515;"&gt;"item"&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;25&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; rssXml.WriteElementString(&lt;span style="color: #a31515;"&gt;"title"&lt;/span&gt;, post.Subject);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;26&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; rssXml.WriteElementString(&lt;span style="color: #a31515;"&gt;"description"&lt;/span&gt;, post.Text);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;27&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; rssXml.WriteElementString(&lt;span style="color: #a31515;"&gt;"link"&lt;/span&gt;, &lt;span style="color: #2b91af;"&gt;PostService&lt;/span&gt;.GetPostURL(post.PostID));&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;28&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; rssXml.WriteElementString(&lt;span style="color: #a31515;"&gt;"pubDate"&lt;/span&gt;, post.CreatedOn.ToShortDateString());&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;29&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; rssXml.WriteEndElement();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;30&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;31&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;32&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rssXml.WriteEndElement();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;33&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rssXml.WriteEndElement();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;34&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rssXml.WriteEndDocument();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;35&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rssXml.Flush();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;36&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rssXml.Close();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;37&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Response.End();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;38&lt;/span&gt;&amp;nbsp;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The .NET framework has excellent built in XML tools so there is no need to worry about outputting valid XML, the framework does it for you. &lt;br /&gt;&lt;br /&gt;The foreach loop creates an &amp;lt;item&amp;gt; element for each blog post returned by the business object.&lt;br /&gt;&lt;br /&gt;Overall, RSS has been the easiest feature I have added to CodeBlog to date. The actual blog engine will be available in open source form for download next week.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-5081996164891512436?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2007/11/adding-rss-syndication-to-codeblog.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-1204958965175982963</guid><pubDate>Sat, 24 Nov 2007 22:15:00 +0000</pubDate><atom:updated>2007-11-24T15:05:20.219-08:00</atom:updated><title>Community Matters</title><description>It is difficult to blog on ASP.NET. &lt;br /&gt;&lt;br /&gt;Many of the times that I submitted a blog post to the popular social networks (&lt;a href="http://www.digg.com"&gt;Digg&lt;/a&gt;, &lt;a href="http://www.reddit.com"&gt;Reddit&lt;/a&gt;, &lt;a href="http://www.dzone.com"&gt;Dzone&lt;/a&gt; etc) it gets buried by open source advocates, yet they don't even bother to click through to read it. The internet is definitly skewed in a unfairly biased anti Microsoft light.&lt;br /&gt;&lt;br /&gt;However, there are places where Microsoft topic blogging is welcome. Sites such as &lt;a href="http://www.dotnetkicks.com"&gt;DotNetKicks&lt;/a&gt; provide a refuge and community for the small and dedicated group of Microsoft programmers.&lt;br /&gt;&lt;br /&gt;So I was very surprised to be &lt;a href="http://www.sitepoint.com/blogs/2007/11/25/keep-your-template-logic-in-the-template/"&gt;attacked&lt;/a&gt; by a fellow ASP.NET programmer today regarding yesterdays blog post. &lt;br /&gt;&lt;br /&gt;Its absolutely fine to disagree with someone on a professional level. We programmers are an opinionated bunch, however there is no reason to be rude or arrogant... Especially when you are incorrect :)&lt;br /&gt;&lt;br /&gt;One of the best attributes of the .NET community is the maturity level of the active participators. Sure, &lt;a href="http://blog.wekeroad.com/2007/10/10/imploding-rails-jesus-dhh-and-the-uncle-ben-principle/"&gt;Rob Conery&lt;/a&gt; might have pissed a few people off, but at least his reaction was to the sheer immaturity of DHH and his Ruby crowd.&lt;br /&gt;&lt;br /&gt;We are ASP.NET developers. Most of us are professionals, some of us are &lt;a href="http://weblogs.asp.net/scottgu/"&gt;Gods&lt;/a&gt;. We are all above acting like children*.&lt;br /&gt;&lt;br /&gt;If you break it all down, all web developers have a common interest. &lt;b&gt;We just choose different routes to accomplish our goal&lt;/b&gt;. It is time to end the petty name calling and arguments between different camps. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://gilesbowkett.blogspot.com/2007/11/why-i-program-in-ruby-and-maybe-why-you.html"&gt;Giles Bowkett&lt;/a&gt; gets it:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Don't program in Ruby because you want power or efficiency. Don't program in Ruby because you think you "should", either. Program in Ruby because you like it. And if you don't like it, don't program in it. Religious wars over programming languages are just silly. The messianic zeal of Christianity's shameful Crusades a thousand years ago still lingers on in Western culture, and one glaring example is the ludicrous idea that there should be one true language or one true editor, or one ring to rule them all. It's much better when programmers can work in multiple languages, multiple editors, and multiple environments. Diversity is healthy for ecologies. This is a point Neal makes in his podcast - he calls it polyglot programming, which is to say multilingual programming. He calls it a positive trend, and I agree.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I challenge all developers to blog on what they love, without trashing what they don't. Spend your time creating masterpieces in the technology you use. Together, we can create innovations that will change the internet.&lt;br /&gt;&lt;br /&gt;&lt;small&gt;* Yes, I am guilty of this too.&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-1204958965175982963?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2007/11/community-matters.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-1865320831995777185</guid><pubDate>Fri, 23 Nov 2007 23:29:00 +0000</pubDate><atom:updated>2007-11-25T11:24:39.835-08:00</atom:updated><title>Keep Presentation and Logic Separate!</title><description>&lt;span style="color: red;"&gt;Update:&lt;/span&gt; One of my commenters dedicated an entire blog post on attacking this technique, prompting me to write &lt;a href="http://codeeleven.blogspot.com/2007/11/community-matters.html"&gt;this&lt;/a&gt; response.&lt;br /&gt;&lt;br /&gt;ASP.NET somewhat emulates the MVC architecture with its code behind web forms. For those who are not familiar, each web form consists of two files; The ASPX file used for defining the appearance of the page (View), and a code behind file is used to implement the page logic (Controller).&lt;br /&gt;&lt;br /&gt;For the most part, it is easy to keep a clean separation of concerns between the two files. However, I repeatedly see inline code mixed in with presentation when people are using data bound controls.&lt;br /&gt;&lt;br /&gt;An example would be the ASP:Repeater control. In a nutshell, the repeater control allows you to create a template and populate it with data from any databindable source (Be it a DataSet, a DataReader, or even a custom collection).&lt;br /&gt;&lt;br /&gt;A common implementation of the ASP:Repeater would be similar to this code from an early version of CodeBlog:&lt;br /&gt;&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset229\fprq1 Consolas;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red0\green0\blue0;\red255\green0\blue0;\red255\green238\blue98;\red43\green145\blue175;}??\fs20 \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Repeater\cf0  \cf5 ID\cf1 ="rptrComment"\cf0  \cf5 runat\cf1 ="server"&amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 div\cf0  \cf5 class\cf1 ="comment-body"&amp;gt;\par ??\cf0             \cb6\highlight6 &amp;lt;%\cf1\cb0\highlight0 #\cf0  \cf7 DataBinder\cf0 .Eval(Container.DataItem, \cf3 "CommentText"\cf0 ) \cb6\highlight6 %&amp;gt;\par ??\cb0\highlight0             \cf1 &amp;lt;\cf3 div\cf0  \cf5 class\cf1 ="comment-name"&amp;gt;\par ??\cf0                 \cf1 &amp;lt;\cf3 a\cf0  \cf5 href\cf1 ="\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # DataBinder.Eval(Container.DataItem,"AuthorWeb") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 "&amp;gt;\par ??\cf0                     \cb6\highlight6 &amp;lt;%\cf1\cb0\highlight0 #\cf0  \cf7 DataBinder\cf0 .Eval(Container.DataItem, \cf3 "AuthorName"\cf0 ) \cb6\highlight6 %&amp;gt;\par ??\cb0\highlight0                 \cf1 &amp;lt;/\cf3 a\cf1 &amp;gt;\par ??\cf0                 - \cb6\highlight6 &amp;lt;%\cf1\cb0\highlight0 #\cf0  \cf7 DataBinder\cf0 .Eval(Container.DataItem, \cf3 "ShortDateTime"\cf0 ) \cb6\highlight6 %&amp;gt;\par ??\cb0\highlight0             \cf1 &amp;lt;/\cf3 div\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 div\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;/\cf3 ItemTemplate\cf1 &amp;gt;\par ??&amp;lt;/\cf3 asp\cf1 :\cf3 Repeater\cf1 &amp;gt;}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: 2px solid black; padding: 5px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;asp&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Repeater&lt;/span&gt; &lt;span style="color: red;"&gt;ID&lt;/span&gt;&lt;span style="color: blue;"&gt;="rptrComment"&lt;/span&gt; &lt;span style="color: red;"&gt;runat&lt;/span&gt;&lt;span style="color: blue;"&gt;="server"&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ItemTemplate&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;div&lt;/span&gt; &lt;span style="color: red;"&gt;class&lt;/span&gt;&lt;span style="color: blue;"&gt;="comment-body"&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background: #ffee62;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue;"&gt;#&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;DataBinder&lt;/span&gt;.Eval(Container.DataItem, &lt;span style="color: #a31515;"&gt;"CommentText"&lt;/span&gt;) &lt;span style="background: #ffee62;"&gt;%&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;div&lt;/span&gt; &lt;span style="color: red;"&gt;class&lt;/span&gt;&lt;span style="color: blue;"&gt;="comment-name"&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;a&lt;/span&gt; &lt;span style="color: red;"&gt;href&lt;/span&gt;&lt;span style="color: blue;"&gt;="&lt;/span&gt;&lt;span style="background: #ffee62;"&gt;&amp;lt;%&lt;/span&gt;# DataBinder.Eval(Container.DataItem,"AuthorWeb") &lt;span style="background: #ffee62;"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;"&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background: #ffee62;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue;"&gt;#&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;DataBinder&lt;/span&gt;.Eval(Container.DataItem, &lt;span style="color: #a31515;"&gt;"AuthorName"&lt;/span&gt;) &lt;span style="background: #ffee62;"&gt;%&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;a&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; - &lt;span style="background: #ffee62;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue;"&gt;#&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;DataBinder&lt;/span&gt;.Eval(Container.DataItem, &lt;span style="color: #a31515;"&gt;"ShortDateTime"&lt;/span&gt;) &lt;span style="background: #ffee62;"&gt;%&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;div&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;div&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ItemTemplate&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;asp&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Repeater&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This repeater was bound to the Comment custom collection I wrote from CodeBlog's business objects. While it works flawlessly, we are embedding inline code to loosely bind our collection to the fields we want outputted.&lt;br /&gt;&lt;br /&gt;The ItemDataBound event is fired every time the repeater binds an item. By catching this event, we can move all of our code to the code behind file where it belongs. We can also add some logic (such as suppressing the hyper link if we don't have a website in the comment object).&lt;br /&gt;&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset229\fprq1 Consolas;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red0\green0\blue0;\red255\green0\blue0;}??\fs20 \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Repeater\cf0  \cf5 ID\cf1 ="rptrComment"\cf0  \cf5 runat\cf1 ="server"&amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 div\cf0  \cf5 class\cf1 ="comment-body"&amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Literal\cf0  \cf5 ID\cf1 ="litCommentText"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf1 /&amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 div\cf0  \cf5 class\cf1 ="comment-name"&amp;gt;\par ??\cf0                 \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 HyperLink\cf0  \cf5 id\cf1 ="hplCommentAuthor"\cf0  \cf5 runat\cf1 ="server"&amp;gt;\cf0                        \par ??                    \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="lblCommentAuthorName"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf1 /&amp;gt;\cf0                             \par ??                \cf1 &amp;lt;/\cf3 asp\cf1 :\cf3 HyperLink\cf1 &amp;gt;\par ??\cf0                 - \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="lblCommentDateTime"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf1 /&amp;gt;\par ??\cf0             \cf1 &amp;lt;/\cf3 div\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 div\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;/\cf3 ItemTemplate\cf1 &amp;gt;\par ??&amp;lt;/\cf3 asp\cf1 :\cf3 Repeater\cf1 &amp;gt;\par ??\par ??}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: 2px solid black; padding: 5px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;asp&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Repeater&lt;/span&gt; &lt;span style="color: red;"&gt;ID&lt;/span&gt;&lt;span style="color: blue;"&gt;="rptrComment"&lt;/span&gt; &lt;span style="color: red;"&gt;runat&lt;/span&gt;&lt;span style="color: blue;"&gt;="server"&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ItemTemplate&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;div&lt;/span&gt; &lt;span style="color: red;"&gt;class&lt;/span&gt;&lt;span style="color: blue;"&gt;="comment-body"&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;asp&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Literal&lt;/span&gt; &lt;span style="color: red;"&gt;ID&lt;/span&gt;&lt;span style="color: blue;"&gt;="litCommentText"&lt;/span&gt; &lt;span style="color: red;"&gt;runat&lt;/span&gt;&lt;span style="color: blue;"&gt;="server"&lt;/span&gt; &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;div&lt;/span&gt; &lt;span style="color: red;"&gt;class&lt;/span&gt;&lt;span style="color: blue;"&gt;="comment-name"&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;asp&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: #a31515;"&gt;HyperLink&lt;/span&gt; &lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;="hplCommentAuthor"&lt;/span&gt; &lt;span style="color: red;"&gt;runat&lt;/span&gt;&lt;span style="color: blue;"&gt;="server"&amp;gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;asp&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Label&lt;/span&gt; &lt;span style="color: red;"&gt;ID&lt;/span&gt;&lt;span style="color: blue;"&gt;="lblCommentAuthorName"&lt;/span&gt; &lt;span style="color: red;"&gt;runat&lt;/span&gt;&lt;span style="color: blue;"&gt;="server"&lt;/span&gt; &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;asp&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: #a31515;"&gt;HyperLink&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; - &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;asp&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Label&lt;/span&gt; &lt;span style="color: red;"&gt;ID&lt;/span&gt;&lt;span style="color: blue;"&gt;="lblCommentDateTime"&lt;/span&gt; &lt;span style="color: red;"&gt;runat&lt;/span&gt;&lt;span style="color: blue;"&gt;="server"&lt;/span&gt; &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;div&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;div&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ItemTemplate&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;asp&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Repeater&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;14&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The main difference between the two code snippets is that the inline code has been replaced with ASP.NET Server controls. We will populate these controls on each ItemDataBound event. With the inline code gone, the Repeater is much more concise and  this page will be easier to maintain in the future. &lt;br /&gt;&lt;br /&gt;In the code behind file, the first task is to capture the ItemDataBound event for the repeater. This is done by overriding OnInit (if you haven't already for some other reason) and adding the event handler callback:&lt;br /&gt;&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset229\fprq1 Consolas;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red0\green0\blue0;\red43\green145\blue175;}??\fs20 \cf1 protected\cf0  \cf1 override\cf0  \cf1 void\cf0  OnInit(\cf4 EventArgs\cf0  e)\par ??\{\par ??    \cf1 base\cf0 .OnInit(e);\par ??    rptrComment.ItemDataBound += \cf1 new\cf0  \cf4 RepeaterItemEventHandler\cf0 (rptrCommentsItemDataBound);\par ??\}}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: 2px solid black; padding: 5px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; OnInit(&lt;span style="color: #2b91af;"&gt;EventArgs&lt;/span&gt; e)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;{&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;base&lt;/span&gt;.OnInit(e);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rptrComment.ItemDataBound += &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;RepeaterItemEventHandler&lt;/span&gt;(rptrCommentsItemDataBound);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;With this done, we can implement a method to handle the event:&lt;br /&gt;&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset229\fprq1 Consolas;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red0\green0\blue0;\red43\green145\blue175;\red0\green128\blue0;\red163\green21\blue21;}??\fs20 \cf1 private\cf0  \cf1 void\cf0  rptrCommentsItemDataBound(\cf4 Object\cf0  Sender, \cf4 RepeaterItemEventArgs\cf0  e)\par ??\{\par ??    \cf5 // This event will be fired even for Header, Seperator, and Footer rows, so we ignore those\par ??\cf0     \cf1 if\cf0  (e.Item.ItemType == \cf4 ListItemType\cf0 .Item || e.Item.ItemType == \cf4 ListItemType\cf0 .AlternatingItem)\par ??    \{\par ??        \par ??        \cf5 // Item.DataItem contains the Item we are binding, in this case, the custom Business Object Comment\par ??\cf0         \cf5 // A simple cast is all that it takes to convert Item.DataItem into a Comment.\par ??\cf0         \cf4 Comment\cf0  currentComment = (\cf4 Comment\cf0 ) e.Item.DataItem;\par ??\par ??        \cf5 // We have to create references to the controls in the Repeater using FindControl\par ??\cf0         \cf4 Literal\cf0  CommentText = (\cf4 Literal\cf0 )e.Item.FindControl(\cf6 "litCommentText"\cf0 );\par ??        \cf4 Label\cf0  CommentAuthorName = (\cf4 Label\cf0 )e.Item.FindControl(\cf6 "lblCommentAuthorName"\cf0 );\par ??        \cf4 Label\cf0  CommentDateTime = (\cf4 Label\cf0 )e.Item.FindControl(\cf6 "lblCommentDateTime"\cf0 );\par ??        \cf4 HyperLink\cf0  CommentAuthor = (\cf4 HyperLink\cf0 )e.Item.FindControl(\cf6 "hplCommentAuthor"\cf0 );\par ??\par ??        \cf5 // Populate the Controls with Data from the Comment Object\par ??\cf0         CommentText.Text = currentComment.Text;\par ??        CommentAuthorName.Text = currentComment.AuthorName;\par ??        CommentDateTime.Text = currentComment.ShortDateTime;\par ??       \par ??        \cf5 // A little logic allows us to only populate the Hyperlink of we have a website stored.\par ??\cf0         \cf1 if\cf0  (currentComment.AuthorWeb != \cf1 string\cf0 .Empty)\par ??        \{\par ??            CommentAuthor.NavigateUrl = currentComment.AuthorWeb;\par ??        \}\par ??    \}\par ??\}}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border: 2px solid black; padding: 5px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; rptrCommentsItemDataBound(&lt;span style="color: #2b91af;"&gt;Object&lt;/span&gt; Sender, &lt;span style="color: #2b91af;"&gt;RepeaterItemEventArgs&lt;/span&gt; e)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;{&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// This event will be fired even for Header, Seperator, and Footer rows, so we ignore those&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (e.Item.ItemType == &lt;span style="color: #2b91af;"&gt;ListItemType&lt;/span&gt;.Item || e.Item.ItemType == &lt;span style="color: #2b91af;"&gt;ListItemType&lt;/span&gt;.AlternatingItem)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Item.DataItem contains the Item we are binding, in this case, the custom Business Object Comment&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// A simple cast is all that it takes to convert Item.DataItem into a Comment.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Comment&lt;/span&gt; currentComment = (&lt;span style="color: #2b91af;"&gt;Comment&lt;/span&gt;) e.Item.DataItem;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// We have to create references to the controls in the Repeater using FindControl&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Literal&lt;/span&gt; CommentText = (&lt;span style="color: #2b91af;"&gt;Literal&lt;/span&gt;)e.Item.FindControl(&lt;span style="color: #a31515;"&gt;"litCommentText"&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Label&lt;/span&gt; CommentAuthorName = (&lt;span style="color: #2b91af;"&gt;Label&lt;/span&gt;)e.Item.FindControl(&lt;span style="color: #a31515;"&gt;"lblCommentAuthorName"&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;14&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Label&lt;/span&gt; CommentDateTime = (&lt;span style="color: #2b91af;"&gt;Label&lt;/span&gt;)e.Item.FindControl(&lt;span style="color: #a31515;"&gt;"lblCommentDateTime"&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;15&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;HyperLink&lt;/span&gt; CommentAuthor = (&lt;span style="color: #2b91af;"&gt;HyperLink&lt;/span&gt;)e.Item.FindControl(&lt;span style="color: #a31515;"&gt;"hplCommentAuthor"&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;16&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;17&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Populate the Controls with Data from the Comment Object&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;18&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; CommentText.Text = currentComment.Text;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;19&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; CommentAuthorName.Text = currentComment.AuthorName;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;20&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; CommentDateTime.Text = currentComment.ShortDateTime;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;21&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;22&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// A little logic allows us to only populate the Hyperlink of we have a website stored.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;23&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (currentComment.AuthorWeb != &lt;span style="color: blue;"&gt;string&lt;/span&gt;.Empty)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;24&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;25&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; CommentAuthor.NavigateUrl = currentComment.AuthorWeb;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;26&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;27&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;28&lt;/span&gt;&amp;nbsp;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The code comments explain the technique fairly well. To summorize, each time the event is fired, Item.DataItem returns a unique Comment object. At that point, it is a trivial matter of setting the Server controls properties with information obtained by the object.&lt;br /&gt;&lt;br /&gt;By making these small changes, I have moved all of the logic into the code behind file where it belongs making ASPX file easier to follow. I was also able to add some conditional logic on the databinding, and the result was a very easy to understand event handler. Overall, this creates clean code that is easy to understand and even easier to maintain.&lt;br /&gt;&lt;br /&gt;There is never a reason to use inline code when you are databinding. Keep a clean separation of concerns and keep your presentation layer and logic layer where they belong.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-1865320831995777185?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2007/11/keep-presentation-and-logic-seperate.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">7</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2370549018150398400.post-1470650697758019519</guid><pubDate>Thu, 22 Nov 2007 19:01:00 +0000</pubDate><atom:updated>2007-11-22T11:40:14.030-08:00</atom:updated><title>A Special Thanksgiving</title><description>I started this blog two weeks ago dedicated to writing a blog post a day. However, I was only able to keep up at that pace for one week. It was a productive week though, with almost 10,000 unique visitors, and a lot of healthy discussion.&lt;br /&gt;&lt;br /&gt;Those of you who have subscribed may have wondered why I have not posted for the last few days.&lt;br /&gt;&lt;br /&gt;On Sunday, my wife was induced into labor and we had our 2nd child, Connor, at 3:30 AM Monday morning after about 18 hours of labor.&lt;br /&gt;&lt;br /&gt;So, as you can imagine, We have been rather busy :)&lt;br /&gt;&lt;br /&gt;Happy Thanksgiving to all, and this blog will be back to its regular daily postings tomorrow.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2370549018150398400-1470650697758019519?l=codeeleven.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://codeeleven.blogspot.com/2007/11/special-thanksgiving.html</link><author>noreply@blogger.com (Jonathan Holland)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item></channel></rss>
