<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3640798027160825921</id><updated>2024-09-09T01:02:20.697-07:00</updated><category term="Asp.Net"/><category term="WebDevelopment"/><category term="Development"/><category term="WebDevelopment Asp.Net"/><category term=".NET 4.0"/><category term="C#"/><category term="Cloud Computing"/><category term="DeepZoom"/><category term="Development Rant Adwords-Api"/><category term="Form"/><category term="MacBook"/><category term="Morallity"/><category term="NCacheD"/><category term="Objective-C"/><category term="PostBack"/><category term="SEO"/><category term="Silverlight"/><category term="Team"/><category term="User Controls"/><category term="dynamic"/><title type='text'>Random Web Developer</title><subtitle type='html'>Ramblings about programming in ASP.NET with c# and other random things.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>21</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-2407755729197454886</id><published>2010-03-10T11:19:00.001-08:00</published><updated>2010-03-10T11:19:59.017-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Development"/><category scheme="http://www.blogger.com/atom/ns#" term="NCacheD"/><title type='text'>NCacheD (Part 1)</title><content type='html'>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;NCacheD (pronounced N-cache-D) is live on CodePlex at &lt;a href=&quot;http://NCacheD.codeplex.com&quot;&gt;http://NCacheD.codeplex.com&lt;/a&gt;. The original intent of this project was to create a very simple, bare bones distributed cache system. It was meant to be an exploration into how such a system works and how it could be implemented in .NET. And to provide a skeleton for a more powerful cache system in the future.&lt;/p&gt;  &lt;p&gt;&lt;img align=&quot;right&quot; src=&quot;http://farm4.static.flickr.com/3034/2289793935_ff33ac222a.jpg&quot; width=&quot;241&quot; height=&quot;184&quot; /&gt;As far as distributed cache systems go, Memcached and Velocity are the main options in .NET and NCacheD is intended to be another alternative. Memcached is known for it&#39;s raw speed and Velocity (or I think it&#39;s now called AppFabric caching) seems more intended for cloud computing (this might be inaccurate but at this time it&#39;s still only RC.)&lt;/p&gt;  &lt;p&gt;Memcached gets it&#39;s speed from being small and being written in C. That has it&#39;s advantages for sure but for a .NET shop and .NET developers it can also be problematic. It can be hard for non-C developers to understand exactly what&#39;s going on with C code. And it can be even harder to modify and fit to your specific needs. If you want to run the code as-is, I think this is fine but if you want to integrate it into your system and especially into your code base, you want to use the same platform.&lt;/p&gt;  &lt;p&gt;When I started thinking about how a distributed cache system must work I saw two important pieces or hurdles to overcome: the cache server must know the size of the objects it&#39;s holding so that the total size can be controlled to ensure as little paging as possible (we want to keep it all in RAM), and it must ensure that different clients will communicate with the same server for the same key value. If client 1 has an object with key &amp;quot;products2010&amp;quot; on server 1 and client two has the same object with key &amp;quot;products2010&amp;quot; then not only are we wasting space, but we run into serious problems when client 1 updates the cache and client 2 is unaware of any changes to &amp;quot;products2010&amp;quot;.&lt;/p&gt;  &lt;p&gt;Determining the size of an object in C# is not a trivial task. Because it is all managed code, there is no way of counting the bytes on the stack or heap. But I realized that determining the size of the objects in a distributed cache system would be pretty easy. In order to send the objects over the wire, they must first be serialized. And the length of the resultant byte array was in effect, the &amp;quot;size&amp;quot; of the object. I could also store the object as a byte array on the server since the serve would never care about the actual type of the object.&lt;/p&gt;  &lt;p&gt;Ensuring that every cached item&#39;s key goes to the same server every time was also not too difficult. NCacheD uses a pretty simple method for doing this. It will check the total available size of each server (assuming all clients use all the same servers) and will &amp;quot;weigh&amp;quot; the servers by their sizes. It will then create a small lookup table of servers giving out slots based on weight. And when a request is made to determine the server by the key, the key is hashed, modulo, and used to determine the particular server. &lt;/p&gt;  &lt;p&gt;With these two parts figured out, the next step was to create a simple cache class for the server (which turned out to be a wrapper around a ConcurrentDictionary&amp;lt;&amp;gt;), a client/server networking system for which I used WCF to keep it simple, and then the rest was plumbing which was greatly simplified by the TPL (Task Parallel Library.)&lt;/p&gt;  &lt;p&gt;Next time I&#39;ll talk more about how the server is determined and the way the cache itself works.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/2407755729197454886/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2010/03/ncached-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/2407755729197454886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/2407755729197454886'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2010/03/ncached-part-1.html' title='NCacheD (Part 1)'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm4.static.flickr.com/3034/2289793935_ff33ac222a_t.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-7037681338669591052</id><published>2010-02-18T11:49:00.001-08:00</published><updated>2010-02-18T12:27:09.989-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Development Rant Adwords-Api"/><title type='text'>Consolidation, the Lost Art</title><content type='html'>&lt;p&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:verdana;&quot;&gt;While working with the Google AdWords API, I discovered a forgotten principle (or lost art) of software engineering. It is called “Consolidation”. This principle, I believe, must have somehow fallen through the cracks when people started talking about DRY, KISS, SRP, etc. But I believe it will revolutionize the way we write programs.&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:verdana;&quot;&gt;Up till now it was commonly thought that breaking logic apart into easily manageable pieces was a good way to build software. “Divide and conquer,” we said. We thought that having well-named, meaningful blocks of code was the best approach to take for creating flexible, maintainable applications. We always thought that two very simple lines of code would always be better than six that did the same thing.&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:verdana;&quot;&gt;We thought wrong.&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:verdana;&quot;&gt;The following description of “Consolidation” is taken from &lt;/span&gt;&lt;a title=&quot;http://code.google.com/apis/adwords/articles/migrating.html#consolidation&quot; href=&quot;http://code.google.com/apis/adwords/articles/migrating.html#consolidation&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:verdana;&quot;&gt;http://code.google.com/apis/adwords/articles/migrating.html#consolidation&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmmN922or1ciy1r7LjWpQLGPFwVllAyKAl0_k8V9L_eP7U7ifrgl5Hgsx-GBr0iaiUneOQ9lejFqF3Cq6d_RM7gGjucJ97JrvBP7kYERy-fKYOP9r8qhHdC5nacEdjNf-W-P-LUiV_mIg/s1600-h/image%5B8%5D.png&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiALIuTvr0AXJJh0B7cOy3R1FQ5o_SPV_7kn-JNliF5_ddySDzDR-FoRAqVwRAX1b0XGnexqQ1uS34I1NaDID-tSqVjOH8czHZFKQejW-vgtj3i_97Px7w1m0tOUF1F9nupDQvUM96gbxU/?imgmax=800&quot; width=&quot;782&quot; height=&quot;410&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/7037681338669591052/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2010/02/consolidation-lost-art.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/7037681338669591052'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/7037681338669591052'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2010/02/consolidation-lost-art.html' title='Consolidation, the Lost Art'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiALIuTvr0AXJJh0B7cOy3R1FQ5o_SPV_7kn-JNliF5_ddySDzDR-FoRAqVwRAX1b0XGnexqQ1uS34I1NaDID-tSqVjOH8czHZFKQejW-vgtj3i_97Px7w1m0tOUF1F9nupDQvUM96gbxU/s72-c?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-3395371830683602368</id><published>2010-01-25T11:49:00.001-08:00</published><updated>2010-01-25T11:49:52.549-08:00</updated><title type='text'>Inspiration</title><content type='html'>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;quot;the first chess program put into practice was designed by legendary British mathematician Alan Turing in 1952, and he didn&#39;t even have a computer! He processed the algorithm on pieces of paper and this &amp;quot;paper machine&amp;quot; played a competent game.&amp;quot; - &lt;a href=&quot;http://www.nybooks.com/articles/23592?utm_medium=email&amp;amp;utm_source=Emailmarketingsoftware&amp;amp;utm_content=728004955&amp;amp;utm_campaign=February112010issue+_+olrukk&amp;amp;utm_term=TheChessMasterandtheComputer&quot;&gt;Garry Kasparov&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;  </content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/3395371830683602368/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2010/01/inspiration.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/3395371830683602368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/3395371830683602368'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2010/01/inspiration.html' title='Inspiration'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-5669637457340385844</id><published>2009-09-29T09:16:00.001-07:00</published><updated>2009-09-29T09:17:00.083-07:00</updated><title type='text'>Learning a New Language</title><content type='html'>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Since I got my Mac, I&#39;ve been trying to learn Objective-C, Cocoa, Cocoa Touch, Xcode, and the rest of the iPhone development stack.&amp;#160; As I spend more and more time on this, I&#39;ve noticed some parallels between learning a new programming language and learning a new spoken language.&amp;#160; &lt;/p&gt;  &lt;p&gt;A few years back I moved to Central America and, among other things, learned Spanish.&amp;#160; Learning Spanish was a long, slow, difficult process.&amp;#160; At one point in the process (maybe a few months in) I realized that Spanish is not just a literal translation of English.&amp;#160; That is, you can&#39;t just translate the words from English to Spanish.&amp;#160; You also can&#39;t just translate the grammar from English to Spanish.&lt;/p&gt;  &lt;p&gt;Aside from the basic spelling and grammar rules, languages are made up of many things such as styles, idioms, phrases, mannerisms, local accents, dialects, and more.&amp;#160; Because of this, the trick to learning a new language (once you already have a basic understanding of the syntax and grammar) is to try and &lt;em&gt;think&lt;/em&gt; in the new language. You want to try and make the dialects and colloquialisms your own.&amp;#160; You don&#39;t want to just translate directly as your speaking as this usually leads to pidgin.&amp;#160; You want to fluently express yourself in this new language and be understood as well as possible.&lt;/p&gt;  &lt;p&gt;Translating this to learning a new programming language, you can see that just knowing the syntax and APIs of the new language is not enough. When writing code in a new language you want to own that new language.&amp;#160; You want the code to look like it was written by someone fluent and familiar with the language.&amp;#160; This will greatly improve the quality and maintainability of the code.&amp;#160; &lt;/p&gt;  &lt;p&gt;This means that when you learn a new programming language, you should learn the coding standards as well.&amp;#160; So when you write code in C#, it should look like C# and should not use hungarian notation.&amp;#160; And when you write code in Objective-C, it should use the Objective-C styles and it shouldn&#39;t look like .NET or anything else.&amp;#160; It can be difficult to adjust to different code/language styles but you haven&#39;t really learned the new language until you&#39;ve done so. &lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/5669637457340385844/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2009/09/learning-new-language.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/5669637457340385844'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/5669637457340385844'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2009/09/learning-new-language.html' title='Learning a New Language'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-8774741664266942112</id><published>2009-09-16T14:14:00.001-07:00</published><updated>2009-09-16T14:14:03.748-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Cloud Computing"/><category scheme="http://www.blogger.com/atom/ns#" term="WebDevelopment"/><title type='text'>How much to you trust Microsoft?</title><content type='html'>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Being a .NET (Microsoft stack) developer requires a substantial amount of trust in Microsoft.&amp;#160; I have to trust them to stay in business.&amp;#160; I have to trust that having in-depth knowledge of there technologies is a good economic decision for my years ahead.&amp;#160; I have to trust them to fix bugs in there software, trust the quality of their products like IIS, Windows server, Visual Studio, SQL Server, and others, and trust them to support the technologies I use for the foreseeable future.&amp;#160; I have to trust that the web sites I develop will work properly when running on their platform.&amp;#160; &lt;/p&gt;  &lt;p&gt;This is a lot of trust.&amp;#160; And Microsoft has been working hard for years to gain it.&amp;#160; But now they are asking for an entirely new level of trust.&amp;#160; With Microsoft&#39;s cloud computing services called &lt;a href=&quot;http://www.microsoft.com/azure/&quot;&gt;Azure&lt;/a&gt;, Microsoft is asking us to not only trust their software but their hardware as well.&amp;#160; They&#39;re now asking us to trust them to take care of all the infrastructure and to trust that everything will work just fine in their hands.&amp;#160; &lt;/p&gt;  &lt;p&gt;This is a big step.&amp;#160; And so I wonder if Scott Guthrie&#39;s &lt;a href=&quot;http://weblogs.asp.net/scottgu/archive/2009/09/15/announcing-the-microsoft-ajax-cdn.aspx&quot;&gt;announcement&lt;/a&gt; yesterday about putting &lt;a href=&quot;http://jquery.com/&quot;&gt;jQuery&lt;/a&gt; and &lt;a href=&quot;http://www.asp.net/ajax/&quot;&gt;Ajax.NET&lt;/a&gt; on their new &lt;a href=&quot;http://www.asp.net/ajax/cdn/&quot;&gt;Ajax CDN&lt;/a&gt; is not just an act of goodwill but is also intended to help build trust in Microsoft hosted web content.&amp;#160; Maybe it&#39;s a bit of both.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/8774741664266942112/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2009/09/how-much-to-you-trust-microsoft.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/8774741664266942112'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/8774741664266942112'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2009/09/how-much-to-you-trust-microsoft.html' title='How much to you trust Microsoft?'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-3040473852585851616</id><published>2009-09-11T11:23:00.001-07:00</published><updated>2009-09-11T11:46:44.467-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Asp.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="WebDevelopment"/><category scheme="http://www.blogger.com/atom/ns#" term="WebDevelopment Asp.Net"/><title type='text'>Performance of an Asp.Net Page versus an Http Handler</title><content type='html'>&lt;p&gt;A coworker recently mentioned to me that he was thinking about using an http handler instead of a page for performance reasons.  My first thought was of a quote I saw in a comment on &lt;a href=&quot;http://stackoverflow.com/&quot;&gt;StackOverflow&lt;/a&gt; &quot;He who sacrifices correctness for performance deserves neither.&quot;  I like the quote.  But it doesn&#39;t really say much about the problem at hand.&lt;/p&gt;  &lt;p&gt;My second thought about these options is that I have trouble imagining that the ASP.Net page life cycle&#39;s way of calling events and virtual functions would really add much overhead.  Especially if these requests will have to communicate with the database.  I would think that the cost of calling the database would far outweigh the cost of generating the page.  &lt;/p&gt;  &lt;p&gt;But talk is cheap. The code for my page is very simple:&lt;/p&gt;  &lt;p&gt;&lt;span style=&quot;font-family:Courier New;&quot;&gt;&amp;lt;%@ Page Language=&quot;C#&quot; AutoEventWireup=&quot;true&quot; CodeBehind=&quot;PerfTestPage.aspx.cs&quot; Inherits=&quot;WebSandBox.PerfTestPage&quot; %&amp;gt;Hello&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;The code-behind for the page is just an empty partial class declaration.  &quot;Hello&quot; is on the same line as the page declaration so I don&#39;t end up with extra &quot;\r\n&quot; charecters in my response stream.&lt;/p&gt;  &lt;p&gt;The code for the handler is equally simple:&lt;/p&gt;  &lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; ProcessRequest(HttpContext context)&lt;br /&gt;{&lt;br /&gt;  context.Response.Write(&lt;span class=&quot;str&quot;&gt;&quot;Hello&quot;&lt;/span&gt;);&lt;br /&gt;}&lt;/pre&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;After wiring up the page and the handler in IIS I created a seperate project to do the performance testing.  The call to get the request does a simple GET request and ensures that the text &quot;Hello&quot; came back on the response.&lt;/p&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; DoRequest(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; url)&lt;br /&gt;{&lt;br /&gt;  WebRequest request = WebRequest.Create(url);&lt;br /&gt;  request.Method = &lt;span class=&quot;str&quot;&gt;&quot;GET&quot;&lt;/span&gt;;&lt;br /&gt;  WebResponse response = request.GetResponse();&lt;br /&gt;  &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; resp = (&lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; StreamReader(response.GetResponseStream())).ReadToEnd();&lt;br /&gt;  &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (resp != &lt;span class=&quot;str&quot;&gt;&quot;Hello&quot;&lt;/span&gt;)&lt;br /&gt;      &lt;span class=&quot;kwrd&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Exception();&lt;br /&gt;}&lt;/pre&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;To ensure that the test is fair, I&#39;m going to call each request a bunch of times before actually timing them.  This will ensure that I&#39;m not testing calls that are warming up IIS.  In addition, this is all locally so network/wire time should not be a factor in this.  Here is the test runner:&lt;/p&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Main(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;[] args)&lt;br /&gt;{&lt;br /&gt;  var page = &lt;span class=&quot;str&quot;&gt;&quot;http://localhost/WebSandBox/PerfTestPage.aspx&quot;&lt;/span&gt;;&lt;br /&gt;  InitializeTest(page);&lt;br /&gt;  var pageTime = RunTest(page);&lt;br /&gt;&lt;br /&gt;  var handler = &lt;span class=&quot;str&quot;&gt;&quot;http://localhost/WebSandBox/PerfTestHandler.axd&quot;&lt;/span&gt;;&lt;br /&gt;  InitializeTest(handler);&lt;br /&gt;  var handlerTime = RunTest(handler);&lt;br /&gt;&lt;br /&gt;  Console.WriteLine(&lt;span class=&quot;str&quot;&gt;&quot;page time: {0} ms&quot;&lt;/span&gt;, pageTime);&lt;br /&gt;  Console.WriteLine(&lt;span class=&quot;str&quot;&gt;&quot;handler time time: {0} ms&quot;&lt;/span&gt;, handlerTime);&lt;br /&gt;&lt;br /&gt;  Console.ReadKey();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; InitializeTest(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; url)&lt;br /&gt;{&lt;br /&gt;  &lt;span class=&quot;kwrd&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; i = 0; i &amp;lt; 20; i++)&lt;br /&gt;  {&lt;br /&gt;      &lt;strong&gt;PerfTester.DoRequest(url);&lt;br /&gt;&lt;/strong&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;long&lt;/span&gt; RunTest(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; url)&lt;br /&gt;{&lt;br /&gt;  var sw = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Stopwatch();&lt;br /&gt;  &lt;span class=&quot;kwrd&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; i = 0; i &amp;lt; 1000; i++)&lt;br /&gt;  {&lt;br /&gt;      sw.Start();&lt;br /&gt;      &lt;strong&gt;PerfTester.DoRequest(url);&lt;/strong&gt;&lt;br /&gt;      sw.Stop();&lt;br /&gt;  }&lt;br /&gt;  &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; sw.ElapsedMilliseconds;&lt;br /&gt;}&lt;/pre&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;For this test we&#39;re executing each request 1,000 times to make the time more significant.  Here are the results:&lt;/p&gt;&lt;br /&gt;&lt;table border=&quot;1&quot; cellspacing=&quot;0&quot; cellpadding=&quot;2&quot; width=&quot;400&quot;&gt;&lt;tbody&gt;    &lt;tr&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt; &lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;&lt;strong&gt;Page (ms per 1,000 requests)&lt;/strong&gt;&lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;&lt;strong&gt;Handler (ms per 1,000 requests)&lt;/strong&gt;&lt;/td&gt;    &lt;/tr&gt;    &lt;tr&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt; &lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;6186&lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;6259&lt;/td&gt;    &lt;/tr&gt;    &lt;tr&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt; &lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;6152&lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;6216&lt;/td&gt;    &lt;/tr&gt;    &lt;tr&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt; &lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;6145&lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;6182&lt;/td&gt;    &lt;/tr&gt;    &lt;tr&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt; &lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;6156&lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;6208&lt;/td&gt;    &lt;/tr&gt;    &lt;tr&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt; &lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;6133&lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;6201&lt;/td&gt;    &lt;/tr&gt;    &lt;tr&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt; &lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;6169&lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;6190&lt;/td&gt;    &lt;/tr&gt;    &lt;tr&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt; &lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;6536&lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;6416&lt;/td&gt;    &lt;/tr&gt;    &lt;tr&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt; &lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;6161&lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;6190&lt;/td&gt;    &lt;/tr&gt;    &lt;tr&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt; &lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;6162&lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;6189&lt;/td&gt;    &lt;/tr&gt;    &lt;tr&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;&lt;strong&gt;Average&lt;/strong&gt;&lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;&lt;strong&gt;6200&lt;/strong&gt;&lt;/td&gt;      &lt;td valign=&quot;top&quot; width=&quot;133&quot;&gt;&lt;strong&gt;6228&lt;/strong&gt;&lt;/td&gt;    &lt;/tr&gt;  &lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;I don&#39;t understand why or how the page is faster than the handler.  Maybe IIS is doing some kind of caching.  Or maybe there was additional traffic and CPU usage on my computer during these tests.  But at around 6.2ms per request, I don&#39;t see much of a difference.&lt;br /&gt;&lt;p&gt;Also, this test is only for very simple text &quot;Hello&quot;.  There would of course be additional overhead when using Asp.Net controls on the page.  But I would doubt that the overhead of these controls would far outweigh whatever method the handler would use to generate the same HTML.  And that&#39;s another topic entirely.&lt;/p&gt;&lt;p&gt;The moral of today&#39;s story, &quot;measure twice, cut once&quot;.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/3040473852585851616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2009/09/performance-of-aspnet-page-versus-http.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/3040473852585851616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/3040473852585851616'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2009/09/performance-of-aspnet-page-versus-http.html' title='Performance of an Asp.Net Page versus an Http Handler'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-1316272649498507987</id><published>2009-09-03T10:45:00.001-07:00</published><updated>2009-09-03T10:45:30.305-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="MacBook"/><category scheme="http://www.blogger.com/atom/ns#" term="Objective-C"/><title type='text'>My new MacBook</title><content type='html'>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;This Monday I received a MacBook so I could create an iPhone application.&amp;#160; &lt;/p&gt;  &lt;p&gt;This is the first time I&#39;m using a Mac since my mom brought home something like &lt;a href=&quot;http://en.wikipedia.org/wiki/Macintosh_Classic&quot;&gt;this&lt;/a&gt; before I was in highschool.&amp;#160; This is also the first time I&#39;ll be using a linux type of system since college.&amp;#160; Needless to say I&#39;m very excited.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJfevbH5eIAasolqGXFDbe8pOtphgvwD53NwG29Z2ArJGoitpD3he5DMWhGRgLLvwRcEkkMG7zEUKe-czV95JA3mLdoOB1NBuKoX7T503I-1xzh4UZYxhmwCVCzAcCGePIhookbIT1xXk/s1600-h/mymac%5B4%5D.jpg&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px&quot; border=&quot;0&quot; alt=&quot;mymac&quot; align=&quot;left&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD6STXeth2410jpiV8bCk_y89fnKY_JRwIms_E-A_ymjmpgv-XUXtpX_SCXtECGSOj7R10UuyNsyj4CiJZ0oQSA_dTpRaIhDqOQLhyRxQEAhJXYj0sBr61uV3W1jb4yzu9roLoEaSWCwY/?imgmax=800&quot; width=&quot;351&quot; height=&quot;267&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I&#39;ve started playing with it a little.&amp;#160; I downloaded XCode and the iPhone SDK.&amp;#160; You can see in the photo that I learned how to change the background color.&amp;#160; I think this is probably one of the most common things people do right after turning on a new computer for the first time.&lt;/p&gt;  &lt;p&gt;After using C# for the last bunch of years, Objective-C is like getting in a time machine and going back 10 years.&amp;#160; So many practices that I&#39;ve come to take for granted are gone.&amp;#160; I&#39;m doubt I&#39;ll ever come to grips with the &amp;quot;NS&amp;quot; prefix for everything.&amp;#160; &lt;/p&gt;  &lt;p&gt;At the same time, the MVC framework to Cocoa seems pretty cool.&amp;#160; And the idea of message-passing for dynamic invocation of methods in a strongly typed system is very interesting.&lt;/p&gt;  &lt;p&gt;In addition to my thoughts and feelings about the platform, framework, language, hardware, etc. it&#39;s also cool to be starting from scratch again.&amp;#160; I barely know how to save a file on the Mac.&amp;#160; I haven&#39;t explicitly used a pointer in almost 10 years.&amp;#160; I&#39;m excited to see what the learning curve is like and exactly what programming skills really do transfer between languages, frameworks, etc.&amp;#160; I&#39;ve been learning F#, haskell, python, and ruby out of personal curiosity but now I have to actually build something in Objective-C.&amp;#160; Should be interesting. &lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/1316272649498507987/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2009/09/my-new-macbook.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/1316272649498507987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/1316272649498507987'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2009/09/my-new-macbook.html' title='My new MacBook'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD6STXeth2410jpiV8bCk_y89fnKY_JRwIms_E-A_ymjmpgv-XUXtpX_SCXtECGSOj7R10UuyNsyj4CiJZ0oQSA_dTpRaIhDqOQLhyRxQEAhJXYj0sBr61uV3W1jb4yzu9roLoEaSWCwY/s72-c?imgmax=800" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-116423035220968869</id><published>2009-09-01T16:37:00.001-07:00</published><updated>2009-09-01T16:44:28.774-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET 4.0"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="dynamic"/><title type='text'>Dynamic Stored Procedure Execution</title><content type='html'>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;With the imminent arrival of the dynamic keyword to C# I think we will be seeing more prototypes of ways of putting dynamic objects to use within .NET.&amp;#160; One interesting use is &lt;a href=&quot;http://haacked.com/&quot;&gt;Phil Haack&lt;/a&gt;&#39;s method of &lt;a href=&quot;http://haacked.com/archive/2009/08/26/method-missing-csharp-4.aspx&quot;&gt;HTML encoding properties that are predicated with an underscore&lt;/a&gt;.&amp;#160; After reading about this I wanted to try creating my own dynamically driven class.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Disclaimer:&amp;#160; I&#39;m still on the fence over the use of dynamic in C&lt;/em&gt;#&lt;em&gt;.&amp;#160; I&#39;m not advocating the use of this code.&amp;#160; I just wanted to see if it was possible and what it would look like.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;One problem with ORMs is mapping stored procedures.&amp;#160; This is usually a manual process because stored procedures are inherently not typed.&amp;#160; So I was envisioning something along the lines of:&lt;/p&gt;  &lt;p&gt;&lt;font face=&quot;Courier New&quot;&gt;IList&amp;lt;Person&amp;gt; people = DataContext.Sproc.ExecuteGetList&amp;lt;Person&amp;gt;.spGetPeopleByDOB(dob: myDate);&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;For the purpose of this prototype, I decided not to use any real data context.&amp;#160; That could be added in easily enough.&amp;#160; For now, I&#39;ll be rolling my own data layer.&lt;/p&gt;  &lt;p&gt;Step 1 - Create a simple DataContext:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPWceDybVWkV63nkxTFl58PLjjafNDyd9SzQo40bAs0eS4J7XaGd9zMmXs-HoEtldlIdaFf62F2vgedn-fBckjvkyFA8mQSE2-4wzaTmSMKRoq-U35yea2ZXZMj4zVh4CatN6TrM2ttAc/s1600-h/image%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsvIMb8cQwu1FzGXzygyHnx2-Bc1VRfVEVhRghejY1hDWR6g-O49BBlsKZpFCC6xFOURkcxWmhDc4h0z6sJ4d0byZoxKtdQeZHqAJRAvwK73cAFtKp7KE44FOG38oBb2Ki1B8j8EDV4qs/?imgmax=800&quot; width=&quot;575&quot; height=&quot;121&quot; /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Step 2 - Create the Sproc class&lt;/p&gt;  &lt;p&gt;This class will basically be a factory for different dynamic stored procedure executers.&amp;#160; This way we can easily differentiate between ExecuteScalar, ExecuteNonQuery, getting an object, and getting a list of objects.&amp;#160; For now, I&#39;m going to implement ExecuteScalar&amp;lt;T&amp;gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwXN73dO7HmfITmnVG_rJl60TBvpHwvlFOEWVjB8xrc3NKdcM2X0432Ut5eY726FrIacQqgFvla4eu27V_oYp0bJgjmS9RhGthwumGxqz0KDbty7dA4WIjEv6QS3Ru5IdujVR2PzxTwZ0/s1600-h/image%5B12%5D.png&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgei5ZAFod550s36MAtqFgzQSVxEiJ0f1KQ-9ncyJIrwfi0oB4j7cWqdCecgiJwU-sjR4vyRvcarCXomzH7-SIpbfE2Y7-ofSPdjOc52AT0HgJF58xxK5T0LVFb0d3ZdAu3fGbB46KJ2Tc/?imgmax=800&quot; width=&quot;433&quot; height=&quot;208&quot; /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Step 3 - Create the DynamicExecuteScalar&amp;lt;T&amp;gt; class&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3R2z37yqpJz2gm48cgQtwLSBw0GpjWtCb5qd2xwIAlo3_qGKkHwfb6PrTeMaXBnOv_iiRx9ekIcA8pZ3np3Ac1dQpFxTmlUi8uJLwiTQmbigmKC1gjns9ylvAv3FoqCxvsrj4pq6u_NI/s1600-h/image%5B19%5D.png&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgW8OZez0_PUpK-wmOFSBaiD2fO2IMQrXnl3ynFGwU5lSLyDJ97OPWOEoTkfshyphenhyphenm6hCavvJf8nfSCkCMJhMy_ALXXuu6I3hb1dMV9lzz7vL66cOTunMr20_DjFwnIFVFwTc75-bOKIylZY/?imgmax=800&quot; width=&quot;607&quot; height=&quot;334&quot; /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The real magic here is the use of TryInvokeMember.&amp;#160; This is the function that will be invoked at runtime whenever someone calls a method on your DynamicObject.&amp;#160; So when I call myDynamicExecuteScalar.CallingSomeMethod() I&#39;m actually calling TryInvokeMember.&amp;#160; &lt;/p&gt;  &lt;p&gt;Inside of TryInvokeMember we use binder.Name to get the name of the method called (eg. &amp;quot;CallingSomeMethod&amp;quot;).&amp;#160; Then we use the binder.CallInfo.ArgumentNames and args[] to get a list of named parameters that we can turn into our sql parameters.&lt;/p&gt;  &lt;p&gt;Once you have this code wired up, you can get a scalar for any stored procedure from your code simply by calling:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEim4vg43Vwy-tiElz5z7w4anFvme_BRIgSCfl0zdsxzmXOMeBLU1gLdvFhhYs4ntR3pLZne6KZ88ZOvFjNl_4KyptSFx-R8QD2XI3egFil9-aB3ikPJwxIIPJSF0nkOqg1Vq6cnGcZJP6U/s1600-h/image%5B43%5D.png&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDVkTA9ZnU_LfgkstVcwAoSMpaKo2zzhMDgUu4lWz7gI80uBq6gZH5lH0UIoiuWNKRQFb0hRigibByZQp7XalzjbpfdJMlc7EDFyYi6pZcNFXgXwz0vERQLNdT46Sm2FWCyoHwrMGdOE4/?imgmax=800&quot; width=&quot;591&quot; height=&quot;38&quot; /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And using this as a starting point you can add ExecuteNonQuery, ExecuteGetList&amp;lt;T&amp;gt;, etc.&amp;#160; You can also modify the data context to be more extensible and mockable.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/116423035220968869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2009/09/dynamic-stored-procedure-execution.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/116423035220968869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/116423035220968869'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2009/09/dynamic-stored-procedure-execution.html' title='Dynamic Stored Procedure Execution'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsvIMb8cQwu1FzGXzygyHnx2-Bc1VRfVEVhRghejY1hDWR6g-O49BBlsKZpFCC6xFOURkcxWmhDc4h0z6sJ4d0byZoxKtdQeZHqAJRAvwK73cAFtKp7KE44FOG38oBb2Ki1B8j8EDV4qs/s72-c?imgmax=800" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-446140576176946238</id><published>2009-08-25T15:08:00.001-07:00</published><updated>2009-08-25T15:08:39.165-07:00</updated><title type='text'>Design vs. Structure</title><content type='html'>&lt;p&gt;In many conversations about development, words like design and structure are thrown around.&amp;#160; It is important then when discussing software development to understand the differences between the two.&lt;/p&gt;  &lt;p&gt;According to Merriam-Webster, &lt;a href=&quot;http://www.merriam-webster.com/dictionary/design&quot;&gt;design&lt;/a&gt; is&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;a particular purpose held in view by an individual or group... deliberate purposive planning&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The definition of &lt;a href=&quot;http://www.merriam-webster.com/dictionary/structure&quot;&gt;structure&lt;/a&gt; is&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;something arranged in a definite pattern of organization... manner of construction&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The difference is that a design is about purpose while structure is about organization.&amp;#160; Code that is structured but has no purpose for it&#39;s structure may as well not be structured at all.&amp;#160; There is no cohesion, no single responsibilities, and no reason for a class to exist if it exists for structure alone.&amp;#160; When we set out to structure our code, we should have a design purpose in mind.&amp;#160; &lt;/p&gt;  &lt;p&gt;Another way of saying this is &amp;quot;&lt;a href=&quot;http://en.wikipedia.org/wiki/Form_follows_function&quot;&gt;form follows function&lt;/a&gt;&amp;quot;.&amp;#160; Determine the function and the form will follow.&amp;#160; Determine the design and the structure will follow.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/446140576176946238/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2009/08/design-vs-structure.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/446140576176946238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/446140576176946238'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2009/08/design-vs-structure.html' title='Design vs. Structure'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-329178733127489721</id><published>2009-08-24T13:08:00.001-07:00</published><updated>2009-08-24T13:13:29.904-07:00</updated><title type='text'>Member Variables are not Global Variables</title><content type='html'>&lt;p&gt;It is widely accepted that global variables, in almost any context, are a bad practice.  But there is a common practice that leads to code that is harder to maintain - the use of member variables for passing information between functions for a particular set of functionality.  This is a subtle way of creating global variables in that they are &quot;global&quot; between functions.&lt;/p&gt;  &lt;p&gt;As an example, let&#39;s look at the code below.  For this example, we&#39;re going to assume that &quot;memberVariable&quot; is not used anywhere else but &quot;DoA()&quot; and &quot;DoB()&quot;.&lt;/p&gt;  &lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; memberVariable = &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; MainFunction()&lt;br /&gt;{&lt;br /&gt;   DoA();&lt;br /&gt;   DoB();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; DoA()&lt;br /&gt;{&lt;br /&gt;   &lt;span class=&quot;rem&quot;&gt;// do some stuff&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt;(something)&lt;br /&gt;       memberVariable = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;&lt;br /&gt;   &lt;span class=&quot;kwrd&quot;&gt;else&lt;/span&gt;&lt;br /&gt;       memberVariable = &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;   &lt;span class=&quot;rem&quot;&gt;// maybe do something else&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; DoB()&lt;br /&gt;{&lt;br /&gt;   &lt;span class=&quot;rem&quot;&gt;// do some stuff&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt;(memberVariable)&lt;br /&gt;       DoOneThing();&lt;br /&gt;   &lt;span class=&quot;kwrd&quot;&gt;else&lt;/span&gt;&lt;br /&gt;       DoAnother();&lt;br /&gt;&lt;br /&gt;   &lt;span class=&quot;rem&quot;&gt;// do more stuff&lt;/span&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Member variables are used for maintaining the state of the particular object.  But as can be seen in this case, &quot;memberVariable&quot; does not contain state.  It contains a flag that is particular to the logic of &quot;MainFunction()&quot;.  This is a bad practice because it is very hard to know what &quot;DoB()&quot; is going to do without also examining &quot;DoA()&quot;.  If this were expanded further and the class had many functions, it would be difficult to know who uses &quot;memberVariable&quot; how and why. &lt;/p&gt;&lt;p&gt;There are a number of ways to refactor this code to change the use of &quot;memberVariable&quot;.  DoB() could take memberVariable as a parameter or retrieve it&#39;s value by calling another function.  Even though there are different ways to alleviate the problem, the idea is the same.  Functions should be autonomous and not require other functions being executed in order to work properly.  And even if a &quot;global&quot; variable is only global to two private functions, it&#39;s still global.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/329178733127489721/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2009/08/member-variables-are-not-global.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/329178733127489721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/329178733127489721'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2009/08/member-variables-are-not-global.html' title='Member Variables are not Global Variables'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-484978627950539883</id><published>2009-08-19T11:59:00.001-07:00</published><updated>2009-08-19T11:59:28.246-07:00</updated><title type='text'>Don&amp;#39;t Arbitrarily Reference the Base Class</title><content type='html'>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;All too often I have seen developers referencing properties and methods of the base class directly. Instead of calling &amp;#8220;&lt;font face=&quot;Courier New&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;this&lt;/font&gt;.SomePropertyOrMethod()&lt;/font&gt;&amp;#8221; or just &amp;#8220;&lt;font face=&quot;Courier New&quot;&gt;SomePropertyOrMethod()&lt;/font&gt;&amp;#8221; they call &amp;#8220;&lt;font face=&quot;Courier New&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;base&lt;/font&gt;.SomePropertyOrMethod()&lt;/font&gt;&amp;#8221;. This has a number of drawbacks.&lt;/p&gt;  &lt;p&gt;1) It implies that a class knows something specific about the parent.&lt;/p&gt;  &lt;p&gt;2) It is now difficult to override the method in this class or a class that inherits from the current class. The base version of the method will always be called even if the method is overridden.&lt;/p&gt;  &lt;p&gt;3) This defeats the purpose of object oriented programming. Calling the base class directly is akin to calling the same method on a utility class. The only difference is that the base class might be looking at the current class&amp;#8217;s state. It&amp;#8217;s just messy.&lt;/p&gt;  &lt;p&gt;4) This is a code smell that makes me think of the &lt;a href=&quot;http://en.wikipedia.org/wiki/BaseBean&quot;&gt;Base Bean&lt;/a&gt; anti-pattern. &amp;#8220;A class should not inherit from another class simply because the parent class contains functionality needed in the subclass.&amp;#8221;&lt;/p&gt;  &lt;p&gt;Now there are definitely times when this is necessary and that is why the keyword exists in the first place. If I&amp;#8217;m overriding &lt;font face=&quot;Courier New&quot;&gt;Page.OnLoad&lt;/font&gt;, I should call &lt;font face=&quot;Courier New&quot;&gt;base.OnLoad&lt;/font&gt; at some point. If I override &lt;font face=&quot;Courier New&quot;&gt;List&amp;lt;&amp;gt;.Add&lt;/font&gt;, I better call &lt;font face=&quot;Courier New&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;base&lt;/font&gt;.Add()&lt;/font&gt; to add the item to the list.&lt;/p&gt;  &lt;p&gt;But just because you can do something doesn&amp;#8217;t mean that you should. And this keyword is no different. Most cases of &lt;font face=&quot;Courier New&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;base&lt;/font&gt;.SomePropertyOrMethod()&lt;/font&gt; should be replaced with &lt;font face=&quot;Courier New&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;this&lt;/font&gt;.SomePropertyOrMethod().&lt;/font&gt;&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/484978627950539883/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2009/08/don-arbitrarily-reference-base-class.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/484978627950539883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/484978627950539883'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2009/08/don-arbitrarily-reference-base-class.html' title='Don&amp;#39;t Arbitrarily Reference the Base Class'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-7266615991562115151</id><published>2009-08-11T21:59:00.001-07:00</published><updated>2009-08-11T21:59:49.460-07:00</updated><title type='text'>Maintenance Cost and C# Auto Properties</title><content type='html'>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb384054.aspx&quot;&gt;Auto properties&lt;/a&gt; in C# provide a simple way to implement a property on a class without explicitly creating the field that the property accessors (get and set) will work on.&amp;#160; There have been many discussions on whether or not auto properties are good, their advantages, and their disadvantages.&amp;#160; Looked at from a code-maintenance perspective, an auto property is much better.&lt;/p&gt;  &lt;p&gt;When maintaining code, one big problem is making sure that the code you’re maintaining isn’t doing anything tricky that will make it difficult to modify or fix.&amp;#160; This is one of the reasons why &lt;a href=&quot;http://en.wikipedia.org/wiki/Single_responsibility_principle&quot;&gt;SRP&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Don&#39;t_repeat_yourself&quot;&gt;DRY&lt;/a&gt; are so important.&amp;#160; If there’s only one place that does something and that place is only responsible for the one thing that it does, a code maintainer’s life is very joyful.&amp;#160; When this is not the case, a small change or fix may have detrimental repercussions.&lt;/p&gt;  &lt;p&gt;With this in mind, there is a maintenance &lt;em&gt;&lt;strong&gt;cost&lt;/strong&gt;&lt;/em&gt; to not using auto properties.&amp;#160; If there’s a field hidden under your property, as a maintainer of your code, I now have to check all uses of the field as well as all uses of the property.&amp;#160; With an auto property, the property is the only thing that needs to be investigated.&lt;/p&gt;  &lt;p&gt;When explicitly creating a field for a property it is important to consider the costs of doing so.&amp;#160; In addition, it’s important to ask if this field is really necessary.&amp;#160; Can all your methods access the property instead?&amp;#160; If so, why even have this extra level of misdirection.&amp;#160; Chances are &lt;a href=&quot;http://en.wikipedia.org/wiki/You_Ain&#39;t_Gonna_Need_It&quot;&gt;YAGNI&lt;/a&gt; plays a big part here.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/7266615991562115151/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2009/08/maintenance-cost-and-c-auto-properties.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/7266615991562115151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/7266615991562115151'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2009/08/maintenance-cost-and-c-auto-properties.html' title='Maintenance Cost and C# Auto Properties'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-1706826107748911701</id><published>2009-03-18T09:17:00.001-07:00</published><updated>2009-03-18T09:17:38.020-07:00</updated><title type='text'>DeflateStream versus GZipStream</title><content type='html'>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.io.compression.deflatestream.aspx&quot;&gt;DeflateStream&lt;/a&gt; and &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.io.compression.gzipstream.aspx&quot;&gt;GZipStream&lt;/a&gt; are the two compression classes that come standard in the System.IO.Compression namespace.&amp;#160; If you&#39;re looking for all out performance, DeflateStream is the answer.&amp;#160; According to msdn,&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The GZipStream class uses the gzip data format, which includes a cyclic redundancy check value for detecting data corruption. The gzip data format uses the same compression algorithm as the DeflateStream class.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;GZipStream is basically DeflateStream with some additional functionality and integrity checking. So if you only care about speed, DeflateStream will be faster.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/1706826107748911701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2009/03/deflatestream-versus-gzipstream.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/1706826107748911701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/1706826107748911701'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2009/03/deflatestream-versus-gzipstream.html' title='DeflateStream versus GZipStream'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-6285715256472180403</id><published>2009-01-02T13:59:00.001-08:00</published><updated>2009-01-02T14:00:55.744-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Development"/><category scheme="http://www.blogger.com/atom/ns#" term="Morallity"/><category scheme="http://www.blogger.com/atom/ns#" term="Team"/><category scheme="http://www.blogger.com/atom/ns#" term="WebDevelopment"/><title type='text'>How I Didn&#39;t Get in Trouble</title><content type='html'>&lt;p&gt;A few months ago I noticed a significant performance problem during the application startup of the really big, web system I work on.  It was literally taking up to a minute and a half for IIS to load up the application.&lt;/p&gt;  &lt;p&gt;After some digging I found out that the application was loading about a million records or so from the database into the application&#39;s cache.  Regardless of the decision to implement this, I did not want this happening locally.  I couldn&#39;t test any of my work.  I couldn&#39;t develop.&lt;/p&gt;  &lt;p&gt;Where I work, even though we all have a local development environment, we all share the same development database server.  And these million or so records were being loaded by a stored procedure aptly named spGetAll[Things].  &lt;/p&gt;  &lt;p&gt;I notified my boss and the developer responsible for creating this stored procedure about my problem and told them that I was practically unable to work and that we had to change this behavior in our development environment.  They said that it would be done...  And I waited... and waited...&lt;/p&gt;  &lt;p&gt;And after a day and a half, I modified the stored procedure to return only the top 20 rows - problem solved!  But I knew that this could cause problems for someone else who might be debugging a problem related to this data and find that the data was missing.  &lt;/p&gt;  &lt;p&gt;So I waited, expecting someone to yell about the missing data and then at me.  But I could work again.  Other&#39;s could work again.  Adding &quot;Top 20&quot; to a stored procedure on a development database saved countless minutes and probably a lot of money for the company.  &lt;/p&gt;  &lt;p&gt;Finally the email arrived.  &quot;There is a problem with the data in such and such table and we&#39;re going to overwrite it with what&#39;s on production.  Is this OK?&quot;  So I humbly sent out an email saying that I modified the spGetAll[Things] and that maybe this is the problem.&lt;/p&gt;  &lt;p&gt;Here I am, thinking that I&#39;m going to get in trouble, that some poor developer spent hours or even days trying to track down a problem that I intentionally created.  And what happens?  &lt;strong&gt;They apologize to ME.&lt;/strong&gt;  OMG.  They said that they were sorry but they&#39;d have to fix the stored procedure.  &lt;/p&gt;  &lt;p&gt;&quot;Ok&quot; by me.  They fixed the stored procedure.  And I quickly add a configuration variable to use a new stored procedure spGetAll[Things]Truncated.  I probably should have done this in the first place but adding &quot;Top 20&quot; is just so much simpler.  Especially when it&#39;s done under the radar.&lt;/p&gt;  &lt;p&gt;The moral:  if I didn&#39;t fess-up to what I&#39;d done I could have gotten in real trouble... and maybe even fired.  Don&#39;t be ashamed of your work.  Even when it&#39;s bad.  There is no way to work in a team if you hide what you&#39;ve done.  And you&#39;ll see that people are very forgiving when you admit to making a mistake.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/6285715256472180403/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2009/01/how-i-didn-get-in-trouble.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/6285715256472180403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/6285715256472180403'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2009/01/how-i-didn-get-in-trouble.html' title='How I Didn&#39;t Get in Trouble'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-6969848314946018110</id><published>2008-12-22T13:11:00.000-08:00</published><updated>2008-12-22T13:18:52.450-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="WebDevelopment Asp.Net"/><title type='text'>The IE6 AntiPattern</title><content type='html'>&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial;&quot;&gt;This might be a little behind the times but it’s still not uncommon for me to spend half a day or more just trying to fix CSS for IE6.  I was reminded of this while reading &lt;/span&gt;&lt;a href=&quot;http://www.joelonsoftware.com/&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial;&quot;&gt;Joel Spolsky’s blog&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial;&quot;&gt; recently where he said&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-style: italic;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: small;&quot;&gt;&quot;I’ve been debugging the new site. The first problem: hopelessly messed up rendering on IE6. The best way to fix CSS problems with IE6 is to generate random mutations on the style sheet until it looks fixed. That’s really the only way to approach these kinds of things; CSS is nondeterministic, and many better minds than mine have gone completely stark raving mad trying to understand the rhyme and reason of IE6 rendering bugs.&quot; - &lt;a href=&quot;http://www.joelonsoftware.com/items/2008/12/19.html&quot;&gt;Joel Spolsky&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial;&quot;&gt;My method is not too different from that of Joel’s.  I know the hacks of putting a “#” before the class name or wrapping the entire CSS in “”.  But these are ridiculous work-arounds… and the amount of time wasted…  I wonder if the additional costs of maintaining MSN, Live, MSDN, Microsoft.com, etc. for IE6 outweigh the expense of…&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial;&quot;&gt;Allow me to digress.  Just the other day my uncle mentioned that he wanted to upgrade his version of Windows XP from the Home Edition to Professional  The reason is that Microsoft was going to stop supporting the Home version soon.  My uncle is the type of person that I would consider an average user.  He uses his computer for managing his photos, email, and the like – nothing fancy.  Because of people like my uncle, I’m pretty sure that IE6 isn’t going away any time soon.  And with IE 6 still at &lt;/span&gt;&lt;a href=&quot;http://www.w3schools.com/browsers/browsers_stats.asp&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial;&quot;&gt;20% of the market share&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial;&quot;&gt;, it’s a browser that we all have to support.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial;&quot;&gt;As far as I know, there isn’t much we can do about the situation except wait it out.  Hopefully with IE 8, Windows 7, and limited support for Windows XP the usage of IE will eventually end. &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial;&quot;&gt;And since we’re all complicit, we should also be thinking about how we got here (like the &lt;/span&gt;&lt;a href=&quot;http://www.google.com/search?q=frog+in+the+pot&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial;&quot;&gt;frog in the pot&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial;&quot;&gt;) and how we can make sure that this does not happen again.  I know the story conventional story line that IE 6 was “The Browser” at the time and so whatever worked on IE was correct.  Then came Firefox and it was back to trying to support two different browsers.  Then came IE 7 which was “broken” because it was “fixed”.  And now with the plethora of options (Safari, Opera, Chrome, etc.) we have our work cut out for us.&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/6969848314946018110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2008/12/ie6-antipattern.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/6969848314946018110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/6969848314946018110'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2008/12/ie6-antipattern.html' title='The IE6 AntiPattern'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-3143470635844634078</id><published>2008-12-19T14:50:00.001-08:00</published><updated>2008-12-19T14:55:52.004-08:00</updated><title type='text'>Isolating 3rd Party JavaScript</title><content type='html'>&lt;span style=&quot;font-family: arial;&quot;&gt;I&#39;m looking for a way of protecting our web pages from 3rd party javascript files that might timeout or throw errors. These files are usually for ads where we just include a script reference.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4pFZnKBcZMl6Wb8V_7VxXvGNxwaFuabYlyhjC2x_lX9GgFwdAoFtgKZZkcnOqALJyYhkJB5kn20IHYx33fGuVILc151zoaBHmyYxZXShxeDUXqj1nnQn2hRPr_GwNSzq3TaYtt0B96vM/s1600-h/srcRef.PNG&quot;&gt;&lt;img style=&quot;cursor: pointer; width: 400px; height: 11px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4pFZnKBcZMl6Wb8V_7VxXvGNxwaFuabYlyhjC2x_lX9GgFwdAoFtgKZZkcnOqALJyYhkJB5kn20IHYx33fGuVILc151zoaBHmyYxZXShxeDUXqj1nnQn2hRPr_GwNSzq3TaYtt0B96vM/s400/srcRef.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5281638500157444658&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;What makes it worse is that these files contain code that does a &lt;span style=&quot;font-family: courier new;&quot;&gt;document.write()&lt;/span&gt;.  Because of this, moving the reference or trying to load the file asynchronously will cause the ads to be rendered on a different part of the page.  Because of the use of &lt;span style=&quot;font-family: courier new;&quot;&gt;document.write()&lt;/span&gt;, the only way to load the files without affecting the page&#39;s load time is to load them from within an iframe.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;In addition, we can override on the &lt;span style=&quot;font-family: courier new;&quot;&gt;onerror &lt;/span&gt;event for the page in the iframe.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaFmErYs26TW5w03f_TaLHh2QoRO_0qaKY97BvR9viAiDMdYV8-X0YVj9t1w5Ma4Bhn8tlCxwGsBzVAljII4jS6KNzUbhndWlBJ9XGnr1tS4atHOObuXLcsze7FHs2kBQlUuihsjEDRGM/s1600-h/iframsource.PNG&quot;&gt;&lt;img style=&quot;cursor: pointer; width: 400px; height: 108px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaFmErYs26TW5w03f_TaLHh2QoRO_0qaKY97BvR9viAiDMdYV8-X0YVj9t1w5Ma4Bhn8tlCxwGsBzVAljII4jS6KNzUbhndWlBJ9XGnr1tS4atHOObuXLcsze7FHs2kBQlUuihsjEDRGM/s400/iframsource.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5281637982735182018&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;This method scares me since I really can&#39;t imagine what would happen if other developers start putting this little snippet of script into all their pages.  In addition this sounds like a whole lot of extra work just because some other companies product is problematic.  Stop using their product is what I think.&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/3143470635844634078/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2008/12/isolating-3rd-party-javascript.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/3143470635844634078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/3143470635844634078'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2008/12/isolating-3rd-party-javascript.html' title='Isolating 3rd Party JavaScript'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4pFZnKBcZMl6Wb8V_7VxXvGNxwaFuabYlyhjC2x_lX9GgFwdAoFtgKZZkcnOqALJyYhkJB5kn20IHYx33fGuVILc151zoaBHmyYxZXShxeDUXqj1nnQn2hRPr_GwNSzq3TaYtt0B96vM/s72-c/srcRef.PNG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-1375434921149075816</id><published>2008-11-04T13:15:00.000-08:00</published><updated>2008-12-23T10:09:06.116-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DeepZoom"/><category scheme="http://www.blogger.com/atom/ns#" term="Silverlight"/><title type='text'>Deep Zoom Composer</title><content type='html'>&lt;div&gt;Wow!&amp;#160; &lt;a href=&quot;http://www.microsoft.com/downloads/details.aspx?FamilyID=457B17B7-52BF-4BDA-87A3-FA8A4673F8BF&amp;amp;displaylang=en&quot;&gt;DeepZoom&lt;/a&gt; composer with &lt;a href=&quot;http://photozoom.mslivelabs.com/&quot;&gt;PhotoZoom &lt;/a&gt;is awesome.&amp;#160; Here&#39;s my first &lt;strike&gt;photo album&lt;/strike&gt;.&amp;#160; All the pictures are from my iPhone so the quality isn&#39;t great.&amp;#160; But it was so easy to make.&amp;#160; &lt;/div&gt;  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;  &lt;div&gt;However, one thing is missing.&amp;#160; I&#39;d like to be able to click on a photo and view the original in case I want to print it or send it.&amp;#160; Maybe I&#39;ll see if I can add this to the opensource proj.&amp;#160; We&#39;ll see if there&#39;s time for that.&lt;/div&gt;  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;  </content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/1375434921149075816/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2008/11/deep-zoom-composer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/1375434921149075816'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/1375434921149075816'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2008/11/deep-zoom-composer.html' title='Deep Zoom Composer'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-2451700340672744837</id><published>2008-10-31T09:54:00.000-07:00</published><updated>2008-10-31T10:14:08.882-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Asp.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="User Controls"/><title type='text'>Sharing User Controls between Web Projects</title><content type='html'>&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;How many times have you had rearrange your solution or copy code around in order to share user controls between projects?  This is one place where Asp.Net is seriously lacking.  A user control is supposed to be a piece of functional content that is broken into a separate control for maintainability and &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: bold;&quot;&gt;code reuse&lt;/span&gt;.  Why then can I only reuse them within one project?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:arial;&quot;&gt;Well I guess there is &lt;a href=&quot;http://support.microsoft.com/kb/825996&quot;&gt;one method&lt;/a&gt; for doing this by using virtual directories in IIS.  So the better question would be why I cannot reuse them &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: bold;&quot;&gt;easily &lt;/span&gt;across multiple projects.&lt;br /&gt;&lt;br /&gt;There are some additional steps to make it much easier to actually use these controls as well as access there public properties and methods.  Here is the whole process:&lt;/span&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;1) Create a new web project for your user controls.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;2) Create a folder in this project where you will put these controls.  (This is not necessary since you can reference the folder of the project but I think that having the user controls folder named the same across projects can make things a little clearer.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;3) In a separate web project from where you want to use your shared user controls, create a directory with the same name as the directory from the previous step.  (In my example I call this “UserControls”.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;4) In the Solution Explorer, right click on this directory and select Add-&gt;Existing Item…&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBxIS8zCU8XiYoTRLPSPhXLWP_Y6ttGk_gbgXoJI0vw_Qx4FW3qyHLuGjuflTHDdYhNzEvH7pxpoUTX2wFVm9uFIbhcAbAGrNuOVlzvu0RdhOqTvHiyVvEivZ7v7f7Oeo-rL0NDsAayGc/s400/AddExisting.bmp&quot; style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 361px; height: 400px;&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5263363706334783826&quot; /&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;br /&gt;5) Browse to the folder in your shared user controls project.  Select all the controls along with their code-behind files.  But instead of clicking the add button, click the down arrow on the right side of the button.  Then select &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: bold;&quot;&gt;Add As Link&lt;/span&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:arial;&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheqWM1RVzQP1djKFh5TUubeMoIVzKfVvgGFll5OCDBIIfeivAcHLpTiwsU45MIiaqz1yAO8GkfA_Z1esFh2MmthY9Ef7H29wy-_Nsbf6mlsBmWkxE6tE2qG2NKLiskmbgwtqWMGRCUECE/s400/AddAsLink.bmp&quot; style=&quot;cursor:pointer; cursor:hand;width: 400px; height: 249px;&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5263364026436380994&quot; /&gt;&lt;br /&gt;&lt;br /&gt;6) You can now repeat this for any other web projects in your solution.  When you’re finished, your solution will look something like this.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:arial;&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZ-44unCwm3QTq6ntavYApnPvFXoRQNvic1lR8hA30oBqdGde8ham05Uc0-RYjeDhx5Zlxul__G3jaI8QkYy51mXO30ZfTeyElilIO1mPsRV_h38z5BFqLtDWwjVQ6ZnKJ5KgmfdTQS-w/s400/Solution.bmp&quot; style=&quot;cursor:pointer; cursor:hand;width: 282px; height: 400px;&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5263364475679845074&quot; /&gt;&lt;br /&gt;&lt;br /&gt;7) You can now repeat this for any other web projects in your solution.  When you’re finished, your solution will look something like this.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;8) Remember to make sure that IIS is aware of your “UserControls” directories as virtual directories so that the asp.net worker process compiles your pages properly.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/2451700340672744837/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2008/10/sharing-user-controls-between-web.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/2451700340672744837'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/2451700340672744837'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2008/10/sharing-user-controls-between-web.html' title='Sharing User Controls between Web Projects'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBxIS8zCU8XiYoTRLPSPhXLWP_Y6ttGk_gbgXoJI0vw_Qx4FW3qyHLuGjuflTHDdYhNzEvH7pxpoUTX2wFVm9uFIbhcAbAGrNuOVlzvu0RdhOqTvHiyVvEivZ7v7f7Oeo-rL0NDsAayGc/s72-c/AddExisting.bmp" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-3455184574154261610</id><published>2008-10-09T12:09:00.001-07:00</published><updated>2008-10-09T12:13:05.245-07:00</updated><title type='text'>Ctrl+F is changing the way we read</title><content type='html'>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5NaIhihx2YeteS7BW-l4T0vm3yrVnqjIh1JUB1wN_AQi8TbUL0-fO35iCbGANnAOB-Lz0TvzTAPhBop_w1k9ONxxDqE18PcGsQogB13HounT0GgkBCwZEyLcnlNTycfplU9aKtC-ZH6s/s1600-h/magnifying-glass.jpg&quot;&gt;&lt;img style=&quot;float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5NaIhihx2YeteS7BW-l4T0vm3yrVnqjIh1JUB1wN_AQi8TbUL0-fO35iCbGANnAOB-Lz0TvzTAPhBop_w1k9ONxxDqE18PcGsQogB13HounT0GgkBCwZEyLcnlNTycfplU9aKtC-ZH6s/s320/magnifying-glass.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5255233512724822322&quot; /&gt;&lt;/a&gt;&lt;div&gt;I don’t know about you but I love [ctrl+f] a.k.a the Find command.  Just as copy/paste changed the way that we write and edit text, [ctrl+f] is changing the way that we read.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When I’m browsing a web site in search of some data, I find [ctrl+f] to be the easiest way of scanning the page to see if it might contain the nugget of knowledge I’m looking for.  Especially today when most pages are full of images, ads, and other noise, [ctrl+k] will take you right to the text your looking for.  And you instantly know, regardless of what the Google search brought up, if the page actually contains what you’re looking for.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Visual Studio also has [ctrl+shift+k] which is the short-cut for “Find in Files”.  This allows me to search the entire codebase for any string (or regex) that I’m looking for.  This is great when I need to maintain (read fix a bug) in a part of a system that I’m unfamiliar with.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For example, let’s say that some value isn’t displaying properly on a web page.  Using Firebug I can usually find the control’s ClientID.  This value usually contains part of the control’s ID.  [Ctrl+shift+k] and I can find all the files (pages and user controls) that use this ID.  Then you can find the type, class declaration… and finally fix the bug.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Imagine having this kind tool when reading a reference book.  Sure the table of contents and index are useful.  But just think of how quickly you could find information if you could quickly search the whole book for a word like ListView.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBjmsfoz4RCmuKkEtOScC_atlKorj5A98HP5Rqn-E1Ft4f2dlEbqa1pkV_vO_yqMyYg9yrWfhX0YzxqB2kRRkd0jRMjJvpN3U8_wn2Q41oNDhCGiRb14TERR-XT2kf84MVmJ6kr9VLd7g/s400/ListViewSearch.bmp&quot; style=&quot;cursor:pointer; cursor:hand;&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5255233929402631826&quot; /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As more and more text based content is available online and we do more and more of our reading online, it will become imperative for any good UI to allow for instant text searching.  That this isn’t already a standard feature in Windows causes a lot of grief.  Just as all text boxes allow cut/copy/paste, they should also allow “find”.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/3455184574154261610/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2008/10/ctrlf-is-changing-way-we-read.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/3455184574154261610'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/3455184574154261610'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2008/10/ctrlf-is-changing-way-we-read.html' title='Ctrl+F is changing the way we read'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5NaIhihx2YeteS7BW-l4T0vm3yrVnqjIh1JUB1wN_AQi8TbUL0-fO35iCbGANnAOB-Lz0TvzTAPhBop_w1k9ONxxDqE18PcGsQogB13HounT0GgkBCwZEyLcnlNTycfplU9aKtC-ZH6s/s72-c/magnifying-glass.jpg" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-7991645996075033171</id><published>2008-10-07T14:20:00.000-07:00</published><updated>2008-10-31T10:06:12.239-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Asp.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="Form"/><category scheme="http://www.blogger.com/atom/ns#" term="PostBack"/><category scheme="http://www.blogger.com/atom/ns#" term="SEO"/><title type='text'>SEO friendly forms in ASP.NET</title><content type='html'>If you ever need to create a page in ASP.NET that uses some kind of Url mapper, you may run into some problems with posting back. If you look closer, you’ll find that the Url of the request is no longer the SEO friendly one but the actual one (possibly including some querystring parameters if they’re part of the mapping.) And .NET does not make it easy to override the address in the “action” attribute of your form.&lt;br /&gt;&lt;br /&gt;The best way I’ve found to fix this problem is to create a Server control that inherits from the standard HtmlForm and overrides the RenderBeginTag() method.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFSECSSzL1-PLFO_j9c5qq9KAy_B0-aDtotNd3iJrHmlQLeUiFDBoZxp5Y7GIM0EHXPc-Xd5v0R-y82exXPcOBP_hX3hDIMKlgZLRgjLW7GD7_9KUZFhiS5bYoIzJwc0lOwCSD9zdTSyc/s1600-h/code1.GIF&quot;&gt;&lt;img style=&quot;CURSOR: hand&quot; id=&quot;BLOGGER_PHOTO_ID_5254525906319742370&quot; border=&quot;0&quot; alt=&quot;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFSECSSzL1-PLFO_j9c5qq9KAy_B0-aDtotNd3iJrHmlQLeUiFDBoZxp5Y7GIM0EHXPc-Xd5v0R-y82exXPcOBP_hX3hDIMKlgZLRgjLW7GD7_9KUZFhiS5bYoIzJwc0lOwCSD9zdTSyc/s400/code1.GIF&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;You can now register and plug this new form into any page. You can then set the attribute AllowPostBack to false if there are no postbacks on your page. Or you can override PostBackUrl to set the “action” attribute on the form.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/7991645996075033171/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2008/10/seo-friendly-forms-in-aspnet.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/7991645996075033171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/7991645996075033171'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2008/10/seo-friendly-forms-in-aspnet.html' title='SEO friendly forms in ASP.NET'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFSECSSzL1-PLFO_j9c5qq9KAy_B0-aDtotNd3iJrHmlQLeUiFDBoZxp5Y7GIM0EHXPc-Xd5v0R-y82exXPcOBP_hX3hDIMKlgZLRgjLW7GD7_9KUZFhiS5bYoIzJwc0lOwCSD9zdTSyc/s72-c/code1.GIF" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3640798027160825921.post-1488398076667306355</id><published>2008-06-15T20:14:00.000-07:00</published><updated>2008-11-12T21:33:45.497-08:00</updated><title type='text'>My first blog</title><content type='html'>This is my first blog...&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1Yt3vSzN9WT55ljrJuY5Mckp3iqQe67g8rx7E6B48NWZpfowD13Vt5ubexIhcpEouI53Jz7ntNv9gb0qix2Xj7xigKMWjMtpBYIzEMQn6OtGqCZZLXyC91pcMx3_zbwph54ZKBdZxqd0/s1600-h/IMG_0073.JPG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1Yt3vSzN9WT55ljrJuY5Mckp3iqQe67g8rx7E6B48NWZpfowD13Vt5ubexIhcpEouI53Jz7ntNv9gb0qix2Xj7xigKMWjMtpBYIzEMQn6OtGqCZZLXyC91pcMx3_zbwph54ZKBdZxqd0/s320/IMG_0073.JPG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5212313526549876834&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryanwe.blogspot.com/feeds/1488398076667306355/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ryanwe.blogspot.com/2008/06/my-first-blog.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/1488398076667306355'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3640798027160825921/posts/default/1488398076667306355'/><link rel='alternate' type='text/html' href='http://ryanwe.blogspot.com/2008/06/my-first-blog.html' title='My first blog'/><author><name>Ryan</name><uri>http://www.blogger.com/profile/05995028859665668169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudwVbPmALkJ-SnxL_S-2RLZlJrVAu-HKSLYnoWVECbOLIcto3cJMeWrRjsZnFOoMNOBoDoJNEbqo0Db2hrG-bBW9p7XZyIhAkXnPsWCalZsnoRfdodAkGEgqX0NhtPRc/s220/groo.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1Yt3vSzN9WT55ljrJuY5Mckp3iqQe67g8rx7E6B48NWZpfowD13Vt5ubexIhcpEouI53Jz7ntNv9gb0qix2Xj7xigKMWjMtpBYIzEMQn6OtGqCZZLXyC91pcMx3_zbwph54ZKBdZxqd0/s72-c/IMG_0073.JPG" height="72" width="72"/><thr:total>0</thr:total></entry></feed>