<?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: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-25340877</id><updated>2011-11-27T17:33:54.877-07:00</updated><category term='finance'/><title type='text'>the ramblings of a .net dude</title><subtitle type='html'>my thoughts on the art of writing software.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>64</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-25340877.post-7623176847121548897</id><published>2011-08-10T07:26:00.004-07:00</published><updated>2011-08-17T07:42:59.152-07:00</updated><title type='text'>Exception Usage Considerations</title><content type='html'>It seems that I always have the following conversation with different developers.&lt;br /&gt;&lt;br /&gt;Them: This method shouldn't throw an exception, it should return an error code.&lt;br /&gt;Me: OK. Why?&lt;br /&gt;Them: Because... umm... exceptions are a terrible means to communicate errors. I want to see a status flag and an error message.&lt;br /&gt;&lt;br /&gt;I kinda get the point, but in frameworks such as .NET and Java, it really doesn't make sense to use anything but exceptions.&lt;br /&gt;&lt;br /&gt;First, if you use error codes or anything of the sort, you now have the &lt;span style="font-weight:bold;"&gt;worst&lt;/span&gt; of both worlds: the runtime and class library code will throw exceptions and your code will return error codes. Now you have to deal with both.&lt;br /&gt;&lt;br /&gt;Second, when returning error codes and messages you have to make assumptions about how application developers will use your code. It's impossible for you to determine under what conditions your code will be used and what assumption the application developer will make about it. It's best to just be consistent and throw an exception when you're not able to complete the work you "contracted" to do through your method signature.&lt;br /&gt;&lt;br /&gt;In the interest of completeness: there's perhaps one case in which you should return a flag instead of throwing an exception. When you have a method that gets called frequently and it also has a high failure rate, you'll likely experience a performance hit (from throwing/handling so many exceptions) that won't be tolerable.&lt;br /&gt;&lt;br /&gt;Microsoft, for example, had the above problem with the &lt;span style="font-weight:bold;"&gt;Int32.Parse&lt;/span&gt; method. To address the issue MS introduced &lt;span style="font-weight:bold;"&gt;TryParse&lt;/span&gt;. This new method returns a flag telling you whether worked and returns the value of the parse in and output parameter called &lt;span style="font-weight:bold;"&gt;result&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;It's important to note, however, that the boolean flag returned only indicates one type of failure: the method's inability to parse the string into an integer. The method still throws an &lt;span style="font-weight:bold;"&gt;ArgumentException&lt;/span&gt; if the argument is not valid.&lt;br /&gt;&lt;br /&gt;So there you have it: always use exceptions. And if you're not going to listen to me, use error flags to indicate just one type of error.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-7623176847121548897?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/7623176847121548897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2011/08/exception-usage-considerations.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/7623176847121548897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/7623176847121548897'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2011/08/exception-usage-considerations.html' title='Exception Usage Considerations'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-5462201333294099731</id><published>2011-05-03T20:24:00.007-07:00</published><updated>2011-05-16T15:31:42.273-07:00</updated><title type='text'>Injection with Unity: Mind Your Lifetime Dependency</title><content type='html'>For the past few months we've had this bug (PROD only, and unreproducible in any of our other environments) where every now and then we could not get data from our DB. The DB was up and running just fine, but the SqlClient on the web server just could not read the data (we'd get 2 errors: one about trying to read data where a reader was already open, and another about not being able to cast the data from the reader to a certain type). In case you're interested, the exact errors were:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;System.InvalidCasException: Specified cast is no valid. At System.Data.SqlClient.SqlBuffer.get_Int32()&lt;/li&gt;&lt;li&gt;Invalid attempt to call Read when reader is closed. Somewhere in System.Data.SqlClient as well.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;For a while we just lived with the error; it didn't happen very often and it only affected a few customers. Then the problem got worse and so we immediately blamed it on some environment change... we recycled the app pool on a consistent basis while trying to figure out what the problem was.&lt;br /&gt;&lt;br /&gt;Finally, when the problem got bad enough, I did a little bit of research and concluded that we were seeing the problem because we were not disposing our LINQ contexts correctly. After trying to prove that the problem was in someone else's code (and failing), I quickly concluded that it must be Unity that was not disposing the contexts.&lt;br /&gt;&lt;br /&gt;You see, I had assumed that Unity would new up an instance of our db context on every call to resolve, but it turns out that by default the lifetime of the dependencies Unity resolves is the same as the lifetime of the IoC container. In our case, the IoC container stayed alive throughout the entire app (because we needed to resolve stuff in our MVC controllers) and so the longer the app went without a restart, and the more requests it handled, the more we saw the error.&lt;br /&gt;&lt;br /&gt;Fortunately, because we were using Unity to resolve all of our dependencies, and because the Unity code was all in one place and well isolated from the rest of the app, it was really easy to fix. All I had to do was write a per HTTP request lifetime manager and plug it into our container. I'll be posting the code for that container soon... but now I gotta go to bed. Looks like we'll have quite a few bugs to fight tomorrow. :)&lt;br /&gt;&lt;br /&gt;Edit:&lt;br /&gt;&lt;br /&gt;As promised, here's teh code for the "per HTTP request" Unity lifetime manager:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="brush: csharp"&gt;public class HttpRequestLifetimeManager : LifetimeManager&lt;br /&gt;{&lt;br /&gt;   private string _key = Guid.NewGuid().ToString();&lt;br /&gt;&lt;br /&gt;   public override object GetValue()&lt;br /&gt;   {&lt;br /&gt;       if (HttpContext.Current != null &amp;amp;&amp;amp; HttpContext.Current.Items.Contains(_key))&lt;br /&gt;           return HttpContext.Current.Items[_key];&lt;br /&gt;       else&lt;br /&gt;           return null;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public override void RemoveValue()&lt;br /&gt;   {&lt;br /&gt;        if (HttpContext.Current != null)&lt;br /&gt;             HttpContext.Current.Items.Remove(_key);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public override void SetValue(object newValue)&lt;br /&gt;   {&lt;br /&gt;        if (HttpContext.Current != null)&lt;br /&gt;             HttpContext.Current.Items[_key] = newValue;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-5462201333294099731?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/5462201333294099731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2011/05/injection-with-unity-mind-your-lifetime.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/5462201333294099731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/5462201333294099731'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2011/05/injection-with-unity-mind-your-lifetime.html' title='Injection with Unity: Mind Your Lifetime Dependency'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-4870874593506031478</id><published>2011-01-20T22:12:00.005-07:00</published><updated>2011-01-21T15:42:23.090-07:00</updated><title type='text'>write less</title><content type='html'>honoring the title and idea of this post i'll just say this to get the point across:&lt;br /&gt;&lt;blockquote&gt;the quality of your solution is inversely proportional to the amount of code you write to solve the problem.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;unfortunately, i have to say a bit more to justify my thoughts.&lt;br /&gt;&lt;br /&gt;i've always wondered about how to write good code; and i'm not the only one apparently:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://imgs.xkcd.com/comics/good_code.png"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 455px; height: 695px;" src="http://imgs.xkcd.com/comics/good_code.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;well, i've finally figured it out: good code is written by writing as little code as possible. this is true because the when you write the bare minimum you will almost naturally end up with code that is easy to read, easy to test, easy to extend, and therefore, easy to maintain (to see more about the attributes of good code, take a look at &lt;a href="http://www.makinggoodsoftware.com/2009/05/07/the-pyramid-of-code-quality-the-5-characteristics-of-good-code/"&gt;the pyramid of code quality&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;i understand that there are guidelines and principles that you must still follow when writing "just enough" code, but things really deteriorate fast when you don't KISS.&lt;br /&gt;&lt;br /&gt;so next time you're inclined to do solve a problem with code, first think about if there's a way to solve it without &lt;span style="font-style: italic;"&gt;any &lt;/span&gt;code. then, and only if you absolutely must, write as little code as possible.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-4870874593506031478?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/4870874593506031478/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2011/01/write-less.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4870874593506031478'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4870874593506031478'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2011/01/write-less.html' title='write less'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-2056263079119906361</id><published>2010-10-26T19:14:00.002-07:00</published><updated>2010-10-26T19:35:24.232-07:00</updated><title type='text'>Simplicity</title><content type='html'>A couple of days ago while on my way to work, I was listening to Erno Rubik on an interview on NPR (yeah, I know, leftist media). &lt;br /&gt;&lt;br /&gt;At one point the host (Doug Fabrizio, I believe) asked: "Why did you choose a cube? Why 9 squares on each side of the cube?" To which Mr. Rubik answered something to the effect of: &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Well, I was trying to come up with the simplest solution possible. And that actually turned out to be very hard; it's always very hard to define something in it's simplest terms... (and a few more minutes of explanation about why reaching simplicity is so hard) Anyhow, I wanted to find the simple form to teach my students how to describe movement in mathematical terms; a cube with nine squares was the simplest way I could do that.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I just loved that answer. I've long had a feeling that when writing software the simplest solution will always be the most maintainable solution. Simplicity is the core principle on which YAGNI, DRY, and so many other software engineering ideas are built. As DaVinci said:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Simplicity is the ultimate sophistication.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;So here's this post in honor of writing &lt;span style="font-style:italic;"&gt;simple&lt;/span&gt;, sophisticated code. Long live simplicity!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-2056263079119906361?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/2056263079119906361/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2010/10/simplicity.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/2056263079119906361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/2056263079119906361'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2010/10/simplicity.html' title='Simplicity'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-6783628344120918398</id><published>2010-05-11T08:37:00.005-07:00</published><updated>2010-05-11T09:10:12.418-07:00</updated><title type='text'>Visual Studio 2010 Debugger Not Attaching Problem</title><content type='html'>Since we moved to Visual Studio 2010, I've had 3 people ask me: "Is there some sort of magic you have to do to get VS2010 to attach to the IIS worker process (w3wp)"?&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, in the interest of (hopefully) saving you some time, I figure I'd write a little bit about what the problem with the VS2010 debugger is. Actually, the debugger is fine, it doesn't have any problems attaching; it's actually VS2010 itself that has a minor bug(?) while attaching.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As you can see in the image below, under normal circumstances Visual Studio automatically detects what type of code the process is running and automatically chooses the correct debugger:&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_U0AuZcqOces/S-l8Mxj22BI/AAAAAAAAAHs/Z33S0t13fa0/s1600/vs2010debugger.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 268px;" src="http://1.bp.blogspot.com/_U0AuZcqOces/S-l8Mxj22BI/AAAAAAAAAHs/Z33S0t13fa0/s400/vs2010debugger.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5470039781322184722" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Unfortunately, however, I've found that sometimes VS2010 cannot detect the correct code type in the worker process and attaches to the process using the .NET 4.0 debugger (I don't know why this happens nor do I know if this happens when attaching to other processes).&lt;br /&gt;&lt;br /&gt;If you attach using the wrong debugger, you'll attach, but you'll notice that none of your symbols ever load and therefore none of your breakpoints ever hit. It's actually somewhat frustrating because everything looks like it should be working but doesn't.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But enough talk about the problem; here's all you need to do to solve the problem if you notice you're not using the right debugger:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Hit the "Select" button the in "Attach to Process" window.&lt;/li&gt;&lt;li&gt;Select the "Debug these code types:" radio button&lt;/li&gt;&lt;li&gt;Check all the code types you want to debug.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;You're shooting for something like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_U0AuZcqOces/S-mAyIVo9GI/AAAAAAAAAH0/_MeORGoNavI/s1600/vs2010debugger2.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 209px;" src="http://4.bp.blogspot.com/_U0AuZcqOces/S-mAyIVo9GI/AAAAAAAAAH0/_MeORGoNavI/s400/vs2010debugger2.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5470044821138240610" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I've found that after you choose the code types you want to debug, VS2010 remembers your selection, so you should never have problems attaching in the future.&lt;br /&gt;&lt;br /&gt;Now, if I could just get rid of that stupid dialog asking me to confirm if I really want to attach to the "potentially dangerous" w3wp process, I'd be set. :)&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-6783628344120918398?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/6783628344120918398/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2010/05/visual-studio-2010-debugger-not.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6783628344120918398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6783628344120918398'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2010/05/visual-studio-2010-debugger-not.html' title='Visual Studio 2010 Debugger Not Attaching Problem'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_U0AuZcqOces/S-l8Mxj22BI/AAAAAAAAAHs/Z33S0t13fa0/s72-c/vs2010debugger.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-4544476331270182251</id><published>2010-01-13T17:28:00.004-07:00</published><updated>2010-10-26T19:36:49.506-07:00</updated><title type='text'>3 Simple Rules To Good Object Oriented Code</title><content type='html'>Mike and I had a long discussion about &lt;a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development"&gt;BDD&lt;/a&gt; last night. After he complained about how BDD didn't lead him to the solution he &lt;span style="font-style:italic;"&gt;wanted&lt;/span&gt;, I said something to the effect of "You know, the only reason we have all these design methodologies is because we don't really know how to think OOP and write OOP".&lt;br /&gt;&lt;br /&gt;At this point, before I continue, I need make something clear: I don't know what I'm talking about; all I know about BDD is what Wikipedia says about it. But I do know that writing good OO code doesn't require 3 different methodologies. All it requires if for programmers to think like objects.&lt;br /&gt;&lt;br /&gt;I like to think that good OO comes down to 3 simple rules:&lt;div&gt;&lt;ol&gt;&lt;li&gt;Objects are all about behavior; not attributes. If attributes defined objects, a cat and a dog would pretty much be the same thing since they both have eyes, noses, legs, etc.&lt;/li&gt;&lt;li&gt;Objects are discrete things from which you can build other things. They're a lot like &lt;a href="http://adotnetdude.blogspot.com/2009/06/how-to-write-reusable-software-lesson.html"&gt;LEGO blocks&lt;/a&gt;. Incidentally, code reuse is a byproduct of good OO code, not the purpose of it.&lt;/li&gt;&lt;li&gt;Objects like to be autonomous self directed entities. Objects don't like "managers"; if your code has lots of managers, you're probably doing something wrong. Objects like to coordinate their work through events; they don't like managers telling them exactly what to do at every point.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;A bonus rule: Composition is usually better than inheritance; it gives you a lot more flexibility when having to change behavior.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To be honest: I'm mostly writing this because I'd like to hear from others what guiding principles you should have in your head when coding. Do we really need a lot of process if we just in our guts &lt;i&gt;know &lt;/i&gt;how to write OO code?&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-4544476331270182251?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/4544476331270182251/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2010/01/3-simple-rules-to-good-object-oriented.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4544476331270182251'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4544476331270182251'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2010/01/3-simple-rules-to-good-object-oriented.html' title='3 Simple Rules To Good Object Oriented Code'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-3850097821530421383</id><published>2009-10-28T19:49:00.003-07:00</published><updated>2009-10-28T19:58:46.228-07:00</updated><title type='text'>The hardest thing about programming.</title><content type='html'>When asked what the hardest thing about programming is, Bill Gates answered:&lt;br /&gt;&lt;blockquote&gt;The hardest part is deciding what the algorithms are, and then simplifying them as much as you can. It’s difficult to get things down to their simplest forms. You have to simulate in your mind how the program’s going to work, and you have to have a complete grasp of how the various pieces of the program work together. The finest pieces of software are those where one individual has a complete sense of exactly how the program works. To have that, you have to really love the program and concentrate on keeping it simple, to an incredible degree.&lt;/blockquote&gt;What's interesting, however, is that the hardest thing about programming is also the best thing about programming.&lt;br /&gt;&lt;br /&gt;I love programming because learning it is relatively easy, but mastering the art is extremely difficult. Like Gates says, reducing things to their simplest form is difficult - but fortunately, it's also beautiful. It's also true that the finest software is written by those who love the program and make a deliberate effort to keep it simple - and again, although difficult, being able to model an entire system in your head is pretty awesome!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-3850097821530421383?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/3850097821530421383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2009/10/hardest-thing-about-programming.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/3850097821530421383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/3850097821530421383'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2009/10/hardest-thing-about-programming.html' title='The hardest thing about programming.'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-5391842444802592170</id><published>2009-10-06T10:54:00.003-07:00</published><updated>2009-10-06T16:33:23.393-07:00</updated><title type='text'>Simple Events In ASP.NET MVC</title><content type='html'>We've been busy improving our customer facing applications. Our new marketing VP noticed some significant improvements that could be made in the workflow of our customer acquisition funnel.&lt;br /&gt;&lt;br /&gt;Making the changes that our marketing VP recommended required some major code changes so we took the opportunity to move our web apps into ASP.NET MVC.&lt;br /&gt;&lt;br /&gt;One of the early decisions we made was to put as little business and application logic on our controllers as possible. Finding a place for business logic is straightforward most of the time; it usually belongs in your (domain) Models.&lt;br /&gt;&lt;br /&gt;Placing application logic in the right place gets a little more complicated. We don't really have services for stuff like sending out emails, etc. so we have to write classes to do all that work. &lt;br /&gt;&lt;br /&gt;Invoking email code, authentication code, etc. right in the controller is an ugly solution. To solve our problem, I came up with a simple eventing mechanism that allows us to move all application code out of our controllers.&lt;br /&gt;&lt;br /&gt;Let's first start with what the code in one of the controllers would look like:&lt;br /&gt;&lt;pre name="code" class="csharp"&gt;&lt;br /&gt;[AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken]&lt;br /&gt;public ActionResult Index(IndexModel model)&lt;br /&gt;{&lt;br /&gt;     //code to interact with your model goes here.&lt;br /&gt;     &lt;br /&gt;     //And now the event code:&lt;br /&gt;     AcmeEvents.Raise(new IndexRanEvent { IndexModel = model });&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The great thing about the code above is that all sort of things could now happen once your index runs; there may be 1 or N subscribers to the event above. Furthermore, you could (at run time) change the code that runs when the event triggers... but I'm getting ahead of my self; we'll look at how that could happen in just a second.&lt;br /&gt;&lt;br /&gt;Let's now look at the "raise event code". To do this, I decided to just use Unity's IoC container to resolve the code should trigger when the event get's raised:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="csharp"&gt;&lt;br /&gt;public static void Raise&amp;lt;T&amp;gt;(T args) where T : IAcmeEvent&lt;br /&gt;{&lt;br /&gt;     foreach(var handler in unityContainer.ResolveAll&amp;lt;Handles&amp;lt;T&amp;gt;&amp;gt;())&lt;br /&gt;     {&lt;br /&gt;          handler.Handle(args);&lt;br /&gt;     }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Some assumptions the code above makes: (1) IAcmeEvent has a Hanlde method; (2) by the time the Raise method runs, the IoC container must have been initialized to map the different "event types" to the specific implementations that will execute.&lt;br /&gt;&lt;br /&gt;How you initialize the container is really not that important: you could do it in code, through a config, or any other method of your choice. What is important, however, is that when you initialize your container, you do it in such a way that code from other assemblies can execute. If you do this, you could literally just drop assemblies in your application and add to or change the behavior of your app.&lt;br /&gt;&lt;br /&gt;So there you have it; a simple eventing mechanism to keep your MVC controllers unpolluted from application logic. I'm really happy about coming up with this solution; I hope you find it useful too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-5391842444802592170?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/5391842444802592170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2009/10/simple-events-in-aspnet-mvc.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/5391842444802592170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/5391842444802592170'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2009/10/simple-events-in-aspnet-mvc.html' title='Simple Events In ASP.NET MVC'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-5333133833530372843</id><published>2009-08-05T13:37:00.010-07:00</published><updated>2009-08-05T14:37:06.991-07:00</updated><title type='text'>Barricading Your Code</title><content type='html'>You've heard it a million times: "Never trust your inputs". Or maybe you've heard its corollary: "Always sanitize your inputs". Easier said then done, right?&lt;br /&gt;&lt;br /&gt;I'd like to show you a way to &lt;span style="font-style: italic;"&gt;barricade&lt;/span&gt; your code so that you can always sanitize your inputs without littering all of your code with sanitation code.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://upload.wikimedia.org/wikipedia/en/2/24/Nassauwall.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 303px; height: 224px;" src="http://upload.wikimedia.org/wikipedia/en/2/24/Nassauwall.JPG" alt="Wall Street Barricade" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The key to writing good sanitation code is controlling &lt;span style="font-style: italic;"&gt;where and how&lt;/span&gt;you accept external input. Just like the barricade in the image above, traffic can &lt;span style="font-style: italic;"&gt;only&lt;/span&gt; flow on the sidewalks and not on the street.&lt;br /&gt;&lt;br /&gt;Here's how to accomplish the same with code:&lt;br /&gt;&lt;pre name="code" class="csharp"&gt;&lt;br /&gt;public class ClassThatUsesBarricade&lt;br /&gt;{&lt;br /&gt;    public void DoWork(string inputOne, int inputTwo, ...)&lt;br /&gt;    {&lt;br /&gt;         //sanitize inputs&lt;br /&gt;         RealDoWork(inputOne, inputTwo, ...);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private void RealDoWork(string inputOne, int inputTwo, ...)&lt;br /&gt;    {&lt;br /&gt;         //don't worry about inputs because no external class could have called this.&lt;br /&gt;         //do work&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;By writing code like the code above, you've barricaded your class: data can only flow into your class through the public method. The private method can absolutely, 100% or your money back, trust its inputs without having to worry about sanitizing them. This way, your real work method can be short, and concise - after all, a method should only do one thing, and do it well.&lt;br /&gt;&lt;br /&gt;If your class has a lot of methods with very similar signatures that do similar things, you might want to reverse the code I showed: you could have a private sanitation code that all public methods that actually do work call. However, that's not really barricading your important methods... at some point you could forget to call the private sanitation method (ie. set up your barricade), and you'd be screwed.&lt;br /&gt;&lt;br /&gt;And there you have it, a code barricade.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-5333133833530372843?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/5333133833530372843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2009/08/barricading-your-code.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/5333133833530372843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/5333133833530372843'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2009/08/barricading-your-code.html' title='Barricading Your Code'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-8258830062674945086</id><published>2009-07-07T20:35:00.008-07:00</published><updated>2009-07-07T21:32:11.490-07:00</updated><title type='text'>When to use Class Inheritance in Programming</title><content type='html'>Last week I listened to a friend of mine complain about some straight-out-of-college programmers he had recently hired: "All of their code has 10 layers of inheritance. It's crazy trying to maintain their code!".&lt;div&gt;Unfortunately my friend is right: inheritance, although powerful - when used correctly, naturally tends to increase complexity.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Since your primary purpose as a programmer is to manage and reduce complexity, you should favors solutions that don't use inheritance. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;At this point you're probably asking yourself: When am I supposed to use inheritance? How do I know if I'm using it correctly?Fortunately, the great Steve McConnel, has written 4 clear cut rules on when to use inheritance and when to use containment:&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;1. If multiple classes share &lt;b&gt;&lt;i&gt;common data but not behavior&lt;/i&gt;&lt;/b&gt;, create a common object that those classes contain.&lt;/blockquote&gt;&lt;blockquote&gt;2. If multiple classes share &lt;b&gt;&lt;i&gt;common behavior but not data&lt;/i&gt;&lt;/b&gt;, derive them from a common bases class that defines the common routines.&lt;/blockquote&gt;&lt;blockquote&gt;3. If multiple clses share &lt;b&gt;&lt;i&gt;commond data and behavior&lt;/i&gt;&lt;/b&gt;, inherit from a common base class that defines the common data and routines.&lt;/blockquote&gt;&lt;blockquote&gt;4. Inherit when you want the base class to control your itnerface; contain when you want to control the interface.&lt;br /&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In summary, only inherit if the new class truly &lt;i&gt;is-a &lt;/i&gt;more specialized version of the base class. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Oh, and one more piece of advice on inheritance: avoid &lt;i&gt;multiple &lt;/i&gt;inheritance like the plague.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-8258830062674945086?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/8258830062674945086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2009/07/when-to-use-class-inheritance-in.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/8258830062674945086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/8258830062674945086'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2009/07/when-to-use-class-inheritance-in.html' title='When to use Class Inheritance in Programming'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-2388295375091719423</id><published>2009-06-15T19:12:00.007-07:00</published><updated>2009-06-15T20:10:34.634-07:00</updated><title type='text'>How To Write Reusable Software: A Lesson From LEGO Blocks</title><content type='html'>I don't know about the places where you have worked, but where I've worked we haven't had a very good track record for writing code that actually gets re-used. In fact, at one place we even gave up: "Software reuse is overrated" a boss muttered once.&lt;br /&gt;&lt;br /&gt;I think the reason we fail so miserably is that we focus too much on the end goal (reusable code), and too little on the qualities that make software reusable. What, then, are the properties of reusable code? Well, that's where the LEGO blocks part comes in.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://upload.wikimedia.org/wikipedia/commons/thumb/3/32/Lego_Color_Bricks.jpg/800px-Lego_Color_Bricks.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 800px; height: 536px;" src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/32/Lego_Color_Bricks.jpg/800px-Lego_Color_Bricks.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The LEGO block analogy comes from David West's &lt;span style="font-style: italic;"&gt;Object Thinking&lt;/span&gt;, but I'd like to highlight a few ideas that make this metaphor so applicable to software development:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;The interface is simple and intuitive. &lt;/span&gt;I've seen my 3 year old daughter build ships with LEGOs. If you want your code to be reused, it should be so simple and so intuitive that others could use it without having to refer to external documentation.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;There's a finite and small number of LEGO block types.&lt;/span&gt; If you find that your library has a high number of classes, think about what you are doing. After all, everything on this planet is made from the same 92 (naturally occurring) elements.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;LEGOs are cool because you can build stuff.&lt;/span&gt; The reason everyone loves LEGO blocks is because they can build whatever they want with them, not just what the box tells them to build. Your software should be the same way; you should be surprised by what end users build with your code. If your code only gets used for what you envisioned, you've failed to write reusable code: people are not able to &lt;span style="font-style: italic;"&gt;compose&lt;/span&gt; software with your code.&lt;/li&gt;&lt;/ul&gt;Finally, don't forget that people don't really care about the technical details behind LEGO blocks; no one cares how the plastic is molded, dyed, etc. LEGO blocks aren't reused because of how well they're manufactured; they're reused because they let end users accomplish their goals.&lt;br /&gt;&lt;br /&gt;Once people are able to accomplish their goals with your code, they'll be using it over and over gain. Guaranteed!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-2388295375091719423?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/2388295375091719423/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2009/06/how-to-write-reusable-software-lesson.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/2388295375091719423'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/2388295375091719423'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2009/06/how-to-write-reusable-software-lesson.html' title='How To Write Reusable Software: A Lesson From LEGO Blocks'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-2788037415556871103</id><published>2009-06-09T08:03:00.000-07:00</published><updated>2009-06-09T08:04:10.404-07:00</updated><title type='text'>Custom Thousand Separator In C#</title><content type='html'>I guess the NFA requires us to use a space (" ") instead of a comma (",") as our thousands separator. I dunno why the have to regulate something like that, but I had to figure out an elegant way to format our numbers the way the powers that be require them to be formatted.&lt;br /&gt;&lt;br /&gt;After struggling with different inelegant solutions for a little while, I finally realized that different countries use different symbols as thousands separators; I knew then that my problem was really a localization problem. A quick search in MSDN lead me to the &lt;a href="http://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.aspx"&gt;NumberFormatInfo&lt;/a&gt; class, which "defines how numeric values are formatted and displayed, depending on the culture" (MSDN).&lt;br /&gt;&lt;br /&gt;The NumberFormatInfo class, has a &lt;span style="font-weight: bold;"&gt;NumberGroupSeparator&lt;/span&gt; property that defines what character to use to separate thousands.&lt;br /&gt;&lt;br /&gt;So, here's how I ended up solving my problem:&lt;br /&gt;&lt;pre name="code" class="csharp"&gt;&lt;br /&gt;public void FormatDouble(double doubleToFormat)&lt;br /&gt;{&lt;br /&gt;     NumberFormatInfo nfi = new CultureInfo("en-US", false).NumberFormat;&lt;br /&gt;     nfi.NumberGroupSeparator = " ";&lt;br /&gt;     Write(doubleToFormat.ToString("n", nfi);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Neat, huh?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-2788037415556871103?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/2788037415556871103/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2009/06/custom-thousand-separator-in-c.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/2788037415556871103'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/2788037415556871103'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2009/06/custom-thousand-separator-in-c.html' title='Custom Thousand Separator In C#'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-6994477618082619387</id><published>2009-03-24T17:22:00.014-07:00</published><updated>2009-03-24T18:09:11.675-07:00</updated><title type='text'>Highly Parallel LINQ To Lucene Indexer</title><content type='html'>I've been wanting to post about this for a while, but haven't been able because I was away vacationing in Hawaii. :)&lt;br /&gt;&lt;br /&gt;I was recently given the assignment to index a couple of our tables that hold large amounts of data. Each tables has well over 3 million records, and each record is fairly large as it represents "emails" with our clients.&lt;br /&gt;&lt;br /&gt;I knew from the get-go I'd have to write a highly parallel process in order for the task to finish promptly - just bringing the data over the wire from the database takes about 45 minutes.&lt;br /&gt;&lt;br /&gt;I have to show a lot of code now, so please bear with me for just a second. The key here is to use several RamDirectory(s) for the small data chunks and merge them into a FSDirectory index that will hold all the data:&lt;br /&gt;&lt;pre name="code" class="csharp"&gt;&lt;br /&gt;namespace Indexer&lt;br /&gt;{ public class BatchIndexer[T] : ParallelIndexer[T]&lt;br /&gt; {&lt;br /&gt;  IQueryable[T] items;&lt;br /&gt;  bool isMergingFinished = false;&lt;br /&gt;  private static object lockObject = new object();&lt;br /&gt;&lt;br /&gt;  public override bool Stopped&lt;br /&gt;  {&lt;br /&gt;   get&lt;br /&gt;   {&lt;br /&gt;    var pstopped = base.Stopped;&lt;br /&gt;    if (pstopped == true)&lt;br /&gt;    {&lt;br /&gt;     return isMergingFinished;&lt;br /&gt;    }&lt;br /&gt;    else&lt;br /&gt;    {&lt;br /&gt;     return false;&lt;br /&gt;    }&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  //stop setting the temp directory here and force the client to pass it in&lt;br /&gt;  public BatchIndexer(string path, IQueryable[T] items)&lt;br /&gt;   : base(new Index[T](path))&lt;br /&gt;  {&lt;br /&gt;   this.items = items;&lt;br /&gt;   QueueChildren();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private void QueueChildren()&lt;br /&gt;  {&lt;br /&gt;   if (null != items &amp;&amp; items.Count() &gt; 0)&lt;br /&gt;   {&lt;br /&gt;    const int pageSize = 100;&lt;br /&gt;    int pageIndex = 0;&lt;br /&gt;&lt;br /&gt;    var currentPage = items.Take(pageSize);&lt;br /&gt;    int pageCount = 1 + items.Count() / pageSize;&lt;br /&gt;    while (pageIndex &lt; pageCount)&lt;br /&gt;    {&lt;br /&gt;     ThreadPool.QueueUserWorkItem(new WaitCallback(QueueChild), currentPage);&lt;br /&gt;     pageIndex++;&lt;br /&gt;     currentPage = items.Skip(pageIndex * pageSize).Take(pageSize);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    //wait for all children to be added to parent&lt;br /&gt;    while (Children.Count() &lt; pageCount)&lt;br /&gt;    {&lt;br /&gt;     Thread.Sleep(2000);&lt;br /&gt;    }&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private void QueueChild(object stateInfo)&lt;br /&gt;  {&lt;br /&gt;   var currentPage = stateInfo as IQueryable[T];&lt;br /&gt;   lock (lockObject)&lt;br /&gt;   {&lt;br /&gt;    AddChild(new BatchIndexerChild[T](new Index[T](), currentPage.ToList()));&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public override void Run()&lt;br /&gt;  {&lt;br /&gt;   //start indexing the children&lt;br /&gt;   foreach (var item in this.Children)&lt;br /&gt;   {&lt;br /&gt;    var child = item as BatchIndexerChild[T];&lt;br /&gt;    ThreadPool.QueueUserWorkItem(new WaitCallback(child.AsyncRun));&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   //wait for all of the children to finish indexing&lt;br /&gt;   while (!IsChildrenStopped)&lt;br /&gt;   {&lt;br /&gt;    Thread.Sleep(1000);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   //merge all indeces into main index&lt;br /&gt;   this.Merge((from c in this.Children select c.Index.Directory).ToArray());&lt;br /&gt;   isMergingFinished = true;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  protected override void Dispose(bool disposing)&lt;br /&gt;  {&lt;br /&gt;   base.Dispose(disposing);&lt;br /&gt;   if (disposing)&lt;br /&gt;   {&lt;br /&gt;    //release managed resource&lt;br /&gt;    if (this.Index != null)&lt;br /&gt;    {&lt;br /&gt;     this.Index.Dispose();&lt;br /&gt;    }&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I particularly like the approach I used because it threads the chunking of the data into smaller pieces AND is also threads the actual indexing of each chunk.&lt;br /&gt;&lt;br /&gt;If you're going to index as much data as I had to index, however, you still have to pre-chunk the data and feed into several instances BatchIndexer; I found that 100,000 records was optima. You'll also want to make sure you release all database resources ASAP: you don't to be hogging a whole bunch of memory! &lt;br /&gt;&lt;br /&gt;Anyhow, I hope this code is useful... it should at least give you start in the right direction. Let me know if you have any questions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-6994477618082619387?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/6994477618082619387/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2009/03/highly-parallel-linq-to-lucene-indexer.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6994477618082619387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6994477618082619387'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2009/03/highly-parallel-linq-to-lucene-indexer.html' title='Highly Parallel LINQ To Lucene Indexer'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-3317155087065197417</id><published>2009-02-22T19:54:00.003-07:00</published><updated>2009-02-26T20:54:02.051-07:00</updated><title type='text'>Factory Pattern</title><content type='html'>After reading &lt;a href="http://adotnetdude.blogspot.com/2008/03/refactoring-code-with-too-many.html"&gt;this&lt;/a&gt; article, a reader recently requested that I show some sample code for the "factory" mentioned in the article.&lt;br /&gt;&lt;br /&gt;Before I give you some sample code, however, let me just write a few words about the Factory Pattern: As the pattern's name suggests, the Factory Pattern creates stuff. Specifically, "factories" create classes without coupling you to a specific instance of the classes it creates.&lt;br /&gt;&lt;br /&gt;Here is some sample code:&lt;br /&gt;&lt;pre name="code" class="csharp"&gt;public class CreditCardBase&lt;br /&gt;{&lt;br /&gt;  //this is the base class that all credit cards implement:&lt;br /&gt;  //it could be an abstract class, or it could have some functionality;&lt;br /&gt;  //it could also be an interface... whatever floats your boat.&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static class CreditCardFactory&lt;br /&gt;{&lt;br /&gt;  public static CreditCardBase GetCreditCard(object someObject)&lt;br /&gt;  {&lt;br /&gt;       //business logic that returns correct credit cart type goes in here.&lt;br /&gt;       if(someObject == "something")&lt;br /&gt;            return new Visa(); //visa of course implements CreditCardBase&lt;br /&gt;       else&lt;br /&gt;            return new Amex(); //also implements CreditCardBase&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class CreditClassClient&lt;br /&gt;{&lt;br /&gt;   //this class consumes a credit card&lt;br /&gt;   public void DoWork()&lt;br /&gt;   {&lt;br /&gt;        CreditCardBase myCreditCard = CreditCardFactory.GetCreditCard(new bizObject());&lt;br /&gt;        //do stuff with myCreditCard&lt;br /&gt;        myCreditCard.Run();&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And there you have it. That's pretty much all there's to it, and the code is pretty self explanatory.&lt;br /&gt;&lt;br /&gt;There's one more thing that's worth mentioning: usually, classes returned by factories have private constructors - to avoid people instantiating the class without calling the factory. This, however is problematic for several reasons:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You may have clients that already instantiate your class.&lt;/li&gt;&lt;li&gt;People usually make private constructors singletons (please don't).&lt;/li&gt;&lt;li&gt;How do you extend a class that has a private constructor? :)&lt;/li&gt;&lt;/ol&gt;Finally, to the anonymous reader that asked for the factory code: let me know if this was useful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-3317155087065197417?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/3317155087065197417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2009/02/factory-pattern.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/3317155087065197417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/3317155087065197417'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2009/02/factory-pattern.html' title='Factory Pattern'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-3117510726436609793</id><published>2009-02-10T21:50:00.001-07:00</published><updated>2009-02-10T21:51:06.026-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='finance'/><title type='text'>How Not To Lose Money In The Stock Market</title><content type='html'>One of the most important rules to remember when investing in the financial markets is to &lt;span style="font-weight: bold;"&gt;Preserve Your Capital!&lt;/span&gt; Not losing money is the first step before you can &lt;span style="font-style: italic;"&gt;make &lt;/span&gt;any money.&lt;br /&gt;&lt;br /&gt;And although I haven't figure out a technique that guarantees 10% yearly gains, I have figured out a pretty good technique for not losing money in major market draw downs. Allow me to show you a chart of one of the &lt;a href="http://en.wikipedia.org/wiki/Exchange-traded_fund"&gt;ETFs&lt;/a&gt; I like to use to trade:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_U0AuZcqOces/SZIvEn5nVkI/AAAAAAAAAFg/fawGHTkpO10/s1600-h/qldMA.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 181px;" src="http://2.bp.blogspot.com/_U0AuZcqOces/SZIvEn5nVkI/AAAAAAAAAFg/fawGHTkpO10/s400/qldMA.JPG" alt="" id="BLOGGER_PHOTO_ID_5301351467845113410" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The chart to above shows the daily price for QLD, along with the 50-day exponential moving average (in red) and the 10-day exponential moving average (in blue). At the bottom of the chart, you can also see the daily trading volume.&lt;br /&gt;&lt;br /&gt;What's interesting in the QLD chart is that during the past year every major market drop has been preceded by a clear signal: the 10-day EMA crosses the 50-day EMA (heading down, of course). And this, even when the market has faced major volatility and huge daily drops.&lt;br /&gt;&lt;br /&gt;You can go back as far as you like, and you'll find that the signal above always hold true. And this is not because I'm so awesome and I've figured out some magic formula - no, it holds true because of the very definition of &lt;a href="http://www.investopedia.com/terms/e/ema.asp"&gt;EMA&lt;/a&gt;. The EMA lines just show you the averages of the stock price for the last 50 and 10 days respectively.&lt;br /&gt;&lt;br /&gt;Of course this technique isn't perfect: you will lose &lt;span style="font-style: italic;"&gt;some &lt;/span&gt;money before the 10-day EMA crosses the 50-day EMA; but at least you won't lose more that 50% of your money, like several people have in the past year.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Disclaimer: &lt;/span&gt;Don't take financial advice from a guy that writes software for a living (i.e. me). Also, don't take advice that makes a living selling financial advice (i.e. your financial advisor). Those guys don't make money in the markets; they make money making you feel good about losing 50% of your capital.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-3117510726436609793?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/3117510726436609793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2009/02/how-not-to-lose-money-in-stock-market.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/3117510726436609793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/3117510726436609793'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2009/02/how-not-to-lose-money-in-stock-market.html' title='How Not To Lose Money In The Stock Market'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_U0AuZcqOces/SZIvEn5nVkI/AAAAAAAAAFg/fawGHTkpO10/s72-c/qldMA.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-3434193040089551294</id><published>2009-02-05T19:24:00.003-07:00</published><updated>2009-02-05T19:52:53.241-07:00</updated><title type='text'>ASP.NET MVC Release Candidate Now Available!</title><content type='html'>The release candidate for Microsoft's ASP.NET is finally &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=f4e4ee26-4bc5-41ed-80c9-261336b2a5b6&amp;amp;displaylang=en"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Sure, this is just another "me-too" Microsoft product: we've had Rails, Cake, and Grails - but this is great news nonetheless! The ASP.NET web forms model is one that I never really understood: Why would you try to imitate a windows form on the web? Anyhow, web forms have been long over-due for a replacement, and now MVC provides a great architectural pattern for building web apps with the .NET framework.&lt;br /&gt;&lt;br /&gt;Scott Gu, has written and in-depth &lt;a href="http://weblogs.asp.net/scottgu/archive/2009/01/27/asp-net-mvc-1-0-release-candidate-now-available.aspx"&gt;article&lt;/a&gt; describing some of the most important improvements on this RC. And, from what Phil Haack said on his &lt;a href="http://haacked.com/"&gt;blog&lt;/a&gt; about this release, I get the feeling there's just a few minor bugs that need to be addressed before the RTM. You could probably start using the RC now without any concerns. In fact, I have a co-worker that has been writing a site on MVC since beta with no problems at all.  Another co-worker mentioned to me today how much more productive he was under the MVC model than the WebForms model.&lt;br /&gt;&lt;br /&gt;If you're still unsure about ASP.NET MVC, go check out &lt;a href="http://stackoverflow.com/"&gt;stackoveflow.com&lt;/a&gt;. StackOverflow was written on the beta release of the MVC stack, and it's an awesome site.&lt;br /&gt;&lt;br /&gt;Now, if you're still unsure, just trust me on this one: put your WebForms on the ground, back away slowly! I don't want anyone getting injured here. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-3434193040089551294?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/3434193040089551294/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2009/02/aspnet-mvc-release-candidate-now.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/3434193040089551294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/3434193040089551294'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2009/02/aspnet-mvc-release-candidate-now.html' title='ASP.NET MVC Release Candidate Now Available!'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-4599378154504733403</id><published>2009-01-26T16:33:00.006-07:00</published><updated>2009-01-27T19:19:16.911-07:00</updated><title type='text'>Software Engineering: There's nothing like it!</title><content type='html'>&lt;h3&gt;Intro&lt;/h3&gt;&lt;br /&gt;Seriously, there's no other type of engineering like software engineering. And that, may or may not be a good thing: it just depends on what you decide to focus on.&lt;br /&gt;&lt;br /&gt;I went to school in the same building where the mechanical engineers, chemical engineers, and civil engineers went to school - yes, I spent almost every waking hour of my college life in the infamous &lt;a href="http://www.et.byu.edu/college_facilities.htm"&gt;Clyde Building&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_U0AuZcqOces/SX5P-ag8RcI/AAAAAAAAAFI/3LfiWH56Di0/s1600-h/clyde.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 187px; height: 150px;" src="http://2.bp.blogspot.com/_U0AuZcqOces/SX5P-ag8RcI/AAAAAAAAAFI/3LfiWH56Di0/s400/clyde.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5295758145522255298" /&gt;&lt;/a&gt;&lt;br /&gt;Yes, for those of you that are wondering, that building has no windows. I'm pretty sure they designed it that way so that your soul would be crushed within the first semester of your career. But that's beside the point: You want to know what I learned in 4 years as an EE at BYU? Well, for the most part, I learned a whole bunch of math... oh yea, and I also learned that writing software isn't like making bridges, roads or "stuff".&lt;br /&gt;&lt;br /&gt;And here's why software enginnering is so different: &lt;span style="font-style:italic;"&gt;software is cheap&lt;/span&gt; to make (Yeah, that's right; even though you think you're making big bucks by writing software, you're still cheap compared to what goes into creating a new car design). Oh, and there's something else: &lt;span style="font-style:italic;"&gt;writing software is much harder than building bridges&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Software is hard&lt;/h3&gt;&lt;br /&gt;See, we can't really prove software will "work". Proving that a program will work according to the specs is pretty much a &lt;a href="http://en.wikipedia.org/wiki/Halting_problem"&gt;halting problem&lt;/a&gt; - that is, given a program and a finite input set, we can't even prove whether the program will even terminate!&lt;br /&gt;&lt;br /&gt;Civil engineers, on the other hand have it easy: given a bridge and environment conditions (load, winds, etc.), they can tell you whether the bridge will stand or not. In fact, it's so easy to "model" bridges that we software engineers have written programs to tell you whether you've built a good bridge or not.&lt;br /&gt;&lt;br /&gt;Software is also harder because as long as the program "works", it doesn't matter what the source code may look like. Sure, some code may be harder to maintain than other, but how do you tell? There's no metrics for code design; we only have &lt;a href="http://en.wikipedia.org/wiki/Code_smell"&gt;smells&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Software is cheap&lt;/h3&gt;&lt;br /&gt;Let's not move on to why software is cheap. If you write a program that doesn't work according to specs, it's not a big deal: you just go back to Notepad, change a little bit of text and (perhaps) recompile. Even software distribution is cheap: when was the last time you got software in a CD? We could spend a lot of time and effort finding bugs and/or proving our program works correctly, but why would we do that? After some point, it really doesn't make sense to spend money finding and solving bugs that may never surface in normal use.&lt;br /&gt;&lt;br /&gt;On the other hand, if you screw the pooch on a bridge you're toast: it's hard to fix, and it was really expensive to build (not to mention how much time it actually take to build). This is why civil engineers, plan, model, test and then finally, after a really long time, build. We just build because it's fast to build. How awesome is that?!&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;Now you know why you're much better than all those other engineers out there. So go rub it in their faces whenever you feel like it. :p&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-4599378154504733403?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/4599378154504733403/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2009/01/software-engineering-theres-nothing.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4599378154504733403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4599378154504733403'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2009/01/software-engineering-theres-nothing.html' title='Software Engineering: There&apos;s nothing like it!'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_U0AuZcqOces/SX5P-ag8RcI/AAAAAAAAAFI/3LfiWH56Di0/s72-c/clyde.gif' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-4053004646958991698</id><published>2009-01-23T09:42:00.002-07:00</published><updated>2009-01-23T10:10:19.221-07:00</updated><title type='text'>What do programmers do?</title><content type='html'>Have you been ever asked what you do for work? I have, and it's always hard for me to answer: if I say I'm a computer programmer people immediately think I can fix their printer - or worse, they want me to build them a dating website for five hundred bucks.&lt;br /&gt;&lt;br /&gt;The truth is that what we "computer scientists" do is more along the lines of what sorcerers do. &lt;a href="http://groups.csail.mit.edu/mac/users/hal/"&gt;Hal Abelson&lt;/a&gt; describes it really well:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Computational processes are abstract beings that inhabit computers. As they evolve, processes manipulate other abstract things called data. The evolution of a process is directed by a pattern of rules called a program. People create programs to direct processes. In effect, we conjure the spirits of the computer with our spells.&lt;br /&gt;&lt;br /&gt;A computational process is indeed much like a sorcerer's idea of a spirit. It cannot be seen or touched. It is not composed of matter at all. However, it is very real. It can perform intellectual work. It can answer questions. It can affect the world by disbursing money at a bank or by controlling a robot arm in a factory. The programs we use to conjure processes are like a sorcerer's spells. They are carefully composed from symbolic expressions in arcane and esoteric programming languages that prescribe the tasks we want our processes to perform.&lt;br /&gt;&lt;br /&gt;A computational process, in a correctly working computer, executes programs precisely and accurately. Thus, like the sorcerer's apprentice, novice programmers must learn to understand and to anticipate the consequences of their conjuring. Even small errors (usually called bugs or glitches) in programs can have complex and unanticipated consequences.&lt;br /&gt;&lt;br /&gt;Fortunately, learning to program is considerably less dangerous than learning sorcery, because the spirits we deal with are conveniently contained in a secure way. Real-world programming, however, requires care, expertise, and wisdom. A small bug in a computer-aided design program, for example, can lead to the catastrophic collapse of an airplane or a dam or the self-destruction of an industrial robot.&lt;br /&gt;&lt;br /&gt;Master software engineers have the ability to organize programs so that they can be reasonably sure that the resulting processes will perform the tasks intended. They can visualize the behavior of their systems in advance. They know how to structure programs so that unanticipated problems do not lead to catastrophic consequences, and when problems do arise, they can debug their programs. Well-designed computational systems, like well-designed automobiles or nuclear reactors, are designed in a modular manner, so that the parts can be constructed, replaced, and debugged separately.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Although I'm attributing the quote to Abelson, the text above comes from the book &lt;span style="font-style:italic;"&gt;Structure and Interpretation of Computer Programs&lt;/span&gt;, written by Albeson, Sussman, and Sussman. The reason I'm attributing the quote to Albeson is because I first came across this by watching one of his MIT lectures on the same topic. &lt;br /&gt;&lt;br /&gt;If you're interested in watching MIT's introductory "Structure and Interpretation of Computer Programs" class, you can find the videos &lt;a href="http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;And now, go conjure some spirits!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-4053004646958991698?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/4053004646958991698/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2009/01/what-do-programmers-do.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4053004646958991698'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4053004646958991698'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2009/01/what-do-programmers-do.html' title='What do programmers do?'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-5731101929534510742</id><published>2009-01-15T19:26:00.005-07:00</published><updated>2009-02-01T18:42:15.399-07:00</updated><title type='text'>The Perils of Sushi Bars</title><content type='html'>&lt;span style="font-style:italic;"&gt;This is the story of how my credit card was almost stolen by a Samurai in a sushi bar in Salt Lake City. If you're interested, read on.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;About 2 months ago I went to a sushi restaurant here in Salt Lake City. After paying our bills and while we were walking out, Kevin (one of my co-workers) noticed that his receipt had his full credit card number printed on it. Rightly concerned, he immediately talked with the restaurant's manager and asked to see the restaurant's copy of his receipt - sure enough, the restaurant was storing hundreds of credit card numbers in their little dinky cash register.&lt;br /&gt;&lt;br /&gt;The whole incident got me thinking about credit card transactions. Every time I buy something with a credit card it's like I'm handing my wallet over to the clerk and saying: "Here's my wallet. Take whatever you need and just hand it back when you're done." Who knows what the POS machine is doing with my credit card number! And that's the least of my concerns: What about the lame payment gateway that stores millions of credit card numbers on servers that will likely be hacked in the next 5 years?&lt;br /&gt;&lt;br /&gt;Interestingly enough, however, the whole credit card thing seems to work remarkably well. I mean, there's little risk in the sushi bar overcharging; after all, I know where they're at, and I also have the the credit card company on my side: one call to the them and the restaurant we'll have to pay the bill. As far as the payment gateway is concerned, even thought there's the PCI standard, when they get hacked we all pay the cost (either thorough higher interest rates, more taxes, etc)... that's why I'm really concerned about them - I worked at a place where we were PCI compliant, but there were still gaping holes in our security model.&lt;br /&gt;&lt;br /&gt;This particular sushi story, however, has a happy ending. We recently went back to the restaurant and were pleasantly surprised to see that our full numbers were no longer being printed on receipts. It's good to see that non-IT folks are finally starting to get the importance of securing information.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-5731101929534510742?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/5731101929534510742/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2009/01/perils-of-sushi-bars.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/5731101929534510742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/5731101929534510742'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2009/01/perils-of-sushi-bars.html' title='The Perils of Sushi Bars'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-6320261797904137805</id><published>2009-01-08T18:38:00.000-07:00</published><updated>2009-01-08T18:35:58.314-07:00</updated><title type='text'>Steve Yegge Is My Hero</title><content type='html'>I regularly read &lt;a href="http://joelonsoftware.com"&gt;Joel Spolky's blog&lt;/a&gt;, &lt;a href="http://codinghorror.com"&gt;Jeff Atwood's blog&lt;/a&gt;, and &lt;a href="http://steve-yegge.blogspot.com"&gt;Steve Yegge's blog&lt;/a&gt;. I really like them all, but Steve's is probably the most thought provoking blog out of the three.&lt;br /&gt;&lt;br /&gt;Recently, for example, he had a post where he discussed (at length), a very intersting topic:&lt;br /&gt;&lt;br /&gt;Imagine Mario, and his brother Luigi, having a conversation in which Mario asks Luigi what's on the other side of the boundary to their &lt;a href="http://www.amazon.com/gp/product/B001AU6W10?ie=UTF8&amp;tag=theramblofane-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B001AU6W10"&gt;Mario Kart&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=theramblofane-20&amp;l=as2&amp;o=1&amp;a=B001AU6W10" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;&lt;br /&gt; universe. Interesting, huh?&lt;br /&gt;&lt;br /&gt;It's interesting because to Mario &amp; Luigi, stuff on the "other" side of their universe boundary is "undefined"; it's undfined in the sense that anything could be there. In fact, to some extent, it doesn't even make sense for them to ask what's on the other side; they simply cannot define what's on the other side as long as they reside inside the Mario Kart universe.&lt;br /&gt;&lt;br /&gt;On the other hand, programmers living outside the Mario Kart universe can easily define what's outside the Mario Kart universe: all they have to do is inspect the memory contents of the system running Mario Kart, and take a peek at what's in there, on the "other" side.&lt;br /&gt;&lt;br /&gt;I enjoyed Steve's post on &lt;a href="http://steve-yegge.blogspot.com/2008/12/programmers-view-of-universe-part-2.html"&gt;embedded systems&lt;/a&gt;because it helped me make sense of the embedded system I live in. I now understand that anything could be out there; it's truly undefined.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-6320261797904137805?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/6320261797904137805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2009/01/steve-yegge-is-my-hero.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6320261797904137805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6320261797904137805'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2009/01/steve-yegge-is-my-hero.html' title='Steve Yegge Is My Hero'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-3858176608240642997</id><published>2009-01-08T16:32:00.006-07:00</published><updated>2009-01-08T17:37:55.913-07:00</updated><title type='text'>Lucene.net UnAuthorizedAccessException</title><content type='html'>Unless you specifically tell Lucene.net where to put its LOCK files (for the index readers and writers), it will put them in your OS's default temp directory (normally C:\Windows\TEMP\). This choice of location may be problematic.&lt;br /&gt;&lt;br /&gt;As you can imagine, there are plenty of scenarios under which Lucene.net may be running under an identity that does not have enough to access to your temp directory. Under such scenarios, you'll get an UnAuthorizedAccessException thrown at you; and your code may not even be around to handle it.&lt;br /&gt;&lt;br /&gt;To solution for this problem is easy; add the following to the &lt;appSettings&gt; section of your application's config file:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&lt;add key="Lucene.Net.lockdir" value="C:\SomeFolderOfYourChoice" /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;After doing this, make sure "Everyone" has full control of the folder you've chosen for Lucene.net to use as its LOCK file folder.&lt;br /&gt;&lt;br /&gt;You should also consider properly disposing your indices when your process finishes so that all locks are release on a timely basis. Unfortunately, I can't tell exactly how to do that - you'll just have to figure it out.&lt;br /&gt;&lt;br /&gt;Finally, if you're reading this for some other reason than having the exception thrown at you, you should really consider using Lucene. It's great!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-3858176608240642997?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/3858176608240642997/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2009/01/lucenenet-unauthorizedaccessexception.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/3858176608240642997'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/3858176608240642997'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2009/01/lucenenet-unauthorizedaccessexception.html' title='Lucene.net UnAuthorizedAccessException'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-4210524184639305084</id><published>2009-01-06T17:20:00.003-07:00</published><updated>2009-01-06T17:46:04.696-07:00</updated><title type='text'>2008 Reflections</title><content type='html'>Man, it feels good to be back to blogging! It was an awesome Christmas break, but I must admit I kept coming up with ideas I wanted to blog about.&lt;br /&gt;&lt;br /&gt;Anyhow, '08 was a great year for me: I moved to a great &lt;a href="http://ibfx.com"&gt;company&lt;/a&gt; and started blogging regularly. I also learned a lot of LINQ, some Ruby, and had some great personal moments.&lt;br /&gt;&lt;br /&gt;As a recap of 2008, I wanted to share my favorite posts so far:&lt;br /&gt;&lt;a href="http://adotnetdude.blogspot.com/2008/12/secret-behind-linq-to-sql.html"&gt;The Secret Behind SQL&lt;/a&gt;&lt;br /&gt;&lt;a href="http://adotnetdude.blogspot.com/2008/11/easy-background-tasks-in-aspnet.html"&gt;Easy Background Tasks in ASP.NET&lt;/a&gt;&lt;br /&gt;&lt;a href="http://adotnetdude.blogspot.com/2008/10/why-partial-classes-are-wrong-and-why.html"&gt;Why Partial Classes Are Wrong!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I also wanted to thank all of you that regularly read my blog. There's a few of you out there that are loyal readers, checking often whether I have new content or not;  knowing that you're reading makes me much more critical of what I write. Thanks for your time!&lt;br /&gt;&lt;br /&gt;Finally, here's and interesting graph of traffic on this blog:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_U0AuZcqOces/SWP5mj5LfjI/AAAAAAAAAFA/yLHR96HRytk/s1600-h/traffic.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 109px;" src="http://3.bp.blogspot.com/_U0AuZcqOces/SWP5mj5LfjI/AAAAAAAAAFA/yLHR96HRytk/s400/traffic.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5288344828328508978" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You see that spike right around Nov. 17th, 2008? That, my friends, comes from &lt;span style="font-style:italic;"&gt;one&lt;/span&gt;small comment buried among hundred of comment's in Jeff Atwood's &lt;a href="http://codinghorror.com"&gt;blog&lt;/a&gt;. Isn't that crazy? That blog is the black hole of developer effort; I swear every developer on planet earth goes there to waste their time... I can't find any other explanation for getting so much traffic from just one comment. Thanks Jeff! And thanks to everyone that followed the link and took time to read what I had to &lt;a href="http://adotnetdude.blogspot.com/2008/11/how-to-be-better-programmer.html"&gt;say&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;May 2009 be a great year for you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-4210524184639305084?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/4210524184639305084/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2009/01/2008-reflections.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4210524184639305084'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4210524184639305084'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2009/01/2008-reflections.html' title='2008 Reflections'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_U0AuZcqOces/SWP5mj5LfjI/AAAAAAAAAFA/yLHR96HRytk/s72-c/traffic.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-2406918634050518311</id><published>2008-12-19T15:17:00.003-07:00</published><updated>2008-12-19T21:37:02.689-07:00</updated><title type='text'>Why You Should Be Controversial</title><content type='html'>I have to tell you a story before any of this makes sense, so bear with me for a minute.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://murrayon.net/"&gt;Michael Murray&lt;/a&gt;, a good buddy of mine, IMed me today telling me he had been invited to write a blog post for the the main page of &lt;a href="http://tech.lds.org/"&gt;tech.lds.org&lt;/a&gt;. I was really happy for him; he deserves it as a tribute to his tireless contributions to the LDS tech community.&lt;br /&gt;&lt;br /&gt;Unfortunately, for reasons that I can understand, Mike was having a hard time coming up with what to say. I mean, there's tons you could say, but you have to be somewhat careful... after all some may mistake criticism  of the software the LDS Church employees write with criticism of the LDS Church period. And then there's also the fact that Mike really cares about the tech.lds community; he's an active moderator in it.&lt;br /&gt;&lt;br /&gt;Unfortunately, the tech.lds community suffers from the same problem any extremely homegenous community does: everyone says the same freaking thing all of the freaking time! Everyone talks about how IT is a means to an end; everyone talks about how we, as IT folk, should seek for way to further the Kingdom and be more wise servants. Please don't get me wrong: I know that what the tech.lds community preaches is true, but haven't we heard enough of that already?&lt;br /&gt;&lt;br /&gt;Why don't we talk about some of the real issues with IT at the Church?&lt;br /&gt;&lt;br /&gt;Here's a few ideas off the top of my head:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;How come LDS software is not open sourced? I still remember when I helped build my chapel back in Ecuador; truly a memorable experience - it was great to be able to contribute beyond tithing money. &lt;/li&gt;&lt;li&gt;How come phone numbers are tied to households in MLS? What's up with that?!? And even more important, how come that wasn't fixed 10 releases ago?&lt;/li&gt;&lt;li&gt;How come the IT department used to pay terrible salaries to IT employees? I recognize this is changing, but what kind of people was the IT department expecting to hire?&lt;/li&gt;&lt;li&gt;Why did it take 10 years for meetinghouses to get broadband internet access? Did IT managers really just learn of white lists?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Why does it take days to transfer membership records into a ward? Isn't it just a simple look up? And if it's not just a simple look up, how come it's not?&lt;/li&gt;&lt;li&gt;Why is the Church developing on the Java stack? When was the last time you saw MLS running on a Linux box?&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;I've been deliberately controversial on this post because I wanted to make point: if you're going to say something, you might as well say something that's worth thinking about. I suspect there are good answers to all of the questions I've listed above; furthermore, I realize in the grand scheme of things I know nothing compared to what the fine folks at the LDS Church do. But at least, you read this far and know you're thinking about software at the Church too.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Disclaimer: I cannot say it more clearly than this: I'm criticizing IT at the LDS Church, I am NOT criticizing the Church of Jesus Christ of Latter Day Saints. To some extent, I'm not trying to criticize the folks the work in IT at the Church; I realize that were I in charge of IT things would probably be even worse than they're now.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-2406918634050518311?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/2406918634050518311/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/12/why-you-should-be-controversial.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/2406918634050518311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/2406918634050518311'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/12/why-you-should-be-controversial.html' title='Why You Should Be Controversial'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-3039720521663190769</id><published>2008-12-11T20:41:00.009-07:00</published><updated>2008-12-12T09:35:46.501-07:00</updated><title type='text'>The Secret Behind LINQ To SQL</title><content type='html'>I finally get it! It's all about &lt;a href="http://msdn.microsoft.com/en-us/library/bb397951.aspx"&gt;expression trees&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;It all finally clicked for me when I saw the declaration of &lt;span style="font-weight:bold;"&gt;IQueryable&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="csharp"&gt;&lt;br /&gt;public interface IQueryable : IEnumerable&lt;br /&gt;{&lt;br /&gt;  Type ElementType { get; }&lt;br /&gt;  Expression Expression { get; }&lt;br /&gt;  IQueryProvider Provider { get; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;See that? It's right there! How could I have been so blind for so long? But I'm getting ahead of myself. Let me tell you about expression trees.&lt;br /&gt;&lt;br /&gt;What are expression trees? Well, they're a trees with expressions as nodes. What do they do? They provide a mechanism to convert code into data (expressions). Why is that useful? Because you may want to examine and/or modify you code before execution. In particular, it would be very useful, if we wanted to take say C# code and convert it to, oh... i dunno.., SQL statements.&lt;br /&gt;&lt;br /&gt;Say then you created the following Expression:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="csharp"&gt;&lt;br /&gt;Expression&amp;lt;Func&amp;lt;int, int, int&amp;gt;&amp;gt; expression = &lt;br /&gt;     (a,b) =&gt; a + b;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;(There's a little magic going on in the above sample: the compiler knows how to take the lambda "(a, b) =&gt; a + b" and make a delegate out of it).&lt;br /&gt;&lt;br /&gt;The above code would literally translate to a "+" plus node with two children nodes: "a" and "b". Obviously, I've simplified the tree for clarity. If you really want to see the tree structure, fire up VS2008 and take a look at the expression tree with the &lt;a href="http://msdn.microsoft.com/en-us/library/bb397975.aspx"&gt;ExpressionTreeVisualizer&lt;/a&gt; plugin.&lt;br /&gt;&lt;br /&gt;Anyhow, now that we have our C# code in a tree, we can easily parse that tree and convert the data to a string that SQL can understand. We can then take that string, send it across the wire to our SQL server and voila: we have LINQ to SQL. Cool, huh?&lt;br /&gt;&lt;br /&gt;Now, here's something else to think about: IEnumerable offers most of the same methods IQueryable offers, yet the declaration is completely different:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="csharp"&gt;&lt;br /&gt;public interface IEnumerable&amp;lt;T&amp;gt; : IEnumerable&lt;br /&gt;{&lt;br /&gt;   IEnumerator&amp;lt;T&amp;gt; GetEnumerator();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Notice how IEnumerable does not have an Expression tree? That's a &lt;span style="font-weight:bold;"&gt;fundamental&lt;/span&gt; difference between the two interfaces. This means that IEnumerable won't do anything with your code but &lt;span style="font-style:italic;"&gt;execute &lt;/span&gt; it. Therefore, if you order, filter, or project an IEnumerable collection, the action will execute in the process where the collection lives; it will not be sent to a beefy SQL box that can handle ordering large sets easily (Yes, I've made that mistake. In fact, that's what inspired this post).&lt;br /&gt;&lt;br /&gt;Turns out my CS professors were right: trees really &lt;span style="font-style:italic;"&gt;are&lt;/span&gt; useful data structures.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-3039720521663190769?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/3039720521663190769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/12/secret-behind-linq-to-sql.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/3039720521663190769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/3039720521663190769'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/12/secret-behind-linq-to-sql.html' title='The Secret Behind LINQ To SQL'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-2125382130191963483</id><published>2008-12-09T09:48:00.005-07:00</published><updated>2008-12-16T20:31:16.193-07:00</updated><title type='text'>Why Programmers Should Have Private Offices.</title><content type='html'>Non-programmers don't get it: interruptions are a huge deal; it takes a lot of mental effort to load the program you're working on onto your brain.&lt;br /&gt;&lt;br /&gt;Once you're in "the zone", you're effective and you write good code. Naturally then, having some dude from marketing stop by to ask a "quick question" is a total disaster; you have to literally unload a bunch of important information from your brain, just to listen to the marketing clown ask you for the 23rd time when the product will ship. Not cool. Not cool at all.&lt;br /&gt;&lt;br /&gt;What non-programmers don't get is how hard it is to resume what you were working on. They don't understand that, to some extent, you have to load all the classes, variables, functions, etc. in your code right onto your memory; you have to enter the freaking Matrix, ant that's no easy task.&lt;br /&gt;&lt;br /&gt;I'm guessing non-programmers think going back to writing code is as easy as going back to writing an email: you just read the last sentence you wrote and pick up from there. Well, it's not that simple.&lt;br /&gt;&lt;br /&gt;Joel Spolsky has been advocating for private offices for developers well for almost a decade now. Yet there's few companies out there that give their developers such luxury. So, if you ever come across such perk, there's a good chance that's a company you want to work for.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-2125382130191963483?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/2125382130191963483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/12/why-programmers-should-have-private.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/2125382130191963483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/2125382130191963483'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/12/why-programmers-should-have-private.html' title='Why Programmers Should Have Private Offices.'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-4979481986093236992</id><published>2008-12-05T21:40:00.001-07:00</published><updated>2009-01-08T16:08:10.725-07:00</updated><title type='text'>From Recursion To Dynamic Programming</title><content type='html'>Dynamic programming is a really useful technique. When used appropriately, it saves processor time and memory space.&lt;br /&gt;&lt;br /&gt;Shoot! After writing all the code for this entry, I just noticed that the Wikipedia entry for &lt;a href="http://en.wikipedia.org/wiki/Dynamic_programming"&gt;dynamic programming&lt;/a&gt; uses the same example I thought about using in this post. Oh well, let me just show you some code and explain just a little.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="csharp"&gt;&lt;br /&gt;private int recursiveFib(int n)&lt;br /&gt;{&lt;br /&gt;  if (n == 0)&lt;br /&gt;   return 0;&lt;br /&gt;  if (n == 1)&lt;br /&gt;   return 1;&lt;br /&gt;  return recursiveFib(n - 1) + recursiveFib(n - 2);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The above code calculates the Fibonacci number for any integer n. The code is easy to read and effective. However, there's one problem: we repeat calls to recursiveFib even though we may have already computed a value. For example for n=4, we'll call recursiveFib(2) twice; this may not seem like a big problem but for larger Ns the number of unique calls to recursiveFib is very small. &lt;span style="font-weight:bold;"&gt;What a waste of processor cycles!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now that we've realized we're wasting resources because the number of unique calls to our recursive methods is small, we're ready to move on to dynamic programming. Here's the dynamic code:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="csharp"&gt;&lt;br /&gt;private int dynamicFib(int n)&lt;br /&gt;{&lt;br /&gt;  int[] dynamicArray = new int[n];&lt;br /&gt;  dynamicArray[0] = 0;&lt;br /&gt;  dynamicArray[1] = 1;&lt;br /&gt;  for (int i = 2; i &lt; n; i++)&lt;br /&gt;  {&lt;br /&gt;   dynamicArray[i] = dynamicArray[i - 1] + dynamicArray[i - 2];&lt;br /&gt;  }&lt;br /&gt;  return dynamicArray[n];&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Even though this code may not be as succinct as the recursive code, it saves resources. By taking a bottom up approach (rather than the top to bottom approach of the recursive method) and saving our previous calculations, we never have to recompute a value again! Although, with oil being as cheap as it is nowadays, you may not really care.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;In summary:&lt;/span&gt;&lt;br /&gt;If you want to solve a problem with dynamic programming, I recommend you first solve it recursively. This may seem like a waste of time, but you need the recursive solution to spot where the improvement to the algorithm needs to occur. Once you've figured that out, all you have to do is compute and store you partial solutions as you go.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-4979481986093236992?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/4979481986093236992/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/12/from-recursion-to-dynamic-programming.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4979481986093236992'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4979481986093236992'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/12/from-recursion-to-dynamic-programming.html' title='From Recursion To Dynamic Programming'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-3942088863467820490</id><published>2008-11-25T20:28:00.002-07:00</published><updated>2008-11-25T21:55:04.091-07:00</updated><title type='text'>Think About It!</title><content type='html'>&lt;span style="font-style: italic;"&gt;Disclaimer: My apologies to the fine people who, unlike me, actually write source control systems.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;If I asked you to write a source control system, you might say: "Pff. That's easy dude! Just store a copy of the document every time make a change. When you need a particular revision, you just access that copy of the document". And although your system would work, I'd say: Think about it!&lt;br /&gt;&lt;br /&gt;Storing a full copy of the document for every change is wasteful; revision changes are small: a line of text here and a line of text there. Why would you store a full copy of the document just for a small change?&lt;br /&gt;&lt;br /&gt;At this point you may be tempted to say: "Well, then just store the original document, and store the changes as small delta files. We can then apply the deltas to get you any revision you want.". This, of course, is a much better solution as far as storage is concerned; however, I'd still say: Think about it!&lt;br /&gt;&lt;br /&gt;Under normal circumstances, users access the most recent revision of a document far more often than any other revision. Furthermore, storing the original document and applying all of its changes is computationally expensive. It would then seem that having to apply all these deltas for our most common operation is a bad idea. Seeing this, how can we further improve our syste?&lt;br /&gt;&lt;br /&gt;Well, how about we store the most recent version of the document instead of the original? This would mean we would have to store deltas to take us all the way back to the original version, but that's OK - it's not much different than what we were thinking about doing before. However, with this change, we can now perform our most common operation (return the current version of a document) in constant time. Also, the expensive operation (returning an older version of the document) now occurs on rare occasions. Better, huh?&lt;br /&gt;&lt;br /&gt;And now that I'm out of ideas for our source control system, I'm going to go back and "Think about it!", a little bit more, because I'm sure there's still lots of room for improvement.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-3942088863467820490?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/3942088863467820490/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/11/think-about-it.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/3942088863467820490'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/3942088863467820490'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/11/think-about-it.html' title='Think About It!'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-7244641063624711594</id><published>2008-11-20T21:37:00.004-07:00</published><updated>2008-11-20T22:58:06.247-07:00</updated><title type='text'>Spell Checking The Right Way</title><content type='html'>In my &lt;a href="http://www.xckd.com/505/"&gt;fun-as-a-rock&lt;/a&gt; database class I recently got an assignment to correct misspellings in a file full with city names.&lt;br /&gt;&lt;br /&gt;Now, there's two ways to do spell checking: the Microsoft way, and the Google way. Care to guess which is the wrong way to do it? Yup, you got it: the Microsoft way sucks! Ok, maybe it didn't suck back in the 17th century when Spanish Monks were doing all the spell checking known to mankind (which I think consisted of 3 or 4 individuals that actually knew how to read, or cared about spelling for that matter).&lt;br /&gt;&lt;br /&gt;So, if the Microsoft spell checker and the Google spell checker could talk, what would they say?&lt;br /&gt;&lt;br /&gt;Microsoft would say: Listen buster! My dictionary contains all the correct words in the &lt;span style="font-style: italic;"&gt;universe&lt;/span&gt;; either you comply or you don't. Got it?&lt;br /&gt;&lt;br /&gt;Google would say: What do I know about spelling? I'm just trying to figure out a way to make more money from all this content I just indexed. Oh, and by the way, that word you just typed, it look awful close to this other word I see a lot in my index. &lt;a href="http://www.google.com/search?q=look+ma+i+can+spel&amp;amp;ie=utf-8&amp;amp;oe=utf-8&amp;amp;aq=t&amp;amp;rls=org.mozilla:en-US:official&amp;amp;client=firefox-a"&gt;Is that what you meant?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The problem with the Microsoft approach should be obvious, but it's important to point out that the Google approach is not without faults either.&lt;br /&gt;&lt;br /&gt;The biggest problem with the Google approach is that to some extent it's a form of &lt;a href="http://en.wikipedia.org/wiki/Crowdsourcing"&gt;crowdsourcing&lt;/a&gt;. If your crowd can't spell, then you're toast.&lt;br /&gt;&lt;br /&gt;Last, but not least, I'd just like to show you some pseudo code on how I implemented my spell checker:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Read all the city names in the file while keeping track of every variation we've seen and how many times we'v seen it (in a hash, dictionary, etc). Take the most popular spelling for each city, and call that the correct spelling.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;To correct word X, calculate its &lt;a href="http://en.wikipedia.org/wiki/Edit_distance"&gt;edit distance&lt;/a&gt; to all the correct spellings. Chances are word X is really the "correct spelling" it mostly resembles.&lt;/li&gt;&lt;li&gt;Figure out what do if you've never seen X before.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;And that concludes today's post. Now if I could just get Google to write grammatically correct sentences for me, I'd never have to worry about proof reading my posts ever again.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Disclaimer: &lt;/span&gt;I would just like it to be known that I'm in no way a MS hater; in fact, I'm somewhat of a MS fan. I'd also like it to be known that I'm not a Google fan boy; in fact, I'm a little afraid of them - they read my email, and I'm sure they're the new federal agency that's in charge of spying on citizens.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-7244641063624711594?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/7244641063624711594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/11/spell-checking-right-way.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/7244641063624711594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/7244641063624711594'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/11/spell-checking-right-way.html' title='Spell Checking The Right Way'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-3890738869861447698</id><published>2008-11-18T18:08:00.005-07:00</published><updated>2008-11-21T13:40:24.908-07:00</updated><title type='text'>How To Be A Better Programmer</title><content type='html'>Glen Wagley, after reading my post on &lt;a href="http://adotnetdude.blogspot.com/2008/11/benefits-and-costs-of-pair-programming.html"&gt;pair programming&lt;/a&gt; said to me: "I understand what you mean about cutting corners. But I don't do it anymore; it's not worth it".&lt;br /&gt;&lt;br /&gt;That was a slap in the face. Here I am blogging about ways to be a better programmer, yet I still cut corners myself.&lt;br /&gt;&lt;br /&gt;All of this lead me to think that the number one thing you can do to become a better programmer is to have courage and integrity: if you see code that needs to be refactored, refactor it; if you know you need to throw away some of your code, don't be hesitant and throw it away; write your unit tests &lt;span style="font-style: italic;"&gt;first&lt;/span&gt;; write your documentation... you get the idea: do those things you know you &lt;span style="font-style: italic;"&gt;should&lt;/span&gt; do even though you don't you don't always &lt;span style="font-style: italic;"&gt;want&lt;/span&gt; to.&lt;br /&gt;&lt;br /&gt;I guess what' I'm trying to say, if you're Mormon, &lt;a href="http://en.wikipedia.org/wiki/Choose_the_right"&gt;CTR&lt;/a&gt;. If you're not Mormon, please contact your local LDS missionaries; they'll be glad to teach you what CTR means. Seriously, however, it's sad that we have sites like &lt;a href="http://thedailywtf.com/Default.aspx"&gt;The Daily WTF&lt;/a&gt; were we laugh about the crap we, so called "pros", write. I know that the profession is new, but that should be no excuse; I don't see a site where surgeons laugh about all the times they've left scissors inside their patients (OK, I really haven't searched and there's probably one out there). I realize we all make honest mistakes, but we should draw the line somewhere.&lt;br /&gt;&lt;br /&gt;Now that I'm done ranting, and while I'm on the topic, here's a list of other things you could do to become a better programmer (in no particular order): learn other languages &amp;amp; platforms other than the one you currently use; learn to write good prose (in more than one language?); learn to touch type (as Steve Yegge suggests &lt;a href="http://steve-yegge.blogspot.com/2008/09/programmings-dirtiest-little-secret.html"&gt;here&lt;/a&gt;); read tons of technical books and even more non-technical books; learn how to market your ideas; be humble and learn from others (regardless of their title/position); use a text editor effectively...&lt;br /&gt;&lt;br /&gt;I have a ton of these, but I'd rather hear from you now. What do you do to become a better programmer?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update: &lt;/span&gt;Since writing this article, a good buddy of mine wrote a rather inspirational story on standing up for what's right. If you so desire, you can find said story &lt;a href="http://wagdog.net/wordpress/?p=27"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-3890738869861447698?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/3890738869861447698/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/11/how-to-be-better-programmer.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/3890738869861447698'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/3890738869861447698'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/11/how-to-be-better-programmer.html' title='How To Be A Better Programmer'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-27401437555207169</id><published>2008-11-15T16:42:00.001-07:00</published><updated>2008-11-15T16:51:43.654-07:00</updated><title type='text'>Brevity In Code</title><content type='html'>Yes, I'm going to try to convince you to write less code. But, this should be an easy feat; I have Shakespeare also advocating my cause:&lt;blockquote&gt;Brevity is the soul of wit.&lt;/blockquote&gt;&lt;br /&gt;Shakespeare's truism is readily apparent in good code: code that expresses complex concepts in succinct statements is beautiful and worthy of admiration. For several reasons, all other things being equal, smaller code is better code.&lt;br /&gt;&lt;br /&gt;Fewer lines of code mean less bugs and lower maintenance cost. There are, however, other less apparent reasons for which you should try to write as little as possible:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You won't fall pray to the temptation of writing code that's not immediately necessary. In other words, you'll be &lt;a href="http://en.wikipedia.org/wiki/You_Ain't_Gonna_Need_It"&gt;YAGNI&lt;/a&gt; compliant. :)&lt;/li&gt;&lt;li&gt;It is better to  be thought a fool than to write code and remove all doubt. Joking aside, however, the more you write, the more likely you're to make a mistake.&lt;/li&gt;&lt;li&gt;You won't get locked into poor decisions. I was watching Abrams &amp;amp; Cwalina speak at PDC today. One of their comments really struck me: they said, and I'm paraphrasing, that refactoring and correcting design mistakes in frameworks is harder when you have more code than what's absolutely necessary. Specifically, they regretted adding a public constructor to the System.Exception base class. That's it! Just &lt;span style="font-style:italic;"&gt;one&lt;/span&gt; public constructor too many! And although they wish they could change it, they simply can't. If you make a poor decision, you'll have to maintain it.&lt;/li&gt;&lt;li&gt;You're less likely to repeat yourself. Or, to phrase this positively, you'll be &lt;a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;DRY&lt;/a&gt; compliant.&lt;/li&gt;&lt;li&gt;Finally, by writing less code, you'll avoid the temptation to over engineer your solutions.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Learning to be concise in code is hard; it takes effort and patience. You'll have to refactor ruthlessly and mercilessly, but it will be worth the effort. Even though you won't have much code to show off, you'll be proud of it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-27401437555207169?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/27401437555207169/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/11/brevity-in-code.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/27401437555207169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/27401437555207169'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/11/brevity-in-code.html' title='Brevity In Code'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-6058956075401018430</id><published>2008-11-13T17:26:00.002-07:00</published><updated>2008-11-13T17:33:13.085-07:00</updated><title type='text'>Character Encoding Utility</title><content type='html'>Have you ever heard of &lt;a href="http://en.wikipedia.org/wiki/Tracer_ammunition"&gt;tracer ammunition&lt;/a&gt;? Well, this post is kind of a tracer post. In a minute you'll see why.&lt;br /&gt;&lt;br /&gt;I recently wrote a small utility to change the character encoding of very large files. I'm thinking about writing a GUI for my utility and making it freely available. Yup, that's right for free.&lt;br /&gt;&lt;br /&gt;Except, before I go through the trouble of writing the GUI, I'd thought I'd find out if there's any interest in such tool or not. If you're here, reading this, that's enough to tell me you're interested. Now, if you really need it right now, email me and I'll be happy to send you the command line tool.&lt;br /&gt;&lt;br /&gt;And now you know why this is a tracer post. See? I did learn something from &lt;span style="font-style:italic;"&gt;The Pragmatic Programmer&lt;/span&gt;! Or from &lt;span style="font-style:italic;"&gt;The 4 Hour Workweek&lt;/span&gt;. Take your pick; they're both excellent books.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-6058956075401018430?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/6058956075401018430/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/11/character-encoding-utility.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6058956075401018430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6058956075401018430'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/11/character-encoding-utility.html' title='Character Encoding Utility'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-5206950709586087128</id><published>2008-11-06T19:23:00.011-07:00</published><updated>2008-11-12T16:15:34.618-07:00</updated><title type='text'>Benefits (And Costs) of Pair Programming</title><content type='html'>I really enjoy pair programming, and so I thought I'd write about some of the benefits I've seen from pair programming.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;i.&lt;/strong&gt;&lt;br /&gt;Pair programming increases job satisfaction. Believe it or not, I crave the interaction with other geeks; I &lt;span style="font-style:italic;"&gt;need&lt;/span&gt; the mental stimulus that comes from talking with my peers.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;ii.&lt;/strong&gt;&lt;br /&gt;Pair programing increases code quality and decreases bug counts. I take pride in my craft; I like to write good code. Unfortunately, under pressure I cut corners all over the place (telling myself I'll refactor later). However, when I have someone watching over my shoulder, it's a lot harder for me to write hacky code. &lt;br /&gt;&lt;br /&gt;But having someone watch what I'm doing isn't just about the guilt trip. I also appreciate having someone immediately available to discuss ideas and to steer me away from potential problems. This alone literally saves me hours in wasted effort.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;iii.&lt;/strong&gt;&lt;br /&gt;Pair programming makes better programmers. I can't even begin to tell you how much I've learned from sitting next to someone while they code. Now, I must admit, probably 90% of what I've learned has little or nothing to do with programming. But it doesn't matter! Believe it or not, programming is a social activity; to put it simply, good code cannot be developed in isolation.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;iv.&lt;/strong&gt;&lt;br /&gt;Pair programming makes programmers "faster". I honestly feel I'm 3 times more effective when I'm pair programming than when I'm sitting by myself in my cube. This is probably because when I'm stuck, or I have a question, I have someone immediately available to help. Also, there's a bit of added pressure to be faster since every hour at the keyboard is really 2 man hours at the keyboard.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;v.&lt;/strong&gt;&lt;br /&gt;Now, what if I told you that all of these benefits come with a fairly low cost? Well, the good news is that they do: according to &lt;a href="http://collaboration.csc.ncsu.edu/laurie/Papers/XPSardinia.PDF"&gt;this study&lt;/a&gt;, the cost is only about 15% increase in development time. Not bad, huh?&lt;br /&gt;&lt;br /&gt;So, if you're still not pair programming, go talk to your boss and start practicing now. You won't regret it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-5206950709586087128?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/5206950709586087128/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/11/benefits-and-costs-of-pair-programming.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/5206950709586087128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/5206950709586087128'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/11/benefits-and-costs-of-pair-programming.html' title='Benefits (And Costs) of Pair Programming'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-2416130748405108609</id><published>2008-11-04T18:09:00.006-07:00</published><updated>2008-11-07T10:24:24.796-07:00</updated><title type='text'>Easy Background Tasks in ASP.NET</title><content type='html'>&lt;span style="font-style: italic;"&gt;Disclaimer: Admittedly, I got &lt;a href="http://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/"&gt;this idea&lt;/a&gt; from Jeff Atwood, but I think I've improved on it quite a bit.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;At work I have an ASP.NET application that needs to check whether the Department of Treasury has published a new OFAC list (a list of people with whom we can't do business). If there's a new list, we need to parse it, store it, and make sure that none of our customers have popped up on the new list.&lt;br /&gt;&lt;br /&gt;In phase 2, we plan to move this functionality into a windows service, but for now this is how I made this all happen in the background:&lt;br /&gt;&lt;br /&gt;First, we start with the interface for our worker objects:&lt;br /&gt;&lt;pre name="code" class="csharp"&gt;&lt;br /&gt;public interface IAsyncWorker&lt;br /&gt;{&lt;br /&gt;    //the name of the worker object&lt;br /&gt;    string Name { get; }&lt;br /&gt;    //return the next time the object should run&lt;br /&gt;    DateTime AbsoluteExpirationTime { get; }&lt;br /&gt;    //does the actual work the worker needs to do&lt;br /&gt;    void DoWork();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now, all we have to do is simply:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Add an implementation of our IAsyncWorker to the HttpRuntime.Cache.&lt;/li&gt;&lt;li&gt;When the cache item expires, call the worker's DoWork() method.&lt;/li&gt;&lt;li&gt;Add your worker item to the cache again so that it runs again.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;If you follow the above steps you should end up with something like:&lt;br /&gt;&lt;pre name="code" class="csharp"&gt;&lt;br /&gt;private static CacheItemRemovedCallback OnCacheRemoved = null;&lt;br /&gt;&lt;br /&gt;protected void Application_Start(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;    AddAsyncTask(new BlacklistWorker()); //BlacklistWorker implements IAsyncWorker, of course&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private void AddAsyncTask(IAsyncWorker worker)&lt;br /&gt;{&lt;br /&gt;    OnCacheRemove = new CacheItemRemovedCallback(CacheItemRemoved);&lt;br /&gt;    HttpRuntime.Cache.Insert(worker.Name, worker, null,&lt;br /&gt;        worker.AbsoluteExpirationTime, Cache.NoSlidingExpiration,&lt;br /&gt;        CacheItemPriority.NotRemovable, OnCacheRemoved);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void CacheItemRemoved(string workerName, object worker, CacheItemRemovedReason r)&lt;br /&gt;{&lt;br /&gt;    IAsyncWorker asyncWorker = worker as IAsyncWorker;&lt;br /&gt;    if(null != asyncWorker)&lt;br /&gt;    {&lt;br /&gt;         asyncWorker.DoWork();&lt;br /&gt;         AddAsyncTask(asyncWorker);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I like this version better than Jeff's because it removes all conditional statements the CacheItemRemoved() method would have had if we had not created and IAsyncWorker interface.&lt;br /&gt;&lt;br /&gt;This has been working great in our initial tests, but we still plan to move this to an external windows service at some point. &lt;br /&gt;&lt;br /&gt;We're not worried about running out of threads (the thread does come out of the AppPool), since our task only needs to run every 24 hours. However, you might run into issues if you need your code to execute under a different identity than the threads in the AppPool. &lt;br /&gt;&lt;br /&gt;This is a great technique: it gives you the ability to do async tasks with very little overhead.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-2416130748405108609?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/2416130748405108609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/11/easy-background-tasks-in-aspnet.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/2416130748405108609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/2416130748405108609'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/11/easy-background-tasks-in-aspnet.html' title='Easy Background Tasks in ASP.NET'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-6124723229733877726</id><published>2008-11-01T20:54:00.000-07:00</published><updated>2008-11-01T08:46:50.833-07:00</updated><title type='text'>Linq To Sql Debugger Visualizer</title><content type='html'>I usually try not to just post links to someone else's content, but the &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/07/31/linq-to-sql-debug-visualizer.aspx"&gt;LINQ To SQL Debug Visualizer&lt;/a&gt; deserves an exception.&lt;br /&gt;&lt;br /&gt;The LINQ debugger is great; it saves you the trouble of having to use something like &lt;a href="http://www.linqpad.net/"&gt;LINQPad&lt;/a&gt; - another great product I wish I had written, and lets you see what your LINQ query will look like in SQL and what it will return.&lt;br /&gt;&lt;br /&gt;If you're like me,  you'll be shocked you hadn't heard about this VS plugin before.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Note: A big thanks to Alex Greenfield for showing me this tool.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-6124723229733877726?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/6124723229733877726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/10/linq-to-sql-debugger-visualizer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6124723229733877726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6124723229733877726'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/10/linq-to-sql-debugger-visualizer.html' title='Linq To Sql Debugger Visualizer'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-725883549897208758</id><published>2008-10-29T21:41:00.000-07:00</published><updated>2008-12-09T09:42:23.152-07:00</updated><title type='text'>Book Review: An Introduction To Bioinformatics Algorithms</title><content type='html'>&lt;font style="font-style: italic;"&gt;Disclaimer: I'm no where nearly important enough for anyone to pay me to write this review. I have no conflicting interest in writing this review... unless you clicked on my amazon.com link and bought the book I guees.&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;So we're using &lt;font style="font-style: italic;"&gt;An Introduction to Bioinfomratics &lt;/font&gt;(by Jones &amp;amp; Pevzner) in (surprise, surprise!) my bioinformatics class. In 7 years of higher education, this is the first time I can say "this textbook rocks!". Ok, of course it doesn't "rock"; it's a freaking textbook - not Larry Mullen on the "40" solo. Anyhow, it's a good book, and I'd get it if I was you; and I'd also make sure you click on my amazon.com widget there on the right before you purchase it.&lt;br /&gt;&lt;br /&gt;Anyhow, let me tell you two things about this book:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Chapter 3 is a brilliant molecular biology primer. I've taken at least 3 semesters of bio and chem classes, and this book explained all of what I learned in those classes brilliantly and concisely (granted, I never got much out of college). In fact, after reading this book I felt like I finally understood molecular biology and could explain it to my grandma (which is harder than you think seeing how she's been dead for like 5 years now).&lt;/li&gt;&lt;li&gt;One thing that annoys me about algorithm books is that they always have lame sample of how the algorithm could be used. Well, not this book my friend! This book begins every chapter with a &lt;span style="font-style: italic;"&gt;real &lt;/span&gt;molecular biology problem and then applies classic computer science college algorithms to the problems. This is what really makes me learn and understand the algorithms.&lt;/li&gt;&lt;/ol&gt;Honestly, if you're considering buying an algorithms books, this is one worth looking at. It's not comprehensive in the number of algorithms it covers, but the ones it does cover, it covers well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-725883549897208758?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/725883549897208758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/10/book-review-introduction-to_29.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/725883549897208758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/725883549897208758'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/10/book-review-introduction-to_29.html' title='Book Review: An Introduction To Bioinformatics Algorithms'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-4745360641288315635</id><published>2008-10-27T16:14:00.006-07:00</published><updated>2008-10-27T21:44:18.739-07:00</updated><title type='text'>Why partial classes are WRONG! (And why you shouldn't use them.)</title><content type='html'>I'm absolutely positive the fine folks at Microsoft, particularly the brilliant &lt;a href="http://en.wikipedia.org/wiki/Anders_Hejlsberg"&gt;Anders Hejlsberg&lt;/a&gt; (C#'s architect), know of a good reason for partial classes. But I've thought about this for a while, and I'm not convinced there's a good use case for partial classes.&lt;br /&gt;&lt;br /&gt;To be intellectually honest I must admit I can actually think of a few scenarios where partial classes make sense; let me tell just lay those out before we continue:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You should use partial classes when some tool (such as Visual Studio), not a developer, writes something like an ASPX page.&lt;/li&gt;&lt;li&gt;You should &lt;span style="font-style: italic;"&gt;sometimes&lt;/span&gt; use partial classes when you write code that will be auto generated (with CodeSmith or such tools). The sometimes I'm thinking of is DAL code.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;You should use partial classes when... ummm, when you, ummm..&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;I guess that was it; there's only &lt;span style="font-style: italic;"&gt;1.5&lt;/span&gt; good use cases I can think of. I know there must be other reasons whey C# allows for partial classes, so if you know of one, don't hate me for being stupid and leave a comment instead.&lt;br /&gt;&lt;br /&gt;The most prevalent argument for partial classes I've heard of is the one that says &lt;span style="font-weight: bold;"&gt;partial classes are great for organizing code&lt;/span&gt;. To this I respond: &lt;span style="font-weight:bold;"&gt;bull&lt;/span&gt;. Partial classes are not great for organizing code; if your class needs to be spread across multiple files just to manage its complexity, there's something fundamentally wrong with your class. Furthermore, when was the last time that having to look for something in multiples files made it easier to find? Finally, and this is my biggest complaint about partial classes, the compiler will never know if all the files present make the &lt;span style="font-weight:bold;"&gt;entire&lt;/span&gt; definition for your class - I'm sure you can see the problems this could create for you.&lt;br /&gt;&lt;br /&gt;Mike Murray (a friend and ex-coworker at TGN) and I had a discussion about this very topic, based on his post about &lt;a href="http://murrayon.net/2008/10/ever-heard-of-partial-methods.html"&gt;partial methods&lt;/a&gt;. While we were talking about partial classes, he mentioned that at TGN he had seen fulfillment code that used partial classes. The developer that wrote the code thought it would be a good idea to separate the SKU specific code into partial classes. At first this may look like a good idea, but again I respond: bull. There's a much better way to implement SKU specific behavior for fulfillment code; it involves interfaces and polymorphism, two fundamental principles of OOD.&lt;br /&gt;&lt;br /&gt;And the list goes on and on. But for just about every argument in favor of partial classes, there's an OO principle that will do the same job in a much better way.&lt;br /&gt;&lt;br /&gt;So, in summary, let me tell you why you shouldn't use partial classes: partial classes will only help you write &lt;span style="font-weight: bold;"&gt;crappy code&lt;/span&gt;. I don't know about you, but I'm already pretty good at writing crappy code; I need tools and frameworks that do the opposite.&lt;br /&gt;&lt;br /&gt;Just as a footnote: I read an interview where Anders was asked about C#'s support for tooling. He mentioned that yes, he always keeps in mind tool support when designing C#. I'm guessing this is the true reason for partial classes, and why you should steer off them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-4745360641288315635?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/4745360641288315635/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/10/why-partial-classes-are-wrong-and-why.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4745360641288315635'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4745360641288315635'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/10/why-partial-classes-are-wrong-and-why.html' title='Why partial classes are WRONG! (And why you shouldn&apos;t use them.)'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-4854556768714469786</id><published>2008-10-23T19:55:00.006-07:00</published><updated>2008-11-01T08:49:29.449-07:00</updated><title type='text'>The Cost of Throwing &amp; Catching Exceptions</title><content type='html'>Seeing how I &lt;a href="http://adotnetdude.blogspot.com/2008/10/when-to-throw-exceptions.html"&gt;recenlty&lt;/a&gt; wrote about how throwing exceptions is not a bad idea for, uhmm - you know, communication errors (believe it or not this is a topic of discussion), I thought I'd follow up with short follow up on the cost of throwing exceptions.&lt;br /&gt;&lt;br /&gt;Those that argue against throwing exceptions for means of communicating errors, normally cite the "high" cost of catching exception: unwinding the stack looking for a handler, executing finally blocks, and finally returning control to the right place is allegedly a costly operation.&lt;br /&gt;&lt;br /&gt;However, because of the way .NET exception handlers are stored in bytecode and because the code is optimized for the case in which an exception is not thrown (which makes sense considering that we shouldn't see TOO many exceptions):&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;The overall cost of a try...catch block that never handles an exception is a few bytes of memory - or at worst a few words - for the entry in the protected regions table. The only possible runtime penalty is the extra time to load those extra few bytes into memory. Since they are stored way away from the JITted bytecode stream, it's highly unlikely you're going to incur any additional cache-misses at runtime as a result of the handler too. Thus, the cost is essentially nothing.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;However, the cost of &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; handling an exception is quite large:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;The cost of not handling an exception that you should have may well be that your program crashes. This results in unhappy customers, a hit to your reputation and development time to go and do a bug-fix, which will almost certainly be much greater than if you had put it in there in the first place. Obviously, protecting code that can not throw an exception under any circumstances is a waste of your development time. But otherwise, it's best to be safe rather than sorry, safe in the knowledge that even if an exception never does occur in that bit of code, it's not really costing anything anyway.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;(Both quotes from The Official Programmer's Heaven Blog on &lt;a href="http://www.programmersheaven.com/user/pheaven/blog/175-Do-trycatch-blocks-hurt-runtime-performance/"&gt;SEH performance&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;One Important Consideration&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Although the performance cost of structured exception handling is almost always minimal, there is one important consideration that you need to make when writing code inside try blocks: the compiler cannot optimize code inside try blocks.&lt;br /&gt;&lt;br /&gt;Take Peter Ritchie's classical example; the following code&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="csharp"&gt;&lt;br /&gt;  int count = 1;&lt;br /&gt;  SomeMethod();&lt;br /&gt;  count++;&lt;br /&gt;  SomeOtherMethod();&lt;br /&gt;  count++;&lt;br /&gt;  Console.WriteLine(count);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;will get optimized to something that will effctively look like&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="csharp"&gt;&lt;br /&gt;  SomeMethod();&lt;br /&gt;  SomeOtherMethod();&lt;br /&gt;  Console.WriteLine(3);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The same code as in Figure 1, inside a try block, however, will not get optimized. The compiler will actually write code that will increment the "count" variable 2 times.&lt;br /&gt;&lt;br /&gt;So, when writing exception handling code, try to be brief inside your try blocks. Other than that, you don't have too much to worry about.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-4854556768714469786?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/4854556768714469786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/10/cost-of-throwing-catching-exceptions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4854556768714469786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4854556768714469786'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/10/cost-of-throwing-catching-exceptions.html' title='The Cost of Throwing &amp; Catching Exceptions'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-2605500674667855882</id><published>2008-10-21T16:35:00.006-07:00</published><updated>2009-02-03T11:39:57.691-07:00</updated><title type='text'>StackOverflow's Dirty Little Secret</title><content type='html'>Seeing how you probably got here from my link on SO, I won't bore you with the details about what SO is and how awesome it is. For everyone else, however, let me just mention that &lt;a href="http://stackoverflow.com/"&gt;StackOverflow&lt;/a&gt; is a community where developers go to ask and answer questions - that's it, but it's AWESUM!&lt;br /&gt;&lt;br /&gt;Here's a list of ideas on how to maximize your StackOverflow experience. In it, you'll find SO's dirty little secret; take a look:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Do:&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;&lt;br /&gt;Put your foot in your mouth (often). Every time I answer incorrectly at SO the community let's me know it promptly and pointedly. It's kind of embarrassing to be wrong online, so you really learn from your mistakes. Not only does the shock factor help you remember the correct answer but, as an added benefit, you will no longer carry with you the baggage of incorrect knowledge in your head.&lt;br /&gt;&lt;br /&gt;I strongly recommend goofing up (and correcting your self); for a good sample of how I've goofed up, see this &lt;a href="http://stackoverflow.com/questions/203695/structure-vs-class-in-c#203698"&gt;question&lt;/a&gt;. I can guarantee you, I'll never get that one wrong again.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;br /&gt;Ask subjective questions. Even though by definitions subjective quesitons do not have one correct answer, there's still value in asking these kinds of questions. I'd say about 50% of the SO population is smarter than I am (yes, I realize why about 50% of the population is smarter than me), so there's a lot of value in seeing what other developers think.&lt;br /&gt;&lt;br /&gt;If you care to see one of the subjective questions I've asked, take a lookie &lt;a href="http://stackoverflow.com/questions/155217/good-c-code-samples"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Don't:&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;&lt;br /&gt;Think that people know what they're talking about just because they have a high reputation score. And this is SO's dirty little secret: you can get a high reputation (which allegedly represents expertise) by just gaming the system. I'm not saying that the system is broken - there's a lot of people out there that reserve the high rep; there are also many that don't. The other side of this coin is also true: there's a lot of sharp people with low reputation scores (probably because they have better things to do than try to get a high SO rep score). &lt;br /&gt;&lt;br /&gt;So, again, don't judge people just because of their rep score.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;br /&gt;Trust answers just because they have a lot of up-votes. Even though there's a lot of smart people at SO, there's also just a lot of people, and sometimes the herd mentality takes over and answers get up-voted for no other reason than the fact that others have up-voted it.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;If you're a developer and you haven't joined StackOverflow yet, I strongly recommed you to head over there and start asking and answering questions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-2605500674667855882?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/2605500674667855882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/10/stackoverflows-dirty-little-secret.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/2605500674667855882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/2605500674667855882'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/10/stackoverflows-dirty-little-secret.html' title='StackOverflow&apos;s Dirty Little Secret'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-7750864974270944690</id><published>2008-10-16T20:57:00.010-07:00</published><updated>2008-10-20T09:12:59.554-07:00</updated><title type='text'>How To Write Self-Documenting Code</title><content type='html'>If I got promoted every time I spotted code like the one that follows, I'd probably be the President of the United States by now. Take a look at Joe's code here:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public static void main(String[] args) {&lt;br /&gt;        String db = args[0];&lt;br /&gt;        String uid = args[1];&lt;br /&gt;        String pwd = args[2];&lt;br /&gt;        &lt;br /&gt;        String url = "jdbc:postgresql://localhost/" + db;&lt;br /&gt;        Connection conn;&lt;br /&gt;        try&lt;br /&gt;        {&lt;br /&gt;            conn = DriverManager.getConnection(url, uid, pwd);&lt;br /&gt;            String query =  "SELECT A.city, A.zip, st_distance(A.longlat_point_meter, " + "B.longlat_point_meter) FROM utzipcode A, utzipcode B WHERE B.city='MENDON' " + "AND A.city&lt;&gt;'MENDON' AND st_distance(A.longlat_point_meter, B.longlat_point_meter) " + "&lt; 20000 ORDER BY 3;";&lt;br /&gt;            &lt;br /&gt;            Statement stmt = conn.createStatement();&lt;br /&gt;            ResultSet rs = stmt.executeQuery(query);&lt;br /&gt;&lt;br /&gt;            ResultSetMetaData resultMetaData = rs.getMetaData();&lt;br /&gt;            System.out.println(resultMetaData.getColumnName(1) + ", " + resultMetaData.getColumnName(2) + ", " +&lt;br /&gt;                    resultMetaData.getColumnName(3));&lt;br /&gt;            while(rs.next()){&lt;br /&gt;                System.out.println(rs.getString(1) + ", " + rs.getString(2) + ", " + rs.getString(3));&lt;br /&gt;            }&lt;br /&gt;            rs.close();&lt;br /&gt;        }&lt;br /&gt;        catch(SQLException sqle){&lt;br /&gt;            System.out.println(sqle.getMessage());&lt;br /&gt;        }   &lt;br /&gt;    }    &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Can you tell what's going on in the code above? You probably can, with some effort - but why should code so simple be hard to understand? How come the code doesn't tell me what it is doing? Plus, when I'm maintaining this beauty 10 years from now, I'll be hunting Joe down and pulling his fingernails every time I have to debug it - seriously, this code sucks.&lt;br /&gt;&lt;br /&gt;Even though just about every programmer I've worked with knows better than to write code that's hard to read, under pressure we all get sloppy. In fact, I was just looking at some code I just wrote a couple of weeks ago as inspiration for this post.&lt;br /&gt;&lt;br /&gt;So, now that I've gotten that off my chest, let's see if we can clean this up some. The n00b fix would be to pepper in some comments like this:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public static void main(String[] args) {&lt;br /&gt;        String db = args[0];&lt;br /&gt;        String uid = args[1];&lt;br /&gt;        String pwd = args[2];&lt;br /&gt;        &lt;br /&gt;        String url = "jdbc:postgresql://localhost/" + db;&lt;br /&gt;        Connection conn;&lt;br /&gt;        try&lt;br /&gt;        {&lt;br /&gt;            //get the connection to the db&lt;br /&gt;            conn = DriverManager.getConnection(url, uid, pwd);&lt;br /&gt;            String query =  "SELECT A.city, A.zip, st_distance(A.longlat_point_meter, " + "B.longlat_point_meter) FROM utzipcode A, utzipcode B WHERE B.city='MENDON' " + "AND A.city&lt;&gt;'MENDON' AND st_distance(A.longlat_point_meter, B.longlat_point_meter) " + "&lt; 20000 ORDER BY 3;";&lt;br /&gt;            &lt;br /&gt;            Statement stmt = conn.createStatement();&lt;br /&gt;            //execute the query defined above&lt;br /&gt;            ResultSet rs = stmt.executeQuery(query);&lt;br /&gt;&lt;br /&gt;            ResultSetMetaData resultMetaData = rs.getMetaData();&lt;br /&gt;            &lt;br /&gt;            //print column names&lt;br /&gt;            System.out.println(resultMetaData.getColumnName(1) + ", " + resultMetaData.getColumnName(2) + ", " +&lt;br /&gt;                    resultMetaData.getColumnName(3));&lt;br /&gt;            &lt;br /&gt;            //print every tuple&lt;br /&gt;            while(rs.next()){&lt;br /&gt;                System.out.println(rs.getString(1) + ", " + rs.getString(2) + ", " + rs.getString(3));&lt;br /&gt;            }&lt;br /&gt;            rs.close();&lt;br /&gt;        }&lt;br /&gt;        catch(SQLException sqle){&lt;br /&gt;            System.out.println(sqle.getMessage());&lt;br /&gt;        }   &lt;br /&gt;    }    &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That still looks terrible, however. Not only that, the comments aren't really that useful; they don't tell me anything I couldn't have figured out by reading the code. In fact, I think these types of comments make the code &lt;span style="font-style:italic;"&gt;harder&lt;/span&gt; to read since they interrupt what's really important - the code. But that's kind of a side note: the real problem here is that comment's don't give me any insight or explain the &lt;span style="font-style:italic;"&gt;intent&lt;/span&gt; of the code.&lt;br /&gt;&lt;br /&gt;Alright then... What do we do now? Well, how about something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public static void main(String[] args) {&lt;br /&gt;        String db = args[0];&lt;br /&gt;        String uid = args[1];&lt;br /&gt;        String pwd = args[2];&lt;br /&gt;        &lt;br /&gt;        String url = "jdbc:postgresql://localhost/" + db;&lt;br /&gt;        Connection conn;&lt;br /&gt;        try&lt;br /&gt;        {&lt;br /&gt;            conn = DriverManager.getConnection(url, uid, pwd);&lt;br /&gt;            &lt;br /&gt;            //we're hard coding the query here because the db is out of SPs - joe&lt;br /&gt;            String query =  "SELECT A.city, A.zip, st_distance(A.longlat_point_meter, " + &lt;br /&gt;                            "B.longlat_point_meter) FROM utzipcode A, utzipcode B WHERE B.city='MENDON' " + &lt;br /&gt;                            "AND A.city&lt;&gt;'MENDON' AND st_distance(A.longlat_point_meter, B.longlat_point_meter) " + &lt;br /&gt;                            "&lt; 20000 ORDER BY 3;";&lt;br /&gt;            &lt;br /&gt;            ResultSet rs = ExecuteQuery(query, conn);&lt;br /&gt;            PrintQueryResults(rs);&lt;br /&gt;            rs.close();&lt;br /&gt;        }&lt;br /&gt;        catch(SQLException sqle){&lt;br /&gt;            System.out.println(sqle.getMessage());&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    private static ResultSet ExecuteQuery(String query, Connection conn) {&lt;br /&gt;        try{&lt;br /&gt;            Statement stmt = conn.createStatement();&lt;br /&gt;            return stmt.executeQuery(query);&lt;br /&gt;        }&lt;br /&gt;        catch(SQLException sqle){&lt;br /&gt;            return null;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    private static void PrintQueryResults(ResultSet rs){&lt;br /&gt;        try{&lt;br /&gt;            ResultSetMetaData resultMetaData = rs.getMetaData();&lt;br /&gt;            System.out.println(resultMetaData.getColumnName(1) + ", " + resultMetaData.getColumnName(2) + ", " +&lt;br /&gt;                    resultMetaData.getColumnName(3));&lt;br /&gt;            while(rs.next()){&lt;br /&gt;                System.out.println(rs.getString(1) + ", " + rs.getString(2) + ", " + rs.getString(3));&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        catch(SQLException sqle){ }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ahhh... much better. I can tell what the code is doing in one brief overview - and most importantly, the code itself is telling me what it's doing! &lt;br /&gt;&lt;br /&gt;Also, the code is now easier to debug and maintain because each method is only a few lines long; this means I'll know exactly where the code may be having problems next time it breaks by just looking at the stack trace. Finally, look at that comment about the query - that really tells me something I could have never known unless Joe had told me.&lt;br /&gt;&lt;br /&gt;So there you go, that's self documenting code in 3 easy steps. Please let Joe know how much you appreciate learning from his mistake by dropping a comment. It'll make him feel better.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-7750864974270944690?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/7750864974270944690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/10/how-to-write-self-documenting-code.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/7750864974270944690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/7750864974270944690'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/10/how-to-write-self-documenting-code.html' title='How To Write Self-Documenting Code'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-2991360595487422279</id><published>2008-10-11T11:53:00.006-07:00</published><updated>2008-11-01T08:48:55.340-07:00</updated><title type='text'>when to throw exceptions</title><content type='html'>have you ever heard the saying "exceptions are for exceptional circumstances"? well, i have, and until recently, i was a firm believer of such thoughts. i'd normally code for every "exceptional" condition and try to do everything i could to avoid having to throw an exception.&lt;br /&gt;&lt;br /&gt;however, just a few days ago, i came across this statement from Krzysztof Cwalina (program manager for the CLR team at MS):&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;One of the biggest misconceptions about exceptions is that they are for “exceptional conditions.” The reality is that they are for communicating error conditions. From a framework design perspective, there is no such thing as an “exceptional condition”. Whether a condition is exceptional or not depends on the context of usage, --- but reusable libraries rarely know how they will be used. For example, OutOfMemoryException might be exceptional for a simple data entry application; it’s not so exceptional for applications doing their own memory management (e.g. SQL server). In other words, one man’s exceptional condition is another man’s chronic condition.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Cwalina then goes on to say that exceptions should be used for common errors such as (1) usage errors, (2) program errors, and finally (3) system errors. it seems to me this in direct opposition of the "exceptional exceptions" mantra.&lt;br /&gt;&lt;br /&gt;to be honest, i never understood why exceptions should only be used in "exceptional" circumstances. it's hard to define "exceptional", and that's exactly the point Cwalina makes in his quote.&lt;br /&gt;&lt;br /&gt;i realize, however, there's circumstances when it doesn't make sense to throw exceptions; for example, why throw a DivideByZeroException when you can easily check for the condition an appropriately terminate?&lt;br /&gt;&lt;br /&gt;but for the most part, exceptions provide an objected oriented way to communicate errors to clients. i think i'm switching from the "exceptional exceptions" camp to the "let's use exceptions to communicate errors" camp. what about you?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Update: I have a new article on the cost of throwing exceptions. If you now think that throwing more exceptions is a good idea, you might want to check &lt;a href="http://adotnetdude.blogspot.com/2008/10/cost-of-throwing-catching-exceptions.html"&gt;this&lt;/a&gt; article too.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-2991360595487422279?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/2991360595487422279/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/10/when-to-throw-exceptions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/2991360595487422279'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/2991360595487422279'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/10/when-to-throw-exceptions.html' title='when to throw exceptions'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-8415631475399559508</id><published>2008-09-07T12:54:00.003-07:00</published><updated>2008-09-07T12:59:49.232-07:00</updated><title type='text'>everything is an object</title><content type='html'>over at &lt;a href="http://www.stackoverflow.com/"&gt;stackoverflow&lt;/a&gt; someone asked "how do i thinki in OO?"&lt;br /&gt;&lt;br /&gt;saint_groceon answered:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Some conceptual advice:&lt;br /&gt;&lt;br /&gt;"has a": A dog has a tail; therefore the Dog class should have a member "tail"&lt;br /&gt;&lt;br /&gt;"is a": A poodle is a dog; therefore Poodle should either be an instance or derived class of Dog&lt;br /&gt;&lt;br /&gt;Thinking this way really sped up my ability to design object oriented structures. Otherwise, starting out it's easy to get twisted up and start adding members to classes that should actually just be instances, or vice versa.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;to which i responded:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;  &lt;br /&gt;saint_groceon's beginner advice although correct, can lead to trouble:&lt;br /&gt;&lt;br /&gt;Objects are not just a collection of attributes and behaviors. If that was the case, dogs and cats would be indistinguishable from each other, as they both have eyes, mouths and legs, and they both eat, sleep and play. In fact, this kind of "object" is almost no different than a C struct.&lt;br /&gt;&lt;br /&gt;Furthermore, the type of thinking described in saint_groceon's post also leads to other problems: If your "Duck" class has a "quack" method, what happens when you need to implement a rubber duck that does not quack? (you may recognize this example from Head First Design Patterns)&lt;br /&gt;&lt;br /&gt;I agree with the fact that objects are usually nouns from the domain's language. However an object is more than that: an object is anything capable of providing a limited set of useful services. And then, with these objects "we decompose the complex world around, and assemble those objects in various ways so that they can perform useful tasks on our behalf" (David West).&lt;br /&gt;&lt;br /&gt;West nails the definition of an objcet; the most important characteristic of an object is it's ability to be composed with other objects to create useful things, much like all of our body parts (properly assembled) make us useful creatures. So, in some respect, everything is an object!&lt;br /&gt;&lt;br /&gt;Edit: I realize that I said little about How To Think OO, and a lot more about what OO is not. I apologize for this, but I'm no OO master, and I'm barely at the stage where I have a feeling what OO IS NOT... I'm not at the point where I can instruct on OO.&lt;br /&gt;&lt;br /&gt;This post was mostly an exercise to help me gather my thoughts about what I've learned so far. I hope you'll find it useful nonetheless.&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-8415631475399559508?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/8415631475399559508/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/09/everything-is-object.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/8415631475399559508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/8415631475399559508'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/09/everything-is-object.html' title='everything is an object'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-8365473848706153470</id><published>2008-08-29T18:33:00.003-07:00</published><updated>2008-08-29T18:55:28.364-07:00</updated><title type='text'>delegation in a load balanced enivornment</title><content type='html'>last week i tried to get impersonation and delegation working for a couple of wcf services and a website. unfortunately, getting this to work took me a lot longer than it should have, so i thought i'd share some of the things i learned.&lt;br /&gt;&lt;br /&gt;in iis 6.0 and earlier, you can only get delegation to work in a load balanced environment, if you do the following:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;make your app run under a domain account&lt;/li&gt;&lt;li&gt;set the proper SPNs (service principal name) on the account:&lt;br /&gt;&lt;pre name="code"&gt;HTTP/appserver domainName\accountName&lt;br /&gt;HTTP/appserver.fullyqualified.name domainName\accountName&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;trust the account (and the machine) for delegation in AD&lt;/li&gt;&lt;li&gt;run aspnet_regiis with the -ga flag and the domain qualified user name&lt;/li&gt;&lt;li&gt;finally add your domain account to IIS_WPG&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;i'm sure most systme engineers know this already, but as a developer, it's the first time i've come across this.&lt;br /&gt;&lt;br /&gt;it's also worth mentioning that under iis 7.0 you do not need to do any of this: you can run your apps under NetworkService, and still have them load balanced.&lt;br /&gt;&lt;br /&gt;what's funny is that after we finally figured out how to get delegation to work for our load balanced applications, we decided that it was way too much setup and we would move to iis 7.0.&lt;br /&gt;in a way, a lot of the time i put into this was wasted, but i learned a ton about security and delegation/impersonation while doing the research to get this to work. i hope it'll save you some time. if it does, or if you have any other questions, please let me know.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-8365473848706153470?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/8365473848706153470/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/08/delegation-in-load-balanced-enivornment.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/8365473848706153470'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/8365473848706153470'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/08/delegation-in-load-balanced-enivornment.html' title='delegation in a load balanced enivornment'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-6017323231583099793</id><published>2008-07-17T19:29:00.000-07:00</published><updated>2008-07-17T20:02:49.185-07:00</updated><title type='text'>the stateless web: it will always bite you!</title><content type='html'>i spent good part of the day building a little control to upload documents for our crm tool today. because i wanted to give the customer the ability to decide how many files she wants to upload at runtime, i put a little "add another file button" on the control, which would dynamically let the user add another file.&lt;br /&gt;&lt;br /&gt;as soon as i had this dynamic functionality built, i threw it on the control where it was supposed to go (yes, my control was nested inside another control, which was then placed on the page where the upload functionality was needed). unbeknown to me, the person who had written this page was also dynamically loading his control; unfortunately, he was only loading the control on the pageload, and not on the postback.&lt;br /&gt;&lt;br /&gt;for about an hour i kept trying to figure out why the button onmy control wasn't firing its events. finally, in frustration, i decided to step through all of the code: as soon as I saw the pageload i realized what was going on: my control wasn't firing events on the postback because it wasn't even there when the page submitted!&lt;br /&gt;&lt;br /&gt;most developers know that web-apps are stateless, but i think we fail to internalize what this really means. we assume that once we declare a variable, it will remain there as long as it's in scope. i'm not trying to blame my co-worker; in fact, i've made this same mistake several times (which is probably why i recognized it almost immediately). i think the problem is we first learn to program in statefull environments, and then make the switch to the web without fully understanding the implication of moving to this new environment.&lt;br /&gt;&lt;br /&gt;anyhow, i'm somewhat upset over the fact that i didn't get to finish the control today. i'm planning on getting up early tomorrow, coming in before anyone can bug me and getting the control done - that is until i run into the next nuisance from the stateless web, i guess.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-6017323231583099793?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/6017323231583099793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/07/stateless-web-it-will-always-bite-you.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6017323231583099793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6017323231583099793'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/07/stateless-web-it-will-always-bite-you.html' title='the stateless web: it will always bite you!'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-6088464983683651827</id><published>2008-07-13T20:04:00.003-07:00</published><updated>2008-07-13T20:31:54.953-07:00</updated><title type='text'>google analytics statistics</title><content type='html'>i was just reviewing some stats from google analytics, and just want to summarize some things i found interesting.&lt;br /&gt;&lt;br /&gt;i'm getting about 30 unique visitors every month; i have to admit, however, that i'm probably 3 of those. most of my traffic is organic and comes through google search (surprise, surprise!).&lt;br /&gt;&lt;br /&gt;my most visited blog entry, is the one i had on particle swarm optimization in c#. my guess is that a whole bunch of lazy college students are looking for code so that they won't have to think in order to do their assignment. the traffic that this post gets is so much grater than anything else i've written, that i'm thinking about catering to lazy C.S college students ;)&lt;br /&gt;&lt;br /&gt;the other blog entries that get quite a bit of traffic, are the ones on biztalk tips; i can see why this is since there aren't actually that many people that blog about biztalk.&lt;br /&gt;&lt;br /&gt;from looking at the reports, however, i'm starting to learn the importance of writing so that you'll come up in search queries. i have an entry, for example, titled "do i really need an orchestration?"; a much better title would have been "when to use an orhestration", or something like that.&lt;br /&gt;&lt;br /&gt;i'm excited about the little traffic i'm getting: there's some dude in sweeden that spent 15+ minutes on my site - i didn't even know that i had 15+ minutes worth of material on my blog! even though it's hard to find time to blog, i'll increase my efforts to do so. like jeff atwood, i've found that it truly is almost as much fun to blog about coding as actually writing code is.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-6088464983683651827?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/6088464983683651827/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/07/google-analytics-statistics.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6088464983683651827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6088464983683651827'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/07/google-analytics-statistics.html' title='google analytics statistics'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-2682009155925873487</id><published>2008-06-02T20:05:00.004-07:00</published><updated>2008-07-13T20:34:26.187-07:00</updated><title type='text'>usu's ezportal security assessment</title><content type='html'>about 3 weeks ago i finished a security assessment for a new application the university of utah is planning on rolling out so that students, teachers, and staff to can manage all of their usu data.&lt;br /&gt;&lt;br /&gt;our analysis included looking at the overall application architecture, looking at the coding, and a test to try to exploit vulnerabilities.&lt;br /&gt;&lt;br /&gt;i thought it was interesting that every major hole in the application, came from the developers trusting the libraries and subcomponents they were using. for example, the developers were using an open source rich text editor (so that users could upload nice looking content without having to know html), that could easily be exploited to upload malicious code, or render content from any other site (yes, as in a xss attack).&lt;br /&gt;&lt;br /&gt;so, the mantra of &lt;a href="http://www.codinghorror.com/blog/archives/000497.html"&gt;"find the dependencies -- and eliminate them"&lt;/a&gt;, turns out to be true for security problems too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-2682009155925873487?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/2682009155925873487/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/06/usus-ezportal-security-assessment.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/2682009155925873487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/2682009155925873487'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/06/usus-ezportal-security-assessment.html' title='usu&apos;s ezportal security assessment'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-4486182118016675057</id><published>2008-05-06T22:21:00.005-07:00</published><updated>2008-06-02T20:05:12.353-07:00</updated><title type='text'>particle swarm optimization (pso) in c#</title><content type='html'>i was going to give a presentation at "code camp" on particle swarm optimization (pso), but unfortunately was not able to do so because of circumstances beyond my control.&lt;br /&gt;&lt;br /&gt;so, i've decided to post my c# implementation &lt;a href="http://blogger.syscoders.net/downloads/ParticleSwarmOptimization.zip"&gt;here&lt;/a&gt; so you can take look at it and play with it. the code graphs the movement of the particle swarm, so it's cool to see how the different pso parameters affect the movement of the swarm.&lt;br /&gt;&lt;br /&gt;the swarm is not divided into neighborhoods and each member only knows about their local best and the swarm's best value to date. if you want to change the code so that i does neighborhoods, be my guest.&lt;br /&gt;&lt;br /&gt;the code is really rough, especially in the way the UI runs. also, there's no way to dynamically change anything; if you want to make any sort of change you have to find the pertinent code, recompile it and rerun it (ie. there are no config files, no input paramenters, nothing).&lt;br /&gt;&lt;br /&gt;so, if you think my code sucks, please let me know!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-4486182118016675057?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/4486182118016675057/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/05/particle-swarm-optimization-pso-in-c.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4486182118016675057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4486182118016675057'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/05/particle-swarm-optimization-pso-in-c.html' title='particle swarm optimization (pso) in c#'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-3147151518326177859</id><published>2008-04-09T12:01:00.003-07:00</published><updated>2008-07-13T20:35:08.238-07:00</updated><title type='text'>biztalk database problems</title><content type='html'>when we started implementing biztalk at tgn there was hardly any documentation on it, and so we had to resolve all of our problems through trial and error, or through help from blogs.&lt;br /&gt;&lt;br /&gt;we had two database problems early on that made us wish someone would have warned us about potential problems:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;by default, the biztalk messagebox is set to autogrow by 1mb. this is a problem, because if you have to autogrow your db, it's likely that you'll need to grow it by more than 1mb and so the 1mb is consumed promplty and the db has to autogrow once again. we had problems with this twice: the first time we just saw the cpu usage spike every time we autogrew; the second time the effects were worst as we we were running out of space on the disk and the server became stuck autogrowing and rolling back once it realized there wasn't enough space. so, if you're gonna autogrow your BizTalkMessageBoxDb database, autogrow it in big enough chunks to avoid performance problmes.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;the PurgeSubscriptionJob_BizTalkMsgBoxDb and TrackedMessages_Copy_BizTalkMsgBoxDB jobs need to run every minute to keep biztalk running in good shape, but unfortunately they are not setup to run by default. we only found out about this when our applications started running absurdly slow and all of our clients complained about time outs.&lt;/li&gt;&lt;/ol&gt;perhaps if we had had a dedicated dba, and admin for our system, we would have noticed these problems before they caused issues. hopefully, you won't have to suffer through these yourself.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-3147151518326177859?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/3147151518326177859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/04/biztalk-database-gotchas.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/3147151518326177859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/3147151518326177859'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/04/biztalk-database-gotchas.html' title='biztalk database problems'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-6664701262576566293</id><published>2008-04-04T21:53:00.010-07:00</published><updated>2009-01-29T22:07:41.935-07:00</updated><title type='text'>refactoring code with too many conditional statements</title><content type='html'>i was once talking with the IS director of a certain company about the tell tale signs of bad code. i mentioned a few of the items that raise flags for me: code duplication, low cohesion in classes, etc.&lt;br /&gt;&lt;br /&gt;the director, which happens to be a really good coder even though he's been in management for several years, mentioned that when he sees code with too many if statements (or any conditional branching for that matter), he knows the code could be cleaned up. after hearing his statement, i started considering on how to clean code that has too many if statements.&lt;br /&gt;&lt;br /&gt;last week i had the opportunity to help a coworker refactor some code that looked something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="csharp"&gt;&lt;br /&gt;public class CreditCardService()&lt;br /&gt;{&lt;br /&gt;  public void DoWork()&lt;br /&gt;  {&lt;br /&gt;       if(creditCardCode = "VISA")&lt;br /&gt;       {&lt;br /&gt;            //about 10 or so lines of code here&lt;br /&gt;       }&lt;br /&gt;       else if (creditCardCode = "MC")&lt;br /&gt;       {&lt;br /&gt;            //about 10 or so lines of code here&lt;br /&gt;            //the code is very similar in all branches&lt;br /&gt;       }&lt;br /&gt;       //a few more branches for the other credit cards we support&lt;br /&gt;       //...&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;the obvious problem with the code above is that it's not making good use of a basic programming principle: polymorphism.&lt;br /&gt;&lt;br /&gt;we could clean up the above code by:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;writing a base class that implements the common functionality across all credit cards&lt;/li&gt;&lt;li&gt;writing children credit card classes that inherit from the base class and implement what's different in each credit card&lt;/li&gt;&lt;li&gt;writing a credit card factory that return the right implementation to the CreditCardService class&lt;/li&gt;&lt;/ul&gt;so, we should end up with code looking something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="csharp"&gt;&lt;br /&gt;public class BaseCreditCard&lt;br /&gt;{&lt;br /&gt;     //all common fields go here&lt;br /&gt;&lt;br /&gt;     public void DoWork()&lt;br /&gt;     {&lt;br /&gt;          //all common functionality goes here&lt;br /&gt;     }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class VisaCreditCard : BaseCreditCard&lt;br /&gt;{&lt;br /&gt;     //all fields pertaining to VISA go here&lt;br /&gt;     &lt;br /&gt;    public void DoWork()&lt;br /&gt;    {&lt;br /&gt;         base.DoWork();&lt;br /&gt;         //visa specific functionality goes here&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class CrediCardFactory()&lt;br /&gt;{&lt;br /&gt;     public static BaseCreditCard GetCard(string cardType)&lt;br /&gt;     {&lt;br /&gt;          //return appropriate credit card child class&lt;br /&gt;          if(cardType.Equals("VISA")&lt;br /&gt;               return new VisaCreditCard();&lt;br /&gt;          //more code like the one above&lt;br /&gt;     }&lt;br /&gt;}&lt;br /&gt;public class CreditCardService()&lt;br /&gt;{&lt;br /&gt;     private CreditCard card;&lt;br /&gt;     public CreditCardService(string cardType)&lt;br /&gt;     {&lt;br /&gt;          card = CreditCardFactory.GetCard(cardType)&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     public void DoWork()&lt;br /&gt;     {&lt;br /&gt;          card.DoWork();&lt;br /&gt;     }    &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ideally, our factory will be really smart about picking the right credit card type, so that all of the if statements necessary to pick the right credit card will all be contained in it.&lt;br /&gt;&lt;br /&gt;using polymorphism in this case makes the code much easier to read, and way easier to maintain as we now have all decision logic in one place, all common logic in another place, and type specific logic in its own place.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-6664701262576566293?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/6664701262576566293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/03/refactoring-code-with-too-many.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6664701262576566293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6664701262576566293'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/03/refactoring-code-with-too-many.html' title='refactoring code with too many conditional statements'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-4831132512031570938</id><published>2008-03-28T22:10:00.028-07:00</published><updated>2008-05-06T23:04:11.102-07:00</updated><title type='text'>simple dependency injection</title><content type='html'>the idea behind dependency injection has been around for a while, and i believe the term "poor man's dependency injection" is popular as well, but i thought i'd share the poor man's method anyhow.&lt;br /&gt;&lt;br /&gt;it's common to find that n-tiered applications (especially applications with a persistence layer and a "business logic layer") although layered, are usually tightly coupled.&lt;br /&gt;&lt;br /&gt;one nuisance that this coupling creates is the inability to write unit tests that only test the business layer. even though you can write tests for the business layer, these cannot run without calling the persistence layer, and thus you end up with slow tests (because of db calls) and redundant tests (assuming you have tests for your persistence layer).&lt;br /&gt;&lt;br /&gt;a very simple method (the poor man's method, of course) to solve this coupling problem is to:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;code to an interface (in the case of the service layer, make sure you're not calling a specific implementation of your persistence layer, but an interface).&lt;/li&gt;&lt;li&gt;overload the constructor(s) for your business logic class so that they also take a specific implementation of the interfaces it depends on.&lt;/li&gt;&lt;/ol&gt;if you do what i've described above, your business layer should end up looking something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="csharp"&gt;&lt;br /&gt;&lt;br /&gt;public interface IPersistenceLayer&lt;br /&gt;{&lt;br /&gt;    void DoWork();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class BusinessLogicLayer&lt;br /&gt;{&lt;br /&gt;    IPersitenceLayer myDataStore;&lt;br /&gt;    public BusinessLogicLayer(IPersistenceLayer someImplementation)&lt;br /&gt;    {&lt;br /&gt;         myDataStore = someImplementation;&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;    public void DoWork()&lt;br /&gt;    {&lt;br /&gt;         //business logic here&lt;br /&gt;         myDataStore.DoWork();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;with the above code you can easily write tests for your business layer that just take a dummy IPersistenceLayer and return mock objects. and so now we have fast tests that don't require any database setup and/or maintenance.&lt;br /&gt;&lt;br /&gt;there is however, one obvious problem with the code presented: why should the clients to the business layer have to know about the layer's dependency? the answer is they shouldn't and that's why we keep all the default constructors, and just have those set the IPersistenceLayer reference to the commonly use implementation of the interface.&lt;br /&gt;&lt;br /&gt;although almost trivial, this method of dependency injection is appropriate for simple scenarios and provides much flexibility.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-4831132512031570938?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/4831132512031570938/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/03/simple-dependency-injection.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4831132512031570938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4831132512031570938'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/03/simple-dependency-injection.html' title='simple dependency injection'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-8548279324897555698</id><published>2008-01-24T19:55:00.000-07:00</published><updated>2008-01-24T20:05:22.394-07:00</updated><title type='text'>linq and lambda expressions</title><content type='html'>i'm aware that i'm about a year (or more, probably) behind on this, but the new c# lambda and linq features are awesome!&lt;br /&gt;&lt;br /&gt;i wrote my first dlinq query today, and i'm now of the opinion that linq will literally change the way we code. i'm aware that i don't recognize all of the repercussions that come from linq, but just the very basic queries i did today, literally changed some more of the fundamental programming paradigms i held.&lt;br /&gt;&lt;br /&gt;as for lambda expressions, i must say that even though the concept is not new (in fact, anonymous delegates and types are almost as old as programming), there's something to be said for how elegant lambda expression are: what would be ugly (or sometimes even impossible constructs) in c# are extremely simple and easy to read statements thanks to lambda expressions.&lt;br /&gt;&lt;br /&gt;i'll keep posting on linq and lambda expressions as i learn more. but if you haven't had a chance to learn about them, i strongly recommend you to.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-8548279324897555698?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/8548279324897555698/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2008/01/linq-and-lambda-expressions.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/8548279324897555698'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/8548279324897555698'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2008/01/linq-and-lambda-expressions.html' title='linq and lambda expressions'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-4567072708490210482</id><published>2007-12-11T20:11:00.000-07:00</published><updated>2008-01-24T20:09:18.186-07:00</updated><title type='text'>a4host.net</title><content type='html'>i'm excited to announce that syscoders lc (the consulting company i started) has finally started a web hosting branch. please take a minute to visit our website at &lt;a href="http://www.a4host.net"&gt;a4host.net&lt;/a&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-4567072708490210482?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/4567072708490210482/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2007/12/a4hostnet.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4567072708490210482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4567072708490210482'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2007/12/a4hostnet.html' title='a4host.net'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-4453314722702344372</id><published>2007-12-06T20:09:00.000-07:00</published><updated>2008-12-16T20:29:55.293-07:00</updated><title type='text'>some problems with biztalk's ftp adapter</title><content type='html'>there are two issues you need to be aware of when using the ftp as a receive location:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;ftp does not have a way to lock files while you're reading them; under some conditions, you could have more than one machine pick up the file and you could end up with duplicate messages. obviously then, you cannot have the host running the ftp adapter live on more than one machine. the receive function of the ftp adapter MUST run under a singleton host.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;the biztalk adapter closes the ftp connection after 3 minutes of inactivity. this means that you must process your files promptly. if you're processing a large file, and it takes more than 3 minutes for your process to commit the message(s) to the message box, you will not be able to delete the file from the ftp receive location once your process finishes. this means that next time your receive location runs again, you'll pick up the same file!&lt;/li&gt;&lt;/ol&gt;we've encountered both of these issues recently, and both are easy to solve:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;like i've already mention, have your ftp receive location run under a singleton host.&lt;/li&gt;&lt;li&gt;just bring the file down (without processing it) through ftp, and put it on some file folder. have the process that would normally work on the file pick the file up from this new location.&lt;/li&gt;&lt;/ol&gt;the "guaranteed delivery" nature is a really nice feature, but you have to be aware of the problems it can create. hopefully this will help you in your development; i know i was scratching my head for a while trying to figure out why the ftp adapter wouldn't delete the files it had processed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-4453314722702344372?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/4453314722702344372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2007/12/some-problems-with-biztalks-ftp-adapter.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4453314722702344372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/4453314722702344372'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2007/12/some-problems-with-biztalks-ftp-adapter.html' title='some problems with biztalk&apos;s ftp adapter'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-8007299500920126834</id><published>2007-11-16T15:19:00.000-07:00</published><updated>2007-11-16T15:37:19.215-07:00</updated><title type='text'>on throwing errors</title><content type='html'>not too long ago i spent quite a few days trying to solve what was a really easy bug.&lt;br /&gt;&lt;br /&gt;after moving a class from one assembly to another, one of my biztalk orchestrations started throwing a runtime error saying that it couldn't serialize an instance of a XmlDocument.&lt;br /&gt;&lt;br /&gt;because the runtime error did not return a stack trace, i was very confused: even though XmlDocument truly is not serialiazable, biztalk is able to dehydrate the contents of a XmlDocument instance by getting the XmlDocument's outerxml and storing it; upon rehydration, the XmlDocument is loaded with the saved string.&lt;br /&gt;&lt;br /&gt;after a few days of thinking about this problem, I realized that the error was not coming from the orchestration's instance of XmlDocument, but instead from a class that held and instance of XmlDocument and which the orchestration was using.&lt;br /&gt;&lt;br /&gt;i simply marked the XmlDocument variable declaration with [NonSerializable] and all the problems went away.&lt;br /&gt;&lt;br /&gt;i mention all of this because if had just gotten the stack trace, all the hassle I went through could have been avoided.&lt;br /&gt;&lt;br /&gt;i've noticed that the errors i throw are usually not very descriptive,  because i understand the code and i know what's going on. however, i've also noticed that when co-workers get exception from my code, it's not clear to them what the error means.&lt;br /&gt;&lt;br /&gt;thus the importance of throwing very specific and very clear error messages; even if they're a little verbose. and outsider needs to understand the context of what's going on in order to be able to understand and solve problems.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-8007299500920126834?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/8007299500920126834/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2007/11/on-throwing-errors.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/8007299500920126834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/8007299500920126834'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2007/11/on-throwing-errors.html' title='on throwing errors'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-7559008604960842615</id><published>2007-09-21T15:08:00.003-07:00</published><updated>2008-10-17T18:50:17.319-07:00</updated><title type='text'>two important biztalk tips</title><content type='html'>without further ado, here are the two tips (in question form):&lt;br /&gt;&lt;ol&gt;&lt;li&gt;do you really need an orchestration?&lt;/li&gt;&lt;li&gt;do you really need an xsd/xml message?&lt;/li&gt;&lt;/ol&gt;most developers making the switch to biztalk are most comfortable with procedural code, and thus writing orchestrations feels natural and is a lot more intuitive. however, i've learned that messaging based solutions are extremely powerful, easier to maintain, and incredibly flexible. i'm not saying that you can't build a messaging based solution if you are using orhcestrations... all i'm saying is that most of the time, whatever you're doing in an orchestration, really doesn't need to be done in an orchestration; this is specially true if all you're doing is message manipulation.&lt;br /&gt;&lt;br /&gt;also, most projects don't need and xsd/xml message. a .net class as a message is, for most solutions, the better option. there's one big con in using a .net class however. if you need to publish your message externally, the you have to go with xsd, because a .net class offers nothing as far as publication goes. nonetheless, if you don't need an externally published message, go with a .net class... it'll save you tons of times and headaches ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-7559008604960842615?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/7559008604960842615/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2007/09/two-important-biztalk-tips.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/7559008604960842615'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/7559008604960842615'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2007/09/two-important-biztalk-tips.html' title='two important biztalk tips'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-1247407004567865806</id><published>2007-06-28T20:48:00.000-07:00</published><updated>2007-06-28T20:56:56.078-07:00</updated><title type='text'>i'm on slashdot!!!</title><content type='html'>ok, so i'm really not on slashdot, but the project i'm working on was recently reviwed &lt;a href="http://science.slashdot.org/article.pl?sid=07/06/19/0235241"&gt;there&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;since i don't particularly like touting my own horn (not to mention that no one reads this blog anyhow), i'll just say that i'm writing all of the back-end communication with sorenson genomics and internal systems.&lt;br /&gt;&lt;br /&gt;i was excited about this project from the get-go, but the "national" attention it's gotten really makes this one something else.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-1247407004567865806?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/1247407004567865806/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2007/06/im-on-slashdot.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/1247407004567865806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/1247407004567865806'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2007/06/im-on-slashdot.html' title='i&apos;m on slashdot!!!'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-914422160565100454</id><published>2007-06-07T18:58:00.000-07:00</published><updated>2007-06-07T19:08:47.520-07:00</updated><title type='text'>communication!</title><content type='html'>i've always been acutely aware of the fact that a lot of problems in life arise out of the lack of proper communication - and IT is no exception to this rule.&lt;br /&gt;&lt;br /&gt;the oracle guys at place i work, are all (with one exception) non-developers, and have decided to start writing some web-services in order to expose some features that haven't been available before.&lt;br /&gt;&lt;br /&gt;one of the services they wrote gets the purchase order for any given sales order. as i tried to consume the service today, i noticed that the purchase order had a flag for whether the purchase order had been canceled - but here's the thing: the flag was not a boolean, it was a string and it returned either 'Yes' or null.&lt;br /&gt;&lt;br /&gt;so i called them and explained that it might be better to use a boolean. they seemed a little reluctant, so i went over to their desks to try to persuade them. and when i got there i realized that i could not explain what i wanted to explain without technical terms, and in a way that would make sense to them. i guess that happens when you only communicate with other techies on a regular basis, but that is really no excuse.&lt;br /&gt;&lt;br /&gt;everything ended up ok; i had to explain a few concepts and terms like coupling, cohesion, etc. but in a way that meant something to them and would show them the values of their code.&lt;br /&gt;&lt;br /&gt;communication is hard, especially when we can't speak the same language. i'm looking forward to more opportunities to interact with the oracle guys, so i can get out of my comfort zone and expand my vocabulary.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-914422160565100454?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/914422160565100454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2007/06/communication.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/914422160565100454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/914422160565100454'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2007/06/communication.html' title='communication!'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-6314671410882856231</id><published>2007-01-18T09:22:00.001-07:00</published><updated>2007-01-18T09:31:41.426-07:00</updated><title type='text'>how to be an expert</title><content type='html'>kathy sierra has an excellent article on &lt;a href="http://headrush.typepad.com/creating_passionate_users/2006/03/how_to_be_an_ex.html"&gt;how to become an expert&lt;/a&gt;. here's a quote, that captures the essence of her post:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;For the superior performer the goal isn't just repeating the same thing again and again but achieving higher levels of control over every aspect of their performance. That's why they don't find practice boring. Each practice session they are working on doing something better than they did the last time.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;i've blogged about becoming a pro too; you can find the post &lt;a href="http://notrefenetre.blogspot.com/2006/11/becoming-pro.html"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-6314671410882856231?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/6314671410882856231/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2007/01/how-to-be-expert.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6314671410882856231'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6314671410882856231'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2007/01/how-to-be-expert.html' title='how to be an expert'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-5969950206977526406</id><published>2007-01-08T16:31:00.001-07:00</published><updated>2008-04-04T16:15:10.863-07:00</updated><title type='text'>self correlating ports (and parallel processing)</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_U0AuZcqOces/RaLVxXmvhYI/AAAAAAAAAAU/IrLYLZpbwNo/s1600-h/selfCorrelatingPort.bmp"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_U0AuZcqOces/RaLVxXmvhYI/AAAAAAAAAAU/IrLYLZpbwNo/s400/selfCorrelatingPort.bmp" alt="" id="BLOGGER_PHOTO_ID_5017807978970973570" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;the image above belongs to an orchestration i wrote to update a table with a list of currencies. the process is rather simple: all we have to do, is get the list of currencies we support (from the database), and then update the exchange rate.&lt;br /&gt;&lt;br /&gt;to do this, i chose to use and extremely parallel method, in which every currency spins off its own thread, calls the service that contains current exchange quotes, and updates its value in the db.&lt;br /&gt;&lt;br /&gt;what you don't see in the image above is the code that gets the list from the database and then instantiates a new orchestration for each currency. what you do see, is the part where the orchestrations (when they have finished their work) call back to signal that they have finished. after this, we send out an email notifying that we've updated all currencies.&lt;br /&gt;&lt;br /&gt;doing this in biztalk is rather simple, since the functionality to asynchronously start orchestrations comes out of the box, and call backs are easily implement with self correlating ports. i like how biztalk makes this parallel process extremely simple.&lt;br /&gt;&lt;br /&gt;if you wish to learn more about how to setup self corrlating ports, visit Stephen W. Thomas BizTalk Blog &lt;a href="http://geekswithblogs.net/sthomas/archive/2006/02/27/70886.aspx"&gt;here&lt;/a&gt; for detailed instructions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-5969950206977526406?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/5969950206977526406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2007/01/self-correlating-ports.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/5969950206977526406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/5969950206977526406'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2007/01/self-correlating-ports.html' title='self correlating ports (and parallel processing)'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_U0AuZcqOces/RaLVxXmvhYI/AAAAAAAAAAU/IrLYLZpbwNo/s72-c/selfCorrelatingPort.bmp' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-6647632032973501193</id><published>2007-01-03T19:51:00.000-07:00</published><updated>2007-01-03T20:47:00.497-07:00</updated><title type='text'>who's on your bus?</title><content type='html'>i once read an interview with jim collins (author of &lt;span style="font-style: italic;"&gt;from good to great&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;built to last&lt;/span&gt;) where he said the most important factor in a succesful company is whther or not "the right people are on the bus". if you have the right people, everything else will fall into place... at least that is the theory. and my gut feeling is that the theory is right; people are not everything, but they are important enough where if you have to just pick one thing, you pick the right people.&lt;br /&gt;&lt;br /&gt;i mention this because of an experience i had at work today:&lt;br /&gt;i found a problem trying to begin a transaction in one of our live servers. before calling the dbas, i made sure i had a pretty good idea of what was going on... the problem only surfaced when trying to start a transaction from a client that was on a different domain.&lt;br /&gt;&lt;br /&gt;i called in one of the dbas and described what was happening and asked for his help to solve the problem. i was polite when i brought the issue up, but our dba immediately became aggresive and blamed the problem on the client. i was confident that the problem was on the server, so i insisted he should at least take a look at it. &lt;br /&gt;&lt;br /&gt;we went back and forth, arguing where the problem was, for at least 10 minutes; i finally had to show our dba i wasn't kidding, and in a somewhat threatening (firm, more than anything) tone told him that (1)what he was saying made no sense and he knew, and (2) what he needed to do to get proof that it was the server that wasn't working.&lt;br /&gt;&lt;br /&gt;after going through the steps i asked to go through, he finally admitted it was the server that wasn't working. he also told me he had no idea on how to fix it (i don't blame him on this... from the research i did before i called him, it was apparent to me that the problem wasn't trivial) and would get back to me whenever he had found a solution. i immedately thanked him for his time and for committing to solving the issue.&lt;br /&gt;&lt;br /&gt;after i hung up, i started thinking: why did it have to come to this? why is it so hard to work with the dbas? (it's not the first time i've had a experience like this, and i'm not the only one that has problems working with them). i thought: "we need the right people on that job, it's a key job. &lt;span style="font-style:italic;"&gt;we nee the right people on the bus&lt;/span&gt;".&lt;br /&gt;&lt;br /&gt;my manager congratulated me on how i handled the situation (he actually sat there listening the whole time because this was a high priority issue for us). after a few comments i told him i thought the hardest part about being a "techie" is not the technology, but working rather &lt;span style="font-weight:bold;"&gt;working&lt;/span&gt; and &lt;span style="font-weight:bold;"&gt;communicating&lt;/span&gt; effectively with others; i also told him most problems in software arise because of problems in these areas... and thus the importance of &lt;span style="font-weight:bold;"&gt;getting the right people on the bus.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-6647632032973501193?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/6647632032973501193/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2007/01/whos-on-your-bus.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6647632032973501193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/6647632032973501193'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2007/01/whos-on-your-bus.html' title='who&apos;s on your bus?'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-116544788563772515</id><published>2006-12-06T16:28:00.000-07:00</published><updated>2006-12-06T18:55:09.316-07:00</updated><title type='text'>learning to drive</title><content type='html'>in his book &lt;span style="font-style:italic;"&gt;extreme programming explained&lt;/span&gt;, kent beck compares software development to driving a car, and makes the following insight:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;The driver of a software project is the customer. If the software doesn't do what they want it to do, you have failed. Of course, they don't know exactly what the software should do. That's why software development is like steering, not like getting the car pointed straight down the road. Our job as programmers is to give the customer a steering wheel and give them feedback about exactly where we are on the road.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;talk about a useful mindset to have! on a similar note, eric (my current manager at work) always tells me about how in one of his most succesful projects, they presented the product to the customer on a daily basis to provide the feedback beck talks about.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-116544788563772515?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/116544788563772515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2006/12/learning-to-drive.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/116544788563772515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/116544788563772515'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2006/12/learning-to-drive.html' title='learning to drive'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-116538303133069199</id><published>2006-12-05T22:28:00.000-07:00</published><updated>2006-12-05T23:18:29.076-07:00</updated><title type='text'>wtf: sonic cineplay</title><content type='html'>i'm well aware of what wtf stands for; however, i choose to ignore that and have it mean &lt;span style=""&gt;&lt;a href="http://thedailywtf.com"&gt;Curious Pervasions in Information Technology.&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;here the is my first wtf:&lt;br /&gt;on friday december 1st i rented a movie. for some unknown reason the dvd would not play correctly on our desktop... after about an hour of trying to make it work, we decided to to just watch the movie on our laptop.&lt;br /&gt;&lt;br /&gt;a few days later, my wife tells me: "something is wrong with the desktop. it won't play the 'signing time' dvds either. i take a quick look, and sure enough, the dvds play but there is no sound.&lt;br /&gt;&lt;br /&gt;after trying everything i could think of (checking codecs, checking settings on the player, checking audio drivers, etc.) for four days, i'm about to give up and roll back to a previous back up. before doing this however, i try one more google search... i find the following on one of roxio's customer forums:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;All,&lt;br /&gt;&lt;br /&gt;There is an issue with Cineplayer not working. That could be no video, no audio or corrupted video. We’re aware of the issue and are working with Sonic on getting this resolved shortly.&lt;br /&gt;&lt;br /&gt;The problem only manifests when the clock is set to the month of December. So simply change the date to another month and it will work.&lt;br /&gt;&lt;br /&gt;This is only a workaround. We are currently working with Sonic to resolve this issue. We’ve been told that a patch should be available by Wednesday, December 6th.&lt;br /&gt;&lt;br /&gt;We apologize for the inconvenience and assure you we are working to get this resolved as quickly as possible.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;this is a wtf on so many levels... i just can't even begin to comprehend why a codec does not work on the month of december. it would be great to look at the code that's causing this bug and then posting it for learning purposes.&lt;br /&gt;&lt;br /&gt;i'm glad i didn't roll back to a previous back up; that would have failed and then i would have probably re-installed everything; after that i would have probably shipped my computer to dell... and pulled my hairs out :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-116538303133069199?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/116538303133069199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2006/12/wtf-sonic-cineplay.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/116538303133069199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/116538303133069199'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2006/12/wtf-sonic-cineplay.html' title='wtf: sonic cineplay'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-116423969342834145</id><published>2006-11-22T16:49:00.000-07:00</published><updated>2006-11-22T21:15:25.373-07:00</updated><title type='text'>taking notes (and a little on UML)</title><content type='html'>i've written about this on my personal blog, but i'll mention it here again... taking notes helps you remember stuff, so i like to do it even if i never look at my notes again.&lt;br /&gt;&lt;br /&gt;not too long ago i interviewed with bill, a manager in the company i work for. while we were talking he took copious notes. while he was doing this he told me not worry, that he always does this even though he normally just throws his notes away.&lt;br /&gt;&lt;br /&gt;under the guidance of this principle, i'd then like to write down the following idea from Fowler's &lt;span style="font-style:italic;"&gt;UML Distilled&lt;/span&gt;:&lt;br /&gt;use cases help you determine requirements; and actors help you determine use cases.&lt;br /&gt;&lt;br /&gt;i like the idea because it's simple, easy to remember, and it helps keep the end in mind.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-116423969342834145?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/116423969342834145/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2006/11/taking-notes-and-little-on-uml.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/116423969342834145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/116423969342834145'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2006/11/taking-notes-and-little-on-uml.html' title='taking notes (and a little on UML)'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-116417349098981144</id><published>2006-11-21T22:21:00.000-07:00</published><updated>2006-11-21T22:33:43.526-07:00</updated><title type='text'>asp 1.1 and 2.0 on the same box</title><content type='html'>the compnay i work for, and a lot of guys on my team have added the .net 2.0 framework to their boxes recently.&lt;br /&gt;&lt;br /&gt;a lot of people have come to ask me either why their 1.1 web projects stopped working or why they can't get a 2.0 asp project to work. 9/10 times the problems arises because the box is trying to run asp 1.1 and 2.0 under the same app pool.&lt;br /&gt;&lt;br /&gt;so, the answer to the problem is to make sure that at the very minimum all your 1.1 stuff is running under one app pool, and all of your 2.0 stuff is running under a different pool.&lt;br /&gt;&lt;br /&gt;a lot of people have asked me why this is, and honestly, i don't know yet (but i'm looking)... i'll post a follow up as soon as i find out. &lt;br /&gt;&lt;br /&gt;but there's an important lesson to learn here, not just some obscure fact about asp:&lt;br /&gt;solving this issues is actually easier than what one would think; all one has to do is look in the eventviewer, where the following error would be logged:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;It is not possible to run two different versions of ASP.NET in the same IIS process. Please use the IIS Administration Tool to reconfigure your server&lt;br /&gt;to run the application in a separate process.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;it's been my experience that most devs don't look in the eventviewer, iis logs, etc, to find clues to their problems. as i've worked with BizTalk (and thus have been forced to look there) i've learned what great tools the eventviwer, the performance counters, and others are.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-116417349098981144?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/116417349098981144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2006/11/asp-11-and-20-on-same-box.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/116417349098981144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/116417349098981144'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2006/11/asp-11-and-20-on-same-box.html' title='asp 1.1 and 2.0 on the same box'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-25340877.post-114412357863233304</id><published>2006-04-03T21:06:00.000-07:00</published><updated>2007-01-03T19:50:54.523-07:00</updated><title type='text'>a place holder</title><content type='html'>just an entry fot this new blog of mine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25340877-114412357863233304?l=adotnetdude.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adotnetdude.blogspot.com/feeds/114412357863233304/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://adotnetdude.blogspot.com/2006/04/place-holder.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/114412357863233304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/25340877/posts/default/114412357863233304'/><link rel='alternate' type='text/html' href='http://adotnetdude.blogspot.com/2006/04/place-holder.html' title='a place holder'/><author><name>Esteban Araya</name><uri>http://www.blogger.com/profile/07645289431023957896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
