<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>Latest entries from timstall.dotnetdevelopersjournal.com</title><link>http://timstall.dotnetdevelopersjournal.com/</link><description></description><copyright>Copyright 2009 timstall.dotnetdevelopersjournal.com</copyright><generator></generator><lastBuildDate>Fri, 03 Jul 2009 15:23:00 GMT</lastBuildDate><image><title>Latest entries from timstall.dotnetdevelopersjournal.com</title><url>http://res.sys-con.com/portlet/163/featured-blog-graphic-145.gif</url><link>http://timstall.dotnetdevelopersjournal.com/</link></image><ttl>360</ttl><docs>http://backend.userland.com/rss</docs><item><title>Why a manager may not want you to learn</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/why_a_manager_may_not_want_you_to_learn.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/why_a_manager_may_not_want_you_to_learn.htm</link><pubDate>Fri, 03 Jul 2009 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=why%5Fa%5Fmanager%5Fmay%5Fnot%5Fwant%5Fyou%5Fto%5Flearn</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>I&#39;m a huge advocate of <a href="/tags/?/learning">learning</a>. And it&#39;s natural for devs to want to pick up new stuff. However, many devs don&#39;t realize that they may report to a manager that actually wants to prevent them from learning new things - even on their own personal time. I think this type of manager is rare. However, it&#39;s good to be aware in case a manager is (perhaps unintentionally) &quot;sabotaging&quot; your learning.</p><p>I hesitated about writing this post lest it seem to cynical or jaded, but it&#39;s worth discussing as developers should be aware of such things. Note that there is not one specific person/event/incident that I have in mind, but rather glimpses of things over the last 10 years.</p><ul><li>Their control - They may want to be in control, and you learning new things that they don&#39;t know takes away from their control. <ul><li><strong>They may want to understand the entire architecture themselves. </strong>It&#39;s sort of a &quot;<a href="/why_the_notbuilthere_mentality.htm">not built here</a>&quot; applied to a personal level - &quot;If I don&#39;t already know it, it must not be necessary.&quot;</li><li><strong>They may not want to learn the new stuff themselves.</strong> If you&#39;re a tech manager, and all your devs learn the next wave of technologies, it pressures you to learn the new wave as well, else you look obsolete.</li><li><strong>They don&#39;t want you exposing their mistakes.</strong> Say a senior developer wrote a bad messaging framework. As long as no other employee has a clue about messaging, no one knows that they made a bad mistake.</li><li><strong>They want you to &quot;suffer&quot; just like they did.</strong> Often new techs make it easier to do something, and rather than have the easy way out, you should do it the original way so you &quot;understand what&#39;s really going on&quot;. Think using assembly language or C++ instead of a higher-level language like C#.</li></ul></li><li>It doesn&#39;t support the immediate work <ul><li><strong>They may think it&#39;s a waste of time</strong> - &quot;We&#39;ve already invested in this architecture, we don&#39;t need anything else.&quot; Even though it&#39;s your own time, they&#39;d rather you spend overtime on &quot;useful features&quot;, like copying and pasting tedious code.</li><li><strong>It competes with your day job</strong> - If you&#39;re researching <a href="/xna_realtimestrategy_game_with_source_code.htm">some cool XNA technology</a>, which is a lot more fun than the drudgery of some bad architecture, it may compete. Suppose you work at home, it might &quot;distract&quot; you.</li><li><strong>It may be misapplied</strong>. New stuff is risky, and could be buggy or applied incorrectly - which would hurt the project.</li><li><strong>Their afraid that &quot;smart&quot; developers are hard to manage</strong>. Smart developers can sometimes be total egomaniacs to work with (because they <a href="/smart_vs_smart_aleck.htm">think they&#39;re so smart</a>), and management may not want to even think about dealing with that.</li></ul></li><li>You may leave <ul><li><strong>You may outgrow your company and leave</strong>-&nbsp; If your company is stuck in the dark ages, they may want to keep everyone&#39;s technical skills &quot;in the dark&quot; as well, lest an employee &quot;see the light&quot; and leave.</li><li><strong>It makes your more marketable, and you may leave</strong>. If you&#39;re stuck with some niche technology on an obsolete framework, you aren&#39;t very marketable and hence can&#39;t get another job, and hence your boss has tremendous control over you.</li></ul></li></ul><p>Examples of how a manager might unintentionally discourage a developer from learning:</p><ul><li>Financially reject <em>anything</em> (like buying new books or tools or paying for a class)</li><li>Undermine your confidence (&quot;Why would you need that&quot;) or question your motives.</li><li>Deny you resources, such as preventing you from installing anything on your machine (open source code, tools, etc...)</li><li>Never affirm new learning or innovation. They tell you &quot;good job&quot; for getting that feature done, but won&#39;t affirm picking up new technologies.</li><li>Never provide their software engineers with a continuing-education plan. Ask yourself, how do developers go &quot;<a href="/what_is_the_difference_between_an_average_dev_and_a_star.htm">to the next level</a>&quot; in your team? Does management help them?</li></ul><p>It&#39;s sad, but some companies are structured where it&#39;s not in the manager&#39;s best interests for the employees to &quot;wise up&quot;. The managers want hard-working, honest people who are easy to manage, but they don&#39;t want to deal with innovation or smart developers.</p><p>LINK: <a href="/does_your_team_culture_encourage_learning.htm">Does your Project encourage learning</a></p>]]></description><category>learning</category><category>management</category></item><item><title>23 features of an enterprise data access layer</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/23_features_of_an_enterprise_data_access_layer_1.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/23_features_of_an_enterprise_data_access_layer_1.htm</link><pubDate>Mon, 29 Jun 2009 17:20:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=23%5Ffeatures%5Fof%5Fan%5Fenterprise%5Fdata%5Faccess%5Flayer%5F1</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>Most line of business applications will die unless they have a strong data access strategy. Enterprise apps simply cannot afford to hard-code thousands of in-line SQL calls to an aspx code behind; the maintenance and lack of reuse and testability will kill you. I realize entire books are written on data-access strategy (<a href="/book_patterns_of_enterprise_application_architecture.htm">Fowler</a>, <a href="/book_microsoft_net_architecting_applications_for_the_ente.htm">Dino/Andrea</a>), and by much smarter men than I, so I only offer this blog post as a summary and braindump. I&#39;m sure I&#39;ve inevitably missed several important aspects. I also realize that developers take their Data Access Layers (DAL) very seriously and personally, and may consider some features more or less important than others.</p><p><strong>Must-have</strong> <strong>features </strong>- This will get you started.</p><ol><li><strong>CRUD</strong> - Give you at least the basic CRUD (Create, Read, Update, Delete) functionality</li><li><strong>Sorted paging and filtering </strong>- Provide a simple way to handle sorted-paging and filtering</li><li><strong>Automatically generated</strong> - For the love of all that is good, do NOT write tons of manual data-access plumbing code by hand. Either code generate it, or use a dynamic ORM (like NHibernate)</li><li><strong>Serializable objects</strong> - Domain objects should be serializable so you can persist them across the wire (such as store them in a cache). Sometimes this is solved as easily as slapping on attributes to your objects.</li><li><strong>Handles concurrency</strong> - Even a where-clause check that simply compares a version (or datetime) stamp.</li><li><strong>Transactions</strong> - Support transactions across multiple tables, such as either using the SQL transaction keyword, or the ADO.Net transaction (or something else?)</li></ol><p><strong>Good-to-have features</strong> - When you start scaling up, you&#39;re really going to want these.</p><ol><li><strong>FK and unique-index lookups</strong> - Provide those extra automatically generated FK and unique-index lookups on your tables.</li><li><strong>Meta-data driven</strong> - Perhaps you define your entity model in xml files, and your process generates the rest from that (tables, SP, DAL, entity C# classes, etc...)</li><li><strong>Mocked / Isolation-Framework-friendly </strong>- It could provide support for a mock database, or at least create interfaces for all the appropriate classes so you program against the interface instead of concrete classes.</li><li><strong>Batching</strong> - (Includes transaction management). If you don&#39;t have the ability to batch two DAL calls together, because remote calls are relatively expensive, you&#39;ll inevitably start squishing unrelated calls into single spaghetti-blobs for performance reasons. </li><li><strong>Insert an entire grid at once</strong> - This could be done via batching, or perhaps SQL 2008&#39;s new <a href="http://msdn.microsoft.com/en-us/library/bb510489.aspx">table value parameter</a>.</li><li><strong>Handle database validation errors </strong>- Ability to capture database validation errors and return them to the business tier. For example, checking that a code must be unique. (See: <a href="/why_would_someone_put_business_logic_in_a_stored_procedure.htm">Why put logic in SP?</a>)</li><li><span style="font-weight: 700">Caching</span> - for performance reasons, you&#39;ll eventually want to cache certain types of data. Ideally your DAL reads some cache-object config file and abstracts this all away, so you don&#39;t litter your codeBehinds with hard-coded cache calls. [LINK: thoughts on caching]</li><li><strong>Multiple types of databases</strong> - Access multiple different types of databases, such as main, historical, reporting, etc...</li><li><strong>Scales <em>out</em> to multiple, partitioned, databases</strong> - For example, your main application data store may be partitioned by user SSN, and hence you can spread out the load across multiple databases instead of having one, giant bottleneck.</li><li><strong>Integrate with a validation framework</strong> - Perhaps by applying attributes to the entity objects (like what <a href="http://msdn.microsoft.com/en-us/library/cc309509.aspx">Enterprise Library Validation Block</a> does), you may want your generator to be able to read both database schema info and external override values from an xml file. For example, say you have an Employee object with a &quot;FirstName&quot; property which maps to the EmpInfo table&#39;s FirstName column, the generator could pull the varchar length and required attributes from the database column, and then possibly pull a required expression pattern from the override xml file.</li><li><strong>Audit trail for changes made</strong> - The business sponsors are going to want to see change history of certain fields, especially security and financial related ones.</li><li><strong>Create UI admin pages </strong>- Provide the ability to create the admin UI pages for easy maintenance of each table. Even if you don&#39;t actually deploy these, they&#39;re a great developer aid.</li></ol><p><strong>Wow</strong> - These are more advanced</p><ol><li><strong>Partial update of an object </strong>- say you have a reusable Employee object with 30 fields, but you only need half those fields in some specific context, it can be beneficial to have a DAL that can be &quot;smart&quot; and updates only the fields that you used in a given context. Perhaps you could add a csv list to the base domain object (that Employee inherits from), and every time a property in Employee is set, it adds the field to that CSV list. Then, it passes that CSV list to the data access strategy, which only updates the fields in that list.</li><li><strong>Provide a data dictionary</strong> so it integrates into other processes. Building off the meta-data approach (where you can automatically generate lots of extra plumbing to assist with integration and abstraction layers), you can start doing some really fancy things: <ol><li>See every instance in the UI where a DB field was ultimately used</li><li>Provide clients a managed abstraction layer that lets them write their own reports <em>given the UI views</em> - not the backend tables.</li><li>Provide clients a managed abstraction layer that lets them do mass updates of their own data (this is a validation and security nightmare).</li></ol></li><li><strong>N-level undo</strong> - I&#39;ve never personally implemented or needed this, but I hear CLSA.Net has it.</li><li><strong>Return deep object graphs</strong> - Having a domain model is great, but there&#39;s the classic OOP - relational data mismatch. ORM mappers explicitly help solve this. Without some sort of ORM mapper, most application inevitably &quot;settle&quot; (?) for a transaction script or table module/active record approach. A deep object graph also requires lazy loading.</li><li><strong>Database independence</strong> - Configure your database for easy switch from SQL Server to Oracle. You could do this at compile time by re-writing your code-generator templates. I&#39;ve heard some architects insist that you should be able to do this at run time as well via a provider model, and updating some information in the config file (I&#39;ve never personally done this).</li></ol><p>Data access is a re-occurring problem, so the community has evolved a lot of different solutions. Consider some of these:</p><ul><li>ORM mappers <ul><li><a href="http://sourceforge.net/projects/nhibernate">NHibernate</a> - A popular ORM mapper (and check out <a href="http://www.bestguesstheory.com/search/label/NHibernate">Hudson Akridge&#39;s blog</a> for NHibernate expertise)</li></ul></li><li>CodeSmith-related (generates code at compile time) <ul><li><a href="http://www.lhotka.net/cslanet/">CLSA.Net</a> - Rockford Lhotka&#39;s super enterprise framework, which has CodeSmith support.</li><li><a href="http://nettiers.com/">.NetTiers</a> - A set of CodeSmith templates to create the entire DAL and UI admin pages.</li><li>Your own custom-built thing (via <a href="http://www.codesmithtools.com/">CodeSmith</a>)</li></ul></li><li>Microsoft solutions <ul><li><a href="http://www.4guysfromrolla.com/articles/020806-1.aspx">Strongly-typed .Net DataSets</a> - This is what .Net first had.</li><li><a href="http://msdn.microsoft.com/en-us/library/bb425822.aspx">Linq-to-Sql</a> - Great for RAD apps, but I&#39;m personally not sure how well it scales. Be sure to run <a href="/sql_tools__profiler_and_sqlcommand.htm">SQL-Profiler</a> on its generated sql.</li><li><a href="http://msdn.microsoft.com/en-us/library/aa697427(VS.80).aspx">Microsoft Entity Framework</a> - Microsoft&#39;s offering for a domain-model approach (as opposed to their out-of-the-box typed datasets).</li></ul></li><li>I&#39;ve heard about, but never personally used these: <ul><li><a href="http://www.castleproject.org/activerecord/index.html">Castle ActiveRecord</a></li><li>(Probably several others too...)</li></ul></li><li>In-line SQL from your Aspx codebehind - ha ha, just kidding. Don&#39;t even think about it. Seriously... don&#39;t.</li></ul>]]></description><category>architecture</category></item><item><title>BOOK: Microsoft .NET: Architecting Applications for the Enterprise</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/book_microsoft_net_architecting_applications_for_the_ente.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/book_microsoft_net_architecting_applications_for_the_ente.htm</link><pubDate>Fri, 19 Jun 2009 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=book%5Fmicrosoft%5Fnet%5Farchitecting%5Fapplications%5Ffor%5Fthe%5Fente</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p style="margin-top: 0px; margin-bottom: 0px">As the .Net platform matures (almost version 4.0!), I&#39;m seeing more and more good .Net architecture books coming out. One such book is <a href="http://www.amazon.com/Microsoft&Acirc;&reg;-NET-Architecting-Applications-PRO-Developer/dp/073562609X/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1244582055&amp;sr=1-1">Microsoft .NET: Architecting Applications for the Enterprise</a>, by Dino Esposito and Andrea Saltarello. </p><p style="margin-top: 0px; margin-bottom: 0px">&nbsp;</p><p style="margin-top: 0px; margin-bottom: 0px">The first section focused heavily on architectural principles. The book was worth getting just for Chapter 3 alone (Design Principles and Patterns), which provided a survey of the various concepts required for high-level architecture, such as OOP, Design Patterns, Structured Design, Separation of Concerns, Dependency Injection, Testability, Security, and AOP.</p><p style="margin-top: 0px; margin-bottom: 0px">&nbsp;</p><p style="margin-top: 0px; margin-bottom: 0px">I also liked their chapter on DataAccess. They made a well-reasoned plug for <a href="http://sourceforge.net/projects/nhibernate">NHiberante</a> and the maintenance benefits of auto-generated dynamic SQL for the data access layer. I admit that I personally have &quot;grown up&quot; with a bias for code-generated <a href="/why_use_stored_procedures_over_direct_sql_calls.htm">stored procedures</a>, but I can see the changing winds.</p><p style="margin-top: 0px; margin-bottom: 0px">&nbsp;</p><p style="margin-top: 0px; margin-bottom: 0px">Their book is very focused on the standard N-tier layers: DataAccess, BusinessFacade, Service, and Presentation. Here&#39;s the table of contents:</p><ul><li><p style="margin-top: 0px; margin-bottom: 0px">Chapter 1: Architects and Architecture Today</p></li><li><p style="margin-top: 0px; margin-bottom: 0px">Chapter 2: UML Essentials</p></li><li><p style="margin-top: 0px; margin-bottom: 0px">Chapter 3: Design Principles and Patterns</p></li><li><p style="margin-top: 0px; margin-bottom: 0px">Chapter 4: The Business Layer</p></li><li><p style="margin-top: 0px; margin-bottom: 0px">Chapter 5: The Service Layer</p></li><li><p style="margin-top: 0px; margin-bottom: 0px">Chapter 6: The Data Access Layer</p></li><li><p style="margin-top: 0px; margin-bottom: 0px">Chapter 7: The Presentation Layer</p></li><li><p style="margin-top: 0px; margin-bottom: 0px">Final Thoughts</p></li><li><p style="margin-top: 0px; margin-bottom: 0px">Appendix: <a href="http://nsk.codeplex.com/">The Northwind Starter Kit</a></p></li></ul><p style="margin-top: 0px; margin-bottom: 0px">The book didn&#39;t discuss much on messaging, caching, validation, logging, system integrations, configuration, or other architectural components. However, most applications make or break on the data access strategy, so I can see the focus there. And, you could have an encyclopedia if you wanted to cover every aspect of enterprise architecture.</p><p style="margin-top: 0px; margin-bottom: 0px">&nbsp;</p><p style="margin-top: 0px; margin-bottom: 0px">I found it interesting comparing the book to Fowler&#39;s landmark <a href="/book_patterns_of_enterprise_application_architecture.htm">Patterns of Enterprise Application Architecture</a>. Indeed, Dino and Andrea continually refer back to patterns in Fowler. The Dino/Andrea book almost seems intended as a sequel to Fowler&#39;s - it adds value by specializing in .Net, having the benefit of almost 6 years of hindsight, and providing constant web references and practical tools (many which didn&#39;t exist when Fowler wrote his book). Overall, it&#39;s a good read for any .Net Architect or aspiring developer. It&#39;s an especially good read for those who grew up as architects in a single company, and therefore may only have exposure to one way of doing architecture.</p>]]></description><category>architecture</category><category>books</category></item><item><title>Why share knowledge with others?</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/why_share_knowledge_with_others.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/why_share_knowledge_with_others.htm</link><pubDate>Wed, 17 Jun 2009 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=why%5Fshare%5Fknowledge%5Fwith%5Fothers</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>I&#39;m a big advocate of knowledge sharing. However, I understand why some developers may be hesitant to do so. We live in an era of unprecedented competition. People (and therefore Companies) compete against one another for employment opportunities, promotions, recognition, mindshare, and plain-old-power. In today&#39;s cut-throat world, it almost seems counter-intuitive to &quot;undermine&quot; yourself by sharing your knowledge (read: &quot;competitive advantage&quot;) with others (read: &quot;competition&quot;).</p><p>While obviously you shouldn&#39;t share trade secrets and proprietary knowledge with the competition, I still think there are a lot of good reasons to share general knowledge with the community, and especially your coworkers.</p><ul><li><strong>It teaches you</strong> <ul><li>Explaining something to others forces you to better understand it yourself.</li><li>It is self correcting - By sharing your knowledge, the other dev may be able to help you improve it by offering tweaks or suggesting gaps that you need to fill.</li><li>It provides a chance to practice your communication. To communicate, you need a &quot;receiver&quot;, someone who wants to catch (i.e. listen to) whatever message you&#39;re &quot;throwing&quot;. This means that the message needs to be relevant. What&#39;s more relevant than a message that is solving the problem that the &quot;receiver&quot; actively wants solved?</li></ul></li><li><strong>Social benefits</strong> <ul><li>To have a friend, you need to be a friend. If you never share your stuff (knowledge, tricks, tools), people may be hesitant to share their stuff with you.</li><li>Some people just enjoy helping others.</li></ul></li><li><strong>It&#39;s part of your job</strong> <ul><li>It frees up co-workers to do something useful (which could in turn benefit you, and more importantly, the company who is <em>paying</em> you), as opposed to them re-inventing what you&#39;ve already done.</li><li>It&#39;s your job as a good developer - <a href="/what_is_the_difference_between_an_average_dev_and_a_star.htm">Good developers</a> share knowledge. Also, when a company is paying you to code, it&#39;s no longer &quot;your code&quot;, but the company&#39;s code, and therefore the company has a right that tricks and knowledge be shared amongst the team.</li></ul></li><li><strong>Demonstrate leadership</strong> <ul><li>Knowledge-sharing increases <a href="/becoming_a_credible_developer.htm">your credibility</a>. By sharing objective things that other devs can verify to be correct, these devs are more likely to trust you on subjective opinions or predictions that are much harder to verify.</li><li>Become a thought-leader - Often consulting firms encourage their star consultants to demonstrate thought leadership by blogging, writing articles, or contributing to open source projects. Sometimes this is great marketing for that company, and even leads to sales. For example, thousands (millions?) of people use <a href="http://confluence.public.thoughtworks.org/display/CCNET">CruiseControl</a> from ThoughtWorks, which in turn gives ThoughtWorks name recognition and marketing.</li><li>It is necessary in order to be promoted. Leaders communicate, and usually the higher up you go, the wider the audience you need to share knowledge with. If you never practice knowledge sharing until you absolutely have to (via a job demand), then you will probably not be very good at it.</li><li>It helps make your approach the official standard (which may be good or bad). If you hide your tricks and code, only you will use them. If someone publicizes and shares their code - even if it&#39;s worse than yours - their code will be used by more people and hence adopted as the &quot;official&quot; team approach.</li></ul></li></ul><p>There are many ways to share your knowledge, such as:</p><ul><li><a href="/wikis_and_web_content_management.htm">Wikis</a></li><li>Email</li><li><a href="/how_to_encourage_standardization.htm">Automated governance</a></li><li>Sample applications</li><li>Team meetings</li><li>1-on-1 meetings (like a <a href="/code_reviews__objections_and_counterobjections.htm">Code Review</a>)</li><li><a href="/the_benefits_of_technical_blogging.htm">Blogging</a></li></ul><p style="margin-top: 0px; margin-bottom: 0px">&nbsp;</p>]]></description><category>learning</category><category>people</category></item><item><title>The benefits of technical blogging</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/the_benefits_of_technical_blogging.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/the_benefits_of_technical_blogging.htm</link><pubDate>Mon, 15 Jun 2009 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=the%5Fbenefits%5Fof%5Ftechnical%5Fblogging</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[By <a href="http://www.google.com/search?hl=en&amp;q=how+many+blogs+are+there&amp;aq=0&amp;oq=how+many+blog&amp;aqi=g10">some estimates</a>, there are over 50 <em>million</em> blogs. Granted, many of these are barely maintained, and they cover all topics (not just software engineering), but clearly there&#39;s something to this whole blogging thing. Keep in mind that the vast majority of these blogs are<em> not</em> profitable - so the authors are writing as hobbyists and not paid professionals. Millions of people - and thousands of software engineers - blog because there are a lot of benefits to it:<em> </em><ol><li>Record smaller thoughts to build up for a larger project like an article or even a book.</li><li>Instant gratification - Blogs let you publish your writing instantly, which is gratifying (as opposed to the lag time for an article or book)</li><li>Ability to share your thoughts with the world - and likewise get feedback on them.</li><li>Practice at writing, beyond just the quick email or IM context.</li><li>Provides an outlet for all the miscellaneous thoughts and code a developer comes across</li><li>Gets you to think deeper about ideas, knowing that you need to at least polish it to the level of a few paragraphs for public consumption. This helps you learn the topic yourself, as one of the best ways to learn is to teach the content to others.</li><li>Thought Leadership - some people (especially consultants where this is a resume credential) really like this. Good blog posts also <a href="/becoming_a_credible_developer.htm">build credibility</a>.</li><li>Confidence booster - putting your thoughts out there to potentially millions of people requires courage, and repeatedly doing that (and growing from the feedback) <a href="/technical_confidence.htm">builds confidence</a>. </li><li>Write anything <a href="/tags/">on any topic</a>, regardless of what you&#39;re currently working on.</li><li>It helps others. For example, sometimes I post the most obscure syntax errors I find - and other people were troubled with the exact same issue, and actually find the post useful.</li><li>Blogging acts like a personal journal. I&#39;ve gotten a kick out of seeing how some of my thoughts have evolved <a href="/read/page/archive.htm">over the last 5 years</a>.</li><li>Low barrier to entry - because blogs are (effectively) free, you can write small chunks, you can write anything you&#39;d like, and you can automatically publish it, there&#39;s a very low barrier to get started.</li></ol><p>Should you blog even if you don&#39;t get traffic? I think yes - <em>if </em>you enjoy it (such as for any of the reasons mentioned above). Traffic comes and goes, and the weirdest entries get tons of traffic while the other entries (that I expect to be popular) are almost ignored.</p><p>Related: <a href="/do_you_have_time_to_blog.htm">Do you have time to blog?</a></p>]]></description><category>learning</category></item><item><title>Real life: Avoiding customization to build a Sandbox</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/real_life_avoiding_customization_to_build_a_sandbox.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/real_life_avoiding_customization_to_build_a_sandbox.htm</link><pubDate>Thu, 11 Jun 2009 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=real%5Flife%5Favoiding%5Fcustomization%5Fto%5Fbuild%5Fa%5Fsandbox</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>I have three kids - two sons and a daughter. Cute little buggers, so I wanted to make them a sandbox to play in. I figure doing something physical and outdoors, as opposed to watching TV, would be good for them. Plus, I&#39;m all for anything that even remotely encourages them to do engineering. However, I have very, <em>very</em>,<em> </em>minimal wood-working skills. When it comes to woodworking, I am (at best) a hobbyist - <a href="/what_is_the_difference_between_an_average_dev_and_a_star.htm">by no means an expert</a>. This means I was just trying to build a simple sandbox that works - no fancy wood cutting, things that take big vocabulary to describe, or expensive tools required. I made a crude box-like design, drove to the local home depot, and got help picking out the wood (12x1x6 inch cedar). The only cuts I made where ones that the home depot guy could do in the store - so no triangle, notched, or diagonal cuts. I hauled my precious wood back to my garage (read: <em>not</em> professional tool workshop), applied one coat of polyurthethane something (read: I hope that helps protect against weathering), and hammered the boards together. After digging the box into the ground and filling it with sand, it was good enough and I was done.</p><p>Why dump such a story on my technical blog? Because my hobbyist mentality towards a wood sandbox is essentially the same as many &quot;programmers&quot; hobbyist mentality towards the craft of software engineering. We both just want to get it done, make the end users happy, and maybe enjoy it along the way. If we miss out on an optimal technique, that&#39;s okay. Working with other people, it can be useful to understand that mindset.</p><p>And yes, the kids loved it.</p><p><img src="http://files.blog-city.com/files/J05/88352/p/f/sandbox.jpg" alt="" title="sandbox.jpg" width="448" height="336" /></p><p>&nbsp;</p>]]></description><category>life</category></item><item><title>An easy way to hack unvalidated web input</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/an_easy_way_to_hack_unvalidated_web_input.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/an_easy_way_to_hack_unvalidated_web_input.htm</link><pubDate>Wed, 10 Jun 2009 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=an%5Feasy%5Fway%5Fto%5Fhack%5Funvalidated%5Fweb%5Finput</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p style="margin-top: 0px; margin-bottom: 0px">Many security bugs get overlooked because hackers use &quot;special&quot; tools that give them options that the original developers anticipate. For example, most web developers only test their application through a browser. While this is sometimes sufficient to check different querystring inputs, it gives one an enormous false sense of security. Consider two cases:</p><ul><li><p style="margin-top: 0px; margin-bottom: 0px">A button is disabled, therefore the developer assumes you can&#39;t click it (Example: A Save button is disabled because some data isn&#39;t valid)</p></li><li><p style="margin-top: 0px; margin-bottom: 0px">Data is stored in a hidden field, therefore the developer assumes that you can&#39;t change it. (Example: A record&#39;s ID is stored in a hidden field)</p></li></ul><p style="margin-top: 0px; margin-bottom: 0px">To some people,&nbsp;this appears safe because IE doesn&#39;t let you click disabled buttons or change the value of hidden fields. However, IE is only used to collect the data from the page and aggregate it into a post that it sends to the webserver. What if the hacker is using a different tool besides IE that gives them more control on how to assemble and send this post (or an <em>extension</em> to IE that lets them modify fields)?</p><p style="margin-top: 0px; margin-bottom: 0px">&nbsp;</p><h3 style="margin-top: 0px; margin-bottom: 0px">How to hack it</h3><p style="margin-top: 0px; margin-bottom: 0px">&nbsp;</p><p style="margin-top: 0px; margin-bottom: 0px">You could crack both the above cases using Visual Studio Team Test (or I bet <a href="http://getfirebug.com/">Firebug</a>, or the <a href="http://blogs.msdn.com/ie/archive/2008/09/03/developer-tools-in-internet-explorer-8-beta-2.aspx">IE8 dev tools</a>). Here&#39;s how:</p><ol><li><p style="margin-top: 0px; margin-bottom: 0px">Open up VS Team Test</p></li><li><p style="margin-top: 0px; margin-bottom: 0px">Create a Test Project, and add a new web test. <a href="http://msdn2.microsoft.com/en-us/library/ms182539(VS.80).aspx">This opens up a recorder in IE</a>.</p></li><li><p style="margin-top: 0px; margin-bottom: 0px">Navigate to the page you want to crack, such as something that stores data in a hidden field.</p></li><li><p style="margin-top: 0px; margin-bottom: 0px">Perform a normal save action, such as saving the page (which uses data from the hidden field)</p></li><li><p style="margin-top: 0px; margin-bottom: 0px">Stop the recording. Play back the test just to make sure it works in the normal case. Note how for each request, VS provides you a new row and lets you see the exact request and response, as well as what visually appears in the Web Browser. </p><ol><li><p style="margin-top: 0px; margin-bottom: 0px">&nbsp;</p></li><li><p style="margin-top: 0px; margin-bottom: 0px"><img src="http://files.blog-city.com/files/J05/88352/p/f/vshack_08102007_c.jpg" alt="" title="vshack_08102007_c.jpg" width="349" height="320" /></p></li></ol></li><li><p style="margin-top: 0px; margin-bottom: 0px">Now start the hacking. Go to the request where you saved the page (that collected data from the hidden field), and unbind that field and change its value to whatever you want. In this case, I simply had a field called &quot;Hidden1&quot;, and I changed it&#39;s value to &quot;abc&quot;. Note that just like IE, the webtest sends a post to the server. But unlike IE, you can easily change the contents of that post. </p><ol><li><p style="margin-top: 0px; margin-bottom: 0px">&nbsp;</p></li><li><p style="margin-top: 0px; margin-bottom: 0px"><img src="http://files.blog-city.com/files/J05/88352/p/f/vshack_08102007_a.jpg" alt="" title="vshack_08102007_a.jpg" width="427" height="237" /></p></li></ol></li><li><p style="margin-top: 0px; margin-bottom: 0px">Rerun the webtest. The new, hacked, value is sent to the server.</p></li><li><p style="margin-top: 0px; margin-bottom: 0px">Note that you can also script VS WebTests with C#. So, you could have a for-loop that re-submits a 1000 requests, varying the post values each time.</p></li></ol><h3 style="margin-top: 0px; margin-bottom: 0px">So, what can we do?</h3><p style="margin-top: 0px; margin-bottom: 0px">&nbsp;</p><p style="margin-top: 0px; margin-bottom: 0px">As a developer, we always need to validate and do security checks on the server - merely JS side validation is not enough. For example, knowing that that hidden field could be hacked, always validate that data as if it were a free-form textbox.</p><p style="margin-top: 0px; margin-bottom: 0px">&nbsp;</p><p style="margin-top: 0px; margin-bottom: 0px">The problem is that this degree of extra validation (1) costs much more time, and (2) could be a big performance hit - which is especially ironic because it&#39;s for something that 99% of users won&#39;t even know about.</p><p style="margin-top: 0px; margin-bottom: 0px">&nbsp;</p><p style="margin-top: 0px; margin-bottom: 0px">Allotting time requires managerial approval. However, most managers see security as one of those &quot;nice-to-have&quot; buzzwords, that they&#39;ll have implemented later &quot;if time permits&quot;.</p><p style="margin-top: 0px; margin-bottom: 0px">I think a good solution to this is to <strong>give management a live demo of your site being hacked</strong> (perhaps try it on the QA machine, not necessarily production). To really make a point, see if you can hack into their profile. Hopefully that will convince management that it&#39;s worth the time.</p><p style="margin-top: 0px; margin-bottom: 0px">&nbsp;</p><p style="margin-top: 0px; margin-bottom: 0px">About the performance hit - I don&#39;t see a silver bullet. Most application performance can be improved by adding more resources somehow - more hardware, better design (caching, batching), coding optimizations, etc... Because applications vary so much, there&#39;s not a one-size-fits-all solution.</p>]]></description><category>security</category><category>aspnet</category></item><item><title>BOOK: Pragmatic Thinking and Learning: Refactor Your Wetware</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/book_pragmatic_thinking_and_learning_refactor_your_wetware.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/book_pragmatic_thinking_and_learning_refactor_your_wetware.htm</link><pubDate>Tue, 09 Jun 2009 21:04:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=book%5Fpragmatic%5Fthinking%5Fand%5Flearning%5Frefactor%5Fyour%5Fwetware</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>I&#39;m fascinated with learning how to learn, so I was excited to finally read Andy Hunt&#39;s <strong><a href="http://pragprog.com/titles/ahptl">Pragmatic Thinking and Learning: Refactor Your Wetware</a></strong>. Recall that Andy is one of the co-stars of the hit <a href="/good_book_the_pragmatic_programmers.htm" title="read entry">The Pragmatic Programmers</a>.</p><p>This is a good example of a higher-level, &quot;non-syntax&quot; book, something that transcends the &quot;How to program XYZ&quot; genre. (Shameless plug: I had written my own book: <a href="http://www.amazon.com/Crash-Course-Reasoning-Tim-Stall/dp/1435755979/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1243479087&amp;sr=1-1">A Crash Course in Reasoning</a>, but I can see why Andy&#39;s is in the top 3000 Amazon sales rank, and mine is barely in the top 3 million).</p><p>My favorite chapter was &quot;Journey from Novice to Expert&quot;, as there is such <a href="/what_is_the_difference_between_an_average_dev_and_a_star.htm">a huge productivity gap</a> here. He also continually emphasized the differences between the two parts of the brain, comparing it to a dual CPU, single master bus design.</p><p>It was an enjoyable read, similar to picking desserts out of a buffet. He had a lot of good quotes throughout the book:</p><ul><li>&quot;... software development must be the most difficult endeavor ever envisioned and practiced by humans.&quot; (pg. 1)</li><li>&quot;... it&#39;s not the teacher <em>teaches</em>; it&#39;s that the student <em>learns</em>.&quot; (pg. 3)</li><li>&quot;Don&#39;t succumb to the false authority of a tool or a model.&quot; (pg. 41)</li><li>&quot;If you don&#39;t keep track of great ideas, you will stop noticing that you have them.&quot; (pg. 53). This is huge. The &quot;slow times&quot; during the day (driving, waiting in line, burping a sleeping baby) are great for mulling over random ideas. It&#39;s almost like collecting raindrops. I used to do this, but got lazy the last few years. Andy&#39;s chapter inspired me to go out, get some pocket-sized notebooks, and start jotting down random thoughts again (read: future blog entries).</li><li>&quot;Try creating your next software design <em>away</em> from your keyboard and monitor...&quot; (pg. 72). It&#39;s ironic, but often sitting in front of the computer, with all the internet distractions, can kill one&#39;s creativity.</li><li>&quot;So if you aren&#39;t pair programming, you definitely need to stop every so often and <em>step away from the keyboard</em>.&quot; (pg. 85). I&#39;ve seen many shops that effectively forbid pair programming, so this at least is a way to partially salvage a bad situation.</li><li>&quot;... until recently, one could provide for one&#39;s family with minimal formal education or training.&quot; (pg. 146)</li><li>&quot;... relegating learning activities to your &#39;free time&#39; is a recipe for failure.&quot; (pg. 154)</li><li>&quot;... documenting is more important than <em>documentation</em>.&quot; (pg. 179). The act of documenting forces you to think through things, where design costs upfront are much cheaper than implementation costs later.</li><li>&quot;... we learn better by discovery, not instruction.&quot; (pg. 194).</li><li>&quot;It&#39;s not that we&#39;re out of time; we&#39;re out of attention.&quot; (pg. 211)</li></ul><p>Perhaps the best effect from reading this kind of book is that it makes you more aware, such that your subconscious mind is constantly thinking about learning.</p>]]></description><category>books</category><category>learning</category></item><item><title>Farewell Paylocity, Hello Career Education Corporation</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/farewell_paylocity_hello_career_education_corporation.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/farewell_paylocity_hello_career_education_corporation.htm</link><pubDate>Mon, 08 Jun 2009 19:08:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=farewell%5Fpaylocity%5Fhello%5Fcareer%5Feducation%5Fcorporation</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>I&#39;ve had the good fortune to serve at Paylocity the last four years. Inheriting a legacy system, I got the opportunity to develope, contribute to process, grow as an architect, and work with a very classy team. </p><p>For a variety of personal and professional reasons, I&#39;ll be switching to a new company soon - <strong><a href="http://www.careered.com/">Career Education Corporation</a></strong>. CEC has a noble mission - to help people with continuing education (something <a href="/tags/?/learning">I have a passion for</a>). They have both an online and brick &amp; mortar presence. It&#39;s an international company with several thousand employees, and a lot of opportunity. I&#39;m looking forward to this new chapter in life.</p>]]></description><category>misc</category></item><item><title>Why XLinq is awesome - the benefits</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/why_xlinq_is_awesome__the_benefits.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/why_xlinq_is_awesome__the_benefits.htm</link><pubDate>Fri, 05 Jun 2009 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=why%5Fxlinq%5Fis%5Fawesome%5F%5Fthe%5Fbenefits</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>I&#39;m a big fan of Xml, especially for internal tools and processes. In order to juggle xml, I&#39;d usually resort to XPath queries, the XmlDocument, and Xml Serializers. However, the new XLinq that came out with .Net 3.0, seems to completely overpower XPath for C# applications. It rocks.</p><p>You can see a <a href="http://msdn.microsoft.com/en-us/library/bb308960.aspx">general overview here</a>. I also found the Linq and Xlinq chapters from <a href="/book_c_30_in_a_nutshell.htm">C# 3.0 in a Nutshell</a> to be wonderful. <a href="/using_linq_to_sort_and_filter_entity_lists.htm">Linq alone is powerful</a>, and XLinq applies linq to xml. There are several specific benefits of XLinq that I want to highlight:</p><p><strong>Easy round-tripping from files or strings:</strong></p><span>XLinq makes it very easy to load or save files from either a string or uri.</span><span> <blockquote><p><font face="Courier New" size="2">[TestMethod]<br />public void Create_1()<br />{<br />&nbsp;&nbsp;//Load from string<br />&nbsp;&nbsp;XElement x1 = XElement.Parse(<br />&nbsp;&nbsp;&nbsp;&nbsp;@&quot;&lt;configuration&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;client enabled=&#39;true&#39;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;timeout&gt;30&lt;/timeout&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/client&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/configuration&gt;&quot;);<br /><br />&nbsp;&nbsp;//Load from uri<br />&nbsp;&nbsp;XElement x2 = XElement.Load(@&quot;C:\temp\x2.xml&quot;);<br /><br />&nbsp;&nbsp;//save to string<br />&nbsp;&nbsp;string s = x1.ToString();<br /><br />&nbsp;&nbsp;//save to file<br />&nbsp;&nbsp;x2.Save(@&quot;C:\temp\x2a.xml&quot;);<br />}</font></p></blockquote></span><p><strong>Easy DOM access and modification</strong></p><p>I recall with XmlDocument (at least how I understood it), nodes were tightly coupled to their original XmlDocument, so it could be a pain to pull out an xml snippet from one doc and insert it into another. With XLinq, you can pretty much juggle it any way - insert/update/remove either attributes, nodes, or inner text.</p><p><span><font face="Courier New" size="2">&nbsp;&nbsp;&nbsp; [TestMethod]<br />&nbsp;&nbsp;&nbsp; <span class="kwrd">public</span> <span class="kwrd">void</span> ModifyDom_1()<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="rem">//Load from string</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XElement x1 = XElement.Parse(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="str">@&quot;&lt;configuration&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;client enabled=&#39;true&#39; attr2=&#39;aaa&#39;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;timeout&gt;30&lt;/timeout&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/client&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/configuration&gt;&quot;</span>);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="rem">//Get a reference to a node:</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XElement xClient = x1.Element(<span class="str">&quot;client&quot;</span>);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="rem">//Modify DOM</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="rem">//&nbsp; Attribute - insert new</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xClient.SetAttributeValue(<span class="str">&quot;new1&quot;</span>, <span class="str">&quot;val1&quot;</span>);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="rem">//&nbsp; Attribute - update</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xClient.SetAttributeValue(<span class="str">&quot;enabled&quot;</span>, <span class="str">&quot;false&quot;</span>);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="rem">//&nbsp; Attribute - remove</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xClient.SetAttributeValue(<span class="str">&quot;attr2&quot;</span>, <span class="kwrd">null</span>);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="rem">//&nbsp; Node - insert new</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XElement xNew1 = XElement.Parse(<span class="str">&quot;&lt;newNode&gt;bbb&lt;/newNode&gt;&quot;</span>);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XElement xNew2 = XElement.Parse(<span class="str">&quot;&lt;newNode&gt;ccc&lt;/newNode&gt;&quot;</span>);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xClient.AddAfterSelf(xNew1);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xClient.AddAfterSelf(xNew2);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="rem">//&nbsp; Node - remove</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xNew2.Remove();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="rem">//&nbsp; InnerText - update</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xClient.Element(<span class="str">&quot;timeout&quot;</span>).Value = <span class="str">&quot;60&quot;</span>;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="rem">//save to string</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kwrd">string</span> s = x1.ToString();<br />&nbsp;&nbsp;&nbsp; }</font></span></p><p><strong>Populating objects from an XLinq Query:</strong></p><p><span>You can see a ton of gems in this snippet from the Chicago Code Camp website:</span></p><p>Say you have a class &quot;Abstract&quot; with properties AbstractCode, SpeakerCode, CoSpeakerCode, Author, Description, and Title.</p><p>There are two xml files - one for &quot;Abstracts&quot; and the other for &quot;Speakers&quot;</p><blockquote><p><font face="Courier New" size="2">&lt;Speakers&gt;<br />&nbsp;&nbsp;&lt;Speaker SpeakerCode=&quot;Homer_Simpson&quot;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&lt;Name&gt;Homer Simpson&lt;/Name&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&lt;Email&gt;homer@email.com&lt;/Email&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&lt;Bio&gt;Nuclear engineer...&lt;/Bio&gt;<br />&nbsp;&nbsp;&lt;/Speaker&gt;<br />&nbsp;&nbsp;...<br />&lt;/Speakers&gt;<br /><br /><br />&lt;Abstracts&gt;<br />&nbsp;&nbsp;&lt;Abstract AbstractCode=&quot;Nuclear_101&quot; SpeakerCode=Homer_Simpson&quot;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&lt;Title&gt;How to be a good employee&lt;/Title&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&lt;Description&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Eat donuts and sleep...<br />&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Description&gt;<br />&nbsp;&nbsp;&lt;/Abstract&gt;<br />&nbsp;&nbsp;...<br />&lt;/Abstracts&gt;</font></p></blockquote><p>The following XLinq snippet shows how to:</p><ol><li>Instantiate an array of Abstract objects from xml by mapping the node, attribute, and inner text values.</li><li>Filter the xml file by multiple expressions and complex logic</li><li>Join multiple xml files together, such as the Abstract and Speaker xml files via a common attribute (SpeakerCode)</li><li>Use external functions (LinqHelper.GetNonNull) in your XLinq query.</li><li>Apply transformations (.Replace() ) to the xml data you&#39;re reading</li><li>Order it all. </li></ol><p><span><font face="Courier New" size="2">&nbsp;&nbsp;&nbsp; XElement xeAbstracts = XElement.Load(<span class="str">&quot;Abstracts.xml&quot;</span>);<br />&nbsp;&nbsp;&nbsp; XElement xeSpeakers = XElement.Load(<span class="str">&quot;Speakers.xml&quot;</span>);<br /><br />&nbsp;&nbsp;&nbsp; Abstract[] abs =<br />&nbsp;&nbsp;&nbsp; (<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from a <span class="kwrd">in</span> xeAbstracts.Elements(<span class="str">&quot;Abstract&quot;</span>)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from s <span class="kwrd">in</span> xeSpeakers.Elements(<span class="str">&quot;Speaker&quot;</span>)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kwrd">where</span> <strong>a.Attribute(<span class="str">&quot;SpeakerCode&quot;</span>).Value <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; == s.Attribute(<span class="str">&quot;SpeakerCode&quot;</span>).Value</strong><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select <span class="kwrd">new</span> Abstract()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AbstractCode = a.Attribute(<span class="str">&quot;AbstractCode&quot;</span>).Value,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SpeakerCode = a.Attribute(<span class="str">&quot;SpeakerCode&quot;</span>).Value,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CoSpeakerCode = <strong>LinqHelper.GetNonNull</strong>(a.Attribute(<span class="str">&quot;CoSpeakerCode&quot;</span>)),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Author = s.Element(<span class="str">&quot;Name&quot;</span>).Value,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Description = a.Element(<span class="str">&quot;Description&quot;</span>).Value<strong>.Replace(<span class="str">&quot;\r\n&quot;</span>,<span class="str">&quot;&lt;br&gt;&quot;</span>)</strong>,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Title = a.Element(<span class="str">&quot;Title&quot;</span>).Value<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; ).OrderBy(n =&gt; n.Title).ToArray();</font></span></p><p>Many of these things would have been either difficult or impossible to do in XPath (unless I&#39;m missing some <em>major</em> trick).</p><p>This alone makes a very powerful case for XLinq.</p>]]></description><category>xml</category></item><item><title>Why would someone put business logic in a stored procedure?</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/why_would_someone_put_business_logic_in_a_stored_procedure.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/why_would_someone_put_business_logic_in_a_stored_procedure.htm</link><pubDate>Thu, 04 Jun 2009 12:18:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=why%5Fwould%5Fsomeone%5Fput%5Fbusiness%5Flogic%5Fin%5Fa%5Fstored%5Fprocedure</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>I have a strong bias against injecting <em>business</em> logic into the stored procedures. It is not scalable, is hard to reuse, is a pain to test, has limited access to your class libraries, etc... However, I think there are some legit cases to put advanced T-SQL in a SP, but you&#39;re playing with fire.</p><p>Here are some&nbsp;reasons - basically either performance, functionality, or legacy constraints force you to. </p><ol><li><strong>Aggregations, Joins, and Filters </strong>- If you need to sum up 1000 child rows, it&#39;s not feasible to return all that data to the app server and sum it in C#. Obviously using the SQL sum() function would be the better choice. Likewise, if your logic is part of a complex filter (say for a search page), it performs much faster to filter at the database and only pull over the data you need.</li><li><strong>Batch calls for performance</strong> - SQL Server is optimized for batch calls. A single update with a complex where clause will likely run much faster than 1000 individual updates with simple where clauses. For performance-critical reasons, this may force logic into the stored procedure. However, in this case, perhaps you can <a href="/tags/?/codegen">code-generate</a> the SQL scripts from some business-rules input file, so you&#39;re not writing tons of brittle SQL logic.</li><li><strong>Database integration validation</strong> - Say you need to ensure that code is unique across all rows in the table (or for a given filter criteria). This, by definition, must be done on the database.</li><li><strong>Make a change to legacy systems where you&#39;re forced into using the SP</strong> - Much of software engineering is <a href="/book_working_effectively_with_legacy_code.htm">working with legacy code</a>. Sometimes this forces you into no-win situations, like fixing some giant black box stored procedure. You don&#39;t have time to rewrite it, the proc requires a 1 line change to work how the client wants it, and making that change in the stored proc is the least of the evils. </li><li><strong>The application has no business tier</strong> - Perhaps this procedure is for a not for an N-tier app. For example, maybe it&#39;s for a custom report, and the reporting framework can only call stored procs directly, without any middle-tier manipulation.</li><li><strong>Performance critical code</strong> - Perhaps &quot;special&quot; code must be optimized for performance, as opposed to maintainability or development schedule. For example, you may have some rules engine that must perform, and being closer to the core data allows that. Of course, sometimes there may be ways to avoid this, such as caching the results, scaling out the database, refactoring the rules engine, or splitting it into CRUD methods that could be batched with an ORM mapping layer.</li><li><strong>Easy transactions</strong> - It can be far easier for a simple architecture to rollback a transaction in SQL than in managed code. This may press developers into dumping more logic into their procs.</li></ol><p>Note that for any of these reasons - consider at least still <a href="/massdatahandler_article_in_net_developers_journal.htm">testing your database logic</a>, and <a href="/refactoring_sql_code_with_file_includes_and_variables.htm">refactoring your SQL scripts</a>.</p><p>These &quot;reasons&quot; are probably a bad idea:</p><ol><li><strong>Easy deployment </strong>- You can update a SQL script in production real quick! Just hope that the update doesn&#39;t itself have an error which accidentally screws all your production data. Also consider, why does the procedure need to be updated out-of-cycle in the first place? Was it something that would ideally have been abstracted out to a proper config file (whose whole point is to provide easy changes post-deployment)? Was it an error in the original logic, which could have been more easily prevented if it had been coded in a testable-friendly language like C#? Also, keep in mind that you can re-deploy a .Net assembly if you match its credentials (strong name, version, etc...), which is very doable given an automated build process.</li><li><strong>It&#39;s so much quicker to develop this way!</strong> Initially it may be faster to type the keystrokes, but the lack of testability and reusability will make the schedule get <em>clobbered</em> during maintenance.</li></ol><p>In my personal experience, I see more data in the SP for the bad reasons (&quot;it&#39;s real quick!&quot;)- the majority of the time it can be refactored out, to the benefit of the application and its development schedule.</p>]]></description><category>sql</category></item><item><title>Chicago Code Camp - reflections</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/chicago_code_camp__reflections.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/chicago_code_camp__reflections.htm</link><pubDate>Tue, 02 Jun 2009 20:09:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=chicago%5Fcode%5Fcamp%5F%5Freflections</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>This weekend the LCNUG and Alt.Net groups hosted a very successful <a href="http://www.chicagocodecamp.com/">Chicago Code Camp</a> at the College of Lake County in IL. We had about 150 people, 30 speakers, and a lot of knowledge transfer. I was privileged to be part of the group that helped facilitate it. We&#39;re in the process of trying to put speaker ppts and code samples up on the website.</p><p>Some misc reflections:</p><p><strong>How did we make that massively awesome code camp website?</strong> We maintained it in ASP.Net, used xml files for the abstracts and speaker bios, and then had an automatic tool take <a href="/screen_scraping_the_easy_way_with_net.htm">screen scrapes</a> of all the generated aspx pages. This saved the results as html files, which could then easily be xcopy-deployed to any FTP server without worrying about a backend data store or server-side support.</p><p><strong>Did you have enough volunteers? I think in the end yes.</strong> People stepped up at the spur of the moment. I especially was impressed with how easy it was to move tables when you have 150 people. For lunch and cleanup, we needed to transport a lot of tables and boxes, and random people kept jumping in to help. What a great community!</p><p><strong>Sounds great, but too bad I missed it. </strong>While we hope to get the ppt&nbsp; slides up soon, also consider checking out the <a href="http://www.chicagocodecamp.com/SpeakerBios.html">blogs of the speakers</a>. Even if the blog isn&#39;t explicitly listed, you can probably find it by googling the speaker name and adding the &quot;.net&quot; or &quot;developer&quot; keyword to the search.</p><p><strong>What&#39;s next?</strong> Stay in touch with the Chicagoland community. Perhaps subscribe to some of the speaker blogs, or visit the LCNUG, ALT.Net, or any of the other user groups.</p><p>See also: <a href="/10_reasons_to_attend_the_chicago_code_camp.htm" class="blogtitle">10 Reasons to attend the Chicago Code Camp</a>, <a href="/chicago_code_camp_sessions_and_agenda_are_up.htm">Sessions up</a>.</p>]]></description><category>events</category></item><item><title>What is the difference between an average dev and a star?</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/what_is_the_difference_between_an_average_dev_and_a_star.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/what_is_the_difference_between_an_average_dev_and_a_star.htm</link><pubDate>Mon, 01 Jun 2009 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=what%5Fis%5Fthe%5Fdifference%5Fbetween%5Fan%5Faverage%5Fdev%5Fand%5Fa%5Fstar</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>Time and again, experience keeps re-affirming me that <a href="/why_are_the_good_devs_ten_times_faster_than_the_average_ones.htm">a star developer is far more productive</a> than several average developers combined. It begs the question - what is the difference between a novice, average, and star developer? The naive thinking is that they&#39;re all the same kind, but they just vary by degree - i.e. that the star produces more code at a faster rate, with less bugs. But there&#39;s so much more than that. The star developer is a fundamentally different kind. Here&#39;s a brain dump of some possible differences between star developers and average devs (This also relates to the Dreyfus model of skill acquisition: <a href="http://en.wikipedia.org/wiki/Dreyfus_model_of_skill_acquisition">http://en.wikipedia.org/wiki/Dreyfus_model_of_skill_acquisition</a>).</p><p>A star developer:</p><ol><li>Mitigates risk</li><li>Writes higher quality code</li><li>Predicts potential problems, and not design the app into a corner</li><li>Addresses performance, security, maintenance</li><li>Makes their teammates better</li><li>Comes up to speed quicker</li><li>Juggles multiple projects</li><li>Troubleshoots and <a href="/what_to_do_before_just_asking_someone.htm">figures out answers themselves</a></li><li>Does self correction</li><li>Handles non-technical constraints (like a political monkey wrench)</li><li><a href="/book_software_estimation_demystifying_the_black_ar.htm">Can provide reliable estimates</a></li><li>Interfaces with non-technical folks (Managers, Business Sponsors); understands the business side</li><li>Throws away bad code; knows when to restart</li><li>Creates reusable code that helps others</li><li>Has influence beyond their immediate project</li><li>Desires to grow</li><li>Can work for longer periods without immediate and visible success</li><li>Can compress the schedule, <a href="/what_would_it_take_to_be_twice_as_productive.htm">such as doubling productivity</a>.</li><li>Can coordinate other developers, even informally and not as a tech lead.</li><li>Can set up and improve process</li><li>Understands the concepts beyond syntax. Average devs crash when the technical road takes a curve with a new language; stars know the concepts and don&#39;t get thrown for a loop.</li><li>Knows when the rules do not apply</li><li>Knows where they want to go; can describe their career path.</li><li>Is continually learning and improving.</li><li>Can point to star developers and industry leads. If you&#39;re developing ASP.Net, and you&#39;ve never even heard of <a href="http://weblogs.asp.net/scottgu/">Scott Guthrie</a>, you&#39;re probably <em>not</em> a star.</li></ol><p>Note that stars does not necessarily:</p><ul><li>Be perfect at everything. We all have some sort of limitations.</li><li>Write perfect code --&gt; we all make mistakes</li><li><a href="/hiring_based_off_years_of_experience_an_analogy_with_art_an.htm">Have N years of experience</a></li><li>Have external metrics (a <a href="/certification_pro_vs_con.htm">degree or certification</a>, a fancy title, got lucky with a well-paying project, etc...)</li></ul><p>As a completely miscellaneous aside, I think of a real-time-strategy game like <a href="/10_rules_that_age_of_empires_teaches_about_development.htm">Age of Empires</a> - what is the difference between an average unit and a star unit? Look at an average unit like a simple solder - it has basic properties like health points, attack, and movement. While merely upgrading the strength of these properties (more health, more attack, etc...) is great, it is still fundamentally missing other powerful aspects- the ability to heal itself, a ranged attack, the ability to swim (or fly!), the ability to collect resources or create buildings, etc... For example, a thousand normal AoE soldiers - which have zero ranged attack, and cannot swim - will never be able to hit an enemy across even a 1-block wide river.</p>]]></description><category>learning</category></item><item><title>BOOK: Software Estimation: Demystifying the Black Art</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/book_software_estimation_demystifying_the_black_ar.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/book_software_estimation_demystifying_the_black_ar.htm</link><pubDate>Fri, 29 May 2009 13:43:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=book%5Fsoftware%5Festimation%5Fdemystifying%5Fthe%5Fblack%5Far</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>I personally have never met a developer who liked giving estimates. Indeed, it&#39;s an uphill battle. It&#39;s not just that developers don&#39;t like working on things which don&#39;t compile. It&#39;s also that amidst endless ambiguity, changing scope, and technical challenges, some boss pressures you into a specific date when a non-specific feature will be fully complete (with no bugs, of course). However, every aspiring tech lead must eventually fight this battle. Because software estimation is perceived as a &quot;soft science&quot;, it&#39;s easy for devs to view it as some necessary tax to tolerate in order to get to the &quot;real&quot; work of coding. Therefore, many devs never try to improve their estimating skills, and hence there are a lot of <a href="/bad_estimate_trick__playing_people_off_of_each_other.htm">bad techniques</a> out there.</p><p>That&#39;s why I&#39;m glad that superstar Steve McConnell dumped his wisdom into <a href="http://www.amazon.com/Software-Estimation-Demystifying-Practices-Microsoft/dp/0735605351/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1243475169&amp;sr=8-1">Software Estimation: Demystifying the Black Art</a>. The book is filled with gems. Here are some of the key tips that I found practical:</p><ul><li>&quot;Distinguish between estimates, targets, and commitments&quot;.</li><li>Once you&#39;ve given an estimate and schedule, <em>control</em> the project so that you meet the estimate (reduce scope, juggle staff, prioritize features, etc...). The schedule is not like a basketball that you toss in the air and hope that it makes the shot - rather it&#39;s like a football that you personally carry to the end zone.</li><li>&quot;We are conditioned to believe that estimates expressed as narrow ranges are more accurate than estimates expressed as wider ranges.&quot; (pg. 18)</li><li>Steve emphasizes the &quot;Cone of Uncertainty&quot; - namely that initially, the project has many unknowns, and hence the estimate has a much larger range. However, as the project progresses and more issues become known, the range shrinks. Ironically, it is at the beginner of the project (where everything is most unknown), that many bosses want a stable, singular, estimate. Consider using phase-specific estimation techniques for different stages of the project - some techniques work better at the begininng with higher uncertainty, others work better near the end. Also, within the same project phase, consider using multiple estimation techniques to detect for converging (and hence more reliable) estimates.</li><li>Always have the people who do the implementation work also provide the estimates.</li><li>Sometimes, you can use group estimates. However, each developer should come up with their estimates separately, else the dominant person in the group will likely overly-influence everyone else (especially because most devs tend to be introverts). If their estimates differ greatly, then discuss why they&#39;re different, and iteratively keep re-estimating until they converge.</li><li>Collect historical data for past projects, which you can then use to assist with future estimates.</li><li>Count, Compute, Judge. If you can simply count the size somehow (lines of code, modules, etc...) - then that&#39;s best. If you cannot directly count, consider computing from things you can count. The point is you always want to avoid subjective judgments when there&#39;s a more objective alternative.</li><li>Try to estimate based off of objective quantities like historical data and lines of code, as opposed to subjective measurements like developer quality. The boss will heckle the subjective measurements: &quot;Your estimate assumes only average developers, but we&#39;re paying for senior devs, so re-calculate with senior devs. Great, that saved us 1 month.&quot;</li><li>When the boss doesn&#39;t like the estimate, change inputs, NOT outputs. For example, don&#39;t just shave a month off your 5-month estimate because your boss will now be more receptive, rather change the inputs (such as reduce features) so that recalculating the estimate now results in 4 months.</li><li>Establish a standard estimation procedure for your department. By following an objective set of steps, you (the estimator) have a level of &quot;protection&quot; from all the business sponsors who want a lower estimate. For example, you might say &quot;Our standard procedure, which historically returns estimates within a 20% accuracy, always adds 15% risk buffer for this type of application.&quot; Then you aren&#39;t the &quot;bad guy&quot; for adding the &quot;extra&quot; 15% (funny how anything that increases an estimate is seen as &quot;extra&quot;, not &quot;striving for accuracy&quot;).</li><li>When presenting your estimates (and schedules), don&#39;t even bother presenting nearly impossible scenarios. The boss will just assume that you&#39;ll be lucky and of course hit the most optimistic number that is mentioned.</li><li>Always give an honest estimate. Don&#39;t lowball the estimate just so that you&#39;re boss accepts it - doing so will screw you with an impossible schedule, which will also destroy your credibility (&quot;you can&#39;t even hit your own estimate!&quot;) If an honest estimate is too high, it is the business sponsor&#39;s decision to reject the project, not the developers.</li></ul><p>Lastly, consider checking out <a href="http://www.construx.com/Page.aspx?nid=68">Construx Estimate</a>.</p>]]></description><category>books</category><category>management</category></item><item><title>Tips to refactor Asp.Net codebehinds to a common base page.</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/tips_to_refactor_aspnet_codebehinds_to_a_common_base_page.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/tips_to_refactor_aspnet_codebehinds_to_a_common_base_page.htm</link><pubDate>Mon, 18 May 2009 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=tips%5Fto%5Frefactor%5Faspnet%5Fcodebehinds%5Fto%5Fa%5Fcommon%5Fbase%5Fpage</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>In Asp.Net, it is common to have the aspx page inherit from a custom page as opposed to directly from System.Web.UI.Page. Usually the application architecture has at least one common &quot;base page&quot; that handles core architectural components. However, you may find that for larger apps, you want to extend your base-page hierarchy such that an entire sub system gets its own base page (which in turn inherits from the global base page). While inheritance with normal C# classes (like in a ClassLibrary project) works great, there are some common hurdles when trying to refactor to a base page in ASP.Net codeBehinds.</p><p>Perhaps the biggest issue is the dependencies, namely:</p><ol><li>Your base page cannot directly reference any user controls. Assuming you put the page page in the AppCode folder, this gets compiled to its own separate DLL, and that DLL has no reference to the UC dll (however, the UC has a reference to AppCode).</li><li>Your base page cannot directly reference the html controls instantiated in the derived-page&#39;s aspx file. For example, if your derived aspx page contains a hidden field or textbox, your base page cannot reference that.</li></ol><p>There are ways to <a href="/book_working_effectively_with_legacy_code.htm">break these dependencies</a>.</p><p><strong>For problem #1 with the User Control references</strong>, you can make an interface, have that user control implement the interface, and then let the base page have a member variable of the interface type. The derived page could populate that variable. In other words:</p><ul><li>Say you have UserControl &quot;Address&quot;.</li><li>Your base page needs to call the &quot;LookupZipCode&quot; method</li><li>Create an interface IAddress with member &quot;LookupZipCode&quot;. Have the UC implement this interface.</li><li>Have your base page contain an instance field of type IAddress. Your base page can then call this.</li><li>Have the derived page pass the UC reference to the base page (perhaps in the OnInit method), for example&nbsp;set base.IAddress = MyUserControl.</li></ul><p>Another approach, say if you&#39;re casting, is to pass in a <a href="/using_generics_for_dynamic_return_type_and_validation.htm">generic</a>. For example, create this kind of method in your base page: Note that &quot;T&#39; would be a user control, but your base page cannot reference user controls.</p><blockquote><p>public T HeaderControl&lt;<strong>T</strong>&gt;() where T : class<br />{<br />&nbsp;&nbsp;&nbsp; return this.Master.FindControl(&quot;Header&quot;) as <strong>T</strong>;<br />}</p></blockquote><p><strong>For problem #2, with html control references</strong>, you could solve this in several ways. Keep in mind that unlike user controls, Html (or WebControls) are predefined in an external assembly - System.Web - and can hence be referenced in the base page. So the question becomes how to pass the reference from the derived to the base class? </p><ul><li>Pass in references via method signature - for example the method that sets a hidden control expects an HtmlInputHidden parameter, as opposed to referencing &quot;this.MyHiddenControl&quot;.</li><li>Make the base class have its own separate protected instance, and have the derived class set this (such as in the derived class&#39;s OnInit). For example, the derived class OnInit method may contain a line like &quot;base.BaseHiddenField = thisMyHiddenField&quot;. This is useful if that control is referenced in many base-class methods, and you don&#39;t want to update all the signatures.</li><li>FindControl - You can always use the &quot;Page.FindControl(string)&quot; method to get a control given the string ID, but this is brittle and slower. Because you pass in a string, you don&#39;t get compile-time type checking. It also must search the entire control collection instead of just having a direct reference to the control.</li></ul><p>While there&#39;s a lot more ways to refactor an ASP.net codeBehind, these two tricks are useful.</p>]]></description><category>aspnet</category></item><item><title>10 Reasons to attend the Chicago Code Camp</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/10_reasons_to_attend_the_chicago_code_camp.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/10_reasons_to_attend_the_chicago_code_camp.htm</link><pubDate>Fri, 15 May 2009 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=10%5Freasons%5Fto%5Fattend%5Fthe%5Fchicago%5Fcode%5Fcamp</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>The LCNUG and Alt.Net groups are hosting a <strong><a href="http://www.chicagocodecamp.com/">Chicago Code Camp</a></strong> on Saturday, May 30th, at College of Lake County (CLC) in the Northwest suburbs. If you&#39;re a passionate developer looking to grow, this is exactly the kind of event you want to consider.</p><ol><li><a href="http://www.chicagocodecamp.com/Sessions.html">33 cutting-edge sessions</a> across a wide spectrum of topics and developer communities.</li><li>Presentations by <a href="http://www.chicagocodecamp.com/SpeakerBios.html">industry leaders</a>, MVPs, experiences developers, and tech leads.</li><li>Networks with perhaps 200 local developers, which always results in great discussions with your peers.</li><li>It&#39;s free!</li><li>Tons of swag.</li><li>Get to ask face-to-face questions with real experts.</li><li><a href="http://www.chicagocodecamp.com/Agenda.html">A full day of sessions</a> - so don&#39;t skip out just because you can only make the morning or afternoon.</li><li>See what new technologies could add value to your development projects.</li><li>Lots of hands-on code, not just fluffy power points about ivory tower theories.</li><li>You will be a better developer for having gone.</li></ol><p>We&#39;re also <a href="http://www.chicagocodecamp.com/VolunteerInfo.html">looking for volunteers</a>. Consider helping out, it&#39;s a great way to get involved.</p>]]></description><category>events</category></item><item><title>Troubleshooting Visual Studio Profiler with ASP.Net</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/troubleshooting_visual_studio_profiler_with_aspnet.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/troubleshooting_visual_studio_profiler_with_aspnet.htm</link><pubDate>Thu, 14 May 2009 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=troubleshooting%5Fvisual%5Fstudio%5Fprofiler%5Fwith%5Faspnet</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>Visual Studio 2008 (and I think 2005) come with a built-in .Net profiler. Profilers are especially useful for troubleshooting performance bottlenecks (Related: <a href="/using_the_clr_profiler.htm">CLR Profiler</a> for old versions of Visual Studio; <a href="/sql_tools__profiler_and_sqlcommand.htm">SQL Profiler</a>). There are already <a href="http://msdn.microsoft.com/en-us/magazine/cc337887.aspx">good tutorials</a> on it, so here I&#39;m just offering misc tips and troubleshooting. Basically, you can go to Analyze &gt; &quot;Launch Performance Wizard&quot;, and just select all the defaults. You can use this with ASP.Net web projects too.</p><p><strong>Error: When trying to start, I got &quot;Value does not fall within the expected range&quot;. </strong></p><p>Solution: You can <a href="http://blogs.msdn.com/profiler/archive/2008/08/22/vs2008-sp1-website-profiling-bug-and-workaround.aspx">set the config of a website</a> to &quot;Any CPU&quot;.</p><p><strong>Error: VSP1351 : The monitor was unable to create one of its global objects </strong></p><p>Other times I got this error:</p><blockquote><p><font face="Courier New" size="2">Error VSP1351 : The monitor was unable to create one of its global objects (Local.vsperf.Admin). Verify that another monitor is not running, or that another application hasn&#39;t created an object of the same name.<br />Profiler exited<br />PRF0010: Launch Aborted - Unable to start vsperfmon.exe</font></p></blockquote><p>Solution: You can use Process Explorer to see <a href="http://social.msdn.microsoft.com/Forums/en-US/vstsprofiler/thread/7e2ecf02-435a-4913-8576-9ce4035de4d7">what is locking</a> &quot;vsperf.Admin&quot;, and then kill that process tree. For me, it was the aspnet_wp.exe process.</p><p><strong>Error: PRF0010: Launch Aborted - Unable to start vsperfmon.exe</strong></p><p>Sometimes I got this error:</p><blockquote><p><font face="Courier New" size="2">PRF0010: Launch Aborted - Unable to start vsperfmon.exe<br />Error VSP1342 : Another instance of the Logger Engine is currently running.<br />Profiler exited</font></p></blockquote><p>Solution: I restarted Visual Studio (yes, it&#39;s lame, but it appeared to work). I also ensured that all other instances of VS were closed.</p><p><strong>Error: Sometimes clicking the stop button caused IE and VS to crash, without even collecting data</strong></p><p>Solution: By just closing the IE browser directly, it worked.</p>]]></description><category>process</category><category>tools</category><category>visual_studio</category></item><item><title>Automated Code Governance</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/automated_code_governance.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/automated_code_governance.htm</link><pubDate>Wed, 13 May 2009 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=automated%5Fcode%5Fgovernance</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>There are lots of ways for a tech-lead to <a href="/how_to_encourage_standardization.htm">encourage standardization</a>. However, any policy that requires manual enforcement will continually be facing an uphill battle. The problem with the human enforcer is that:</p><ol><li>Enforcing policy is seen as being the &quot;bad guy&quot;, and no-one wants to always be the bad guy</li><li>The human will not have time - they&#39;ll be pulled onto other features</li><li>The human will be accused of &quot;ivory tower&quot; antics that just slows down real work</li><li>The human cannot possibly monitor everyone&#39;s code every day</li></ol><p>The optimal way is to have an automated build policy as part of your continuous integration. This policy could check for many objective metrics, such as (DISCLAIMER: I haven&#39;t personally implemented all of these yet - it&#39;s just a brainstorm based on various research):</p><ul><li><strong><a href="/automating_code_coverage_from_the_command_line.htm">Code Coverage</a></strong> - Enforces developers to write unit tests by demanding that the tests provide X code coverage.</li><li><strong><a href="/cool_tool__ndepend_for_automated_code_metrics.htm">Code metrics</a></strong> (like NDepend) - Runs static metrics like LineCount (discourages large methods that have multiple responsibilities) and cyclomatic code complexity (including checks for dependencies, which is often then #1 culprit that prevents testability).</li><li><strong><a href="http://www.redhillconsulting.com.au/products/simian/">Code duplication</a></strong> (like Simian) - Encourages refactoring by checking for chunks of duplicate code. Ideally, this covers not just C#, but all languages like HTML, JS, and <a href="/refactoring_sql_code_with_file_includes_and_variables.htm">SQL</a>.</li><li><strong><a href="http://msdn.microsoft.com/en-us/library/bb429476.aspx">Static code analysis</a> </strong>(like FxCop) - Runs static rules to check for bad or risky code, kind of like compiler warnings on steroids.</li><li><strong>Stored Procedure scans</strong> - Creates a test database, and runs all the stored procs to check their query execution plan for performance bottlenecks (like table or index scans), or too many dependencies.</li></ul><p>While policies sound cool, in the trenches, many devs view them as just a nuisance that slows down &quot;real&quot; work. Here are some problems to anticipate:</p><ul><li>Devs don&#39;t want to do it - it&#39;s not fun to write high-quality code. </li><li>Devs complaining that they don&#39;t have time</li><li>Management pulling the rug out from under you (they don&#39;t have time, or they don&#39;t want to be the &quot;bad&quot; guy)</li><li>Makes build take too long</li></ul><p>Given these types of problems, here are ideas to minimize any riots as you try to roll these out.</p><ul><li>Set up policy first - without it failing the build yet, so everyone can see results for a few weeks.</li><li>Ensure that people can run all policy checks locally first, and verify that they pass locally.</li><li>Create an exclude list so any developer can register exceptions.</li><li>Grandfather all existing code by using this exclude list.</li><li>Minimize the scope of what is checked (start with just 1 core assembly, and gradually expand to others).</li><li>Roll out 1 policy at a time.</li><li>Ramp up your build servers. Consider a distributed build, such as using <a href="http://confluence.public.thoughtworks.org/display/CCNET/Project+Trigger">CruiseControl&#39;s project trigger</a> feature.</li></ul>]]></description><category>architecture</category></item><item><title>Avoiding unnecessary server work in ASP.Net</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/avoiding_unnecessary_server_work_in_aspnet.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/avoiding_unnecessary_server_work_in_aspnet.htm</link><pubDate>Tue, 12 May 2009 12:22:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=avoiding%5Funnecessary%5Fserver%5Fwork%5Fin%5Faspnet</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>One of the best ways to increase performance in ASP.Net pages is to not do any unnecessary server-side work. For example, every postback and callback will re-trigger the entire Page&#39;s server life cycle - rerunning OnInit, OnLoad, OnPreRender, etc... However, a server-side action only require a fraction of the original code to run - for example clicking a button may not require you to repopulate all dropdowns. </p><table border="1" cellpadding="2" width="100%" height="142" style="border-collapse: collapse" bordercolor="#111111"><tbody><tr><td width="26%" height="19" bgcolor="#c0c0c0"><strong>Concept</strong></td><td width="43%" height="19" bgcolor="#c0c0c0"><strong>Example</strong></td><td width="81%" height="19" bgcolor="#c0c0c0"><strong>Details</strong></td></tr><tr><td width="26%" height="19">Is Postback</td><td width="43%" height="19">Clicking an ASP.Net button postbacks the page</td><td width="81%" height="19">this.IsPostBack</td></tr><tr><td width="26%" height="19">Is Callback</td><td width="43%" height="19">A JavaScript triggers an ASP.Net 2.0 callback</td><td width="81%" height="19">this.IsCallback</td></tr><tr><td width="26%" height="19">Is Redirecting</td><td width="43%" height="19">A method has called Response.Redirect, but there is still heavy processing (that is now unnecessary) that will still be called.</td><td width="81%" height="19">Response.IsRequestBeingRedirected</td></tr><tr><td width="26%" height="19">Is Ajax update panel postback</td><td width="43%" height="19">A button within an Ajax update panel has been clicked, but don&#39;t redo server work outside of that update panel</td><td width="81%" height="19">public static bool IsPartialPostback(System.Web.UI.Page p)<br />{<br />return ((System.Web.UI.ScriptManager.GetCurrent(p) != null) <br />&amp;&amp; (System.Web.UI.ScriptManager.GetCurrent(p).IsInAsyncPostBack))<br />}</td></tr><tr><td width="26%" height="18">Is Button click</td><td width="43%" height="18">User clicks exit button - no need to repopulate dropdowns</td><td width="81%" height="18">Request[&quot;__EVENTTARGET&quot;] //indicates which event (like a button) triggered the postback.</td></tr></tbody></table><p>&nbsp;</p>]]></description><category>aspnet</category></item><item><title>Yes-no questions that a non-technical recruiter can ask during an interview</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/yesno_questions_that_a_nontechnical_recruiter_can_ask_duri.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/yesno_questions_that_a_nontechnical_recruiter_can_ask_duri.htm</link><pubDate>Mon, 11 May 2009 14:40:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=yesno%5Fquestions%5Fthat%5Fa%5Fnontechnical%5Frecruiter%5Fcan%5Fask%5Fduri</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>When interviewing, many companies first filter developers through HR (such as for online resume screening or a phone call). The irony is that they want a technical star, but screen all candidates through <a href="/what_if_im_a_nontechnical_person_doing_technical_recruitin.htm">non-technical HR folk</a>. Sometimes people in such situations, pressed for time, resort to quick yes-no questions. The <a href="/hiring_based_off_years_of_experience_an_analogy_with_art_an.htm">naive approach</a> is to just ask &quot;rate yourself on 1-10&quot;, or &quot;do you have over X years experience?&quot; While I think the best type of interview is one where technical people can ask technical questions (or even <a href="/why_you_need_to_be_able_to_write_code_on_a_whiteboard.htm">write pseudo-code on the whiteboard</a>), not every developer gets that opportunity. So if for whatever reason, the recruiter is limited to only yes-no questions, consider these kind of questions:</p><ol><li>Do you program in your spare time? --&gt; programming in your spare time implies that you enjoy programming, which implies that you&#39;re motivated and good at it.</li><li>Do you have any Microsoft Certifications? --&gt; implies basic <em>Microsoft-specific</em> education</li><li>Do you have an engineering or CS degree? --&gt; implies a basic <em>general</em> education</li><li>Have you ever lead a team of over 3 people? --&gt; implies basic leadership abilities.</li><li>Have you ever programmed an application over X thousand lines-of-code? --&gt; big apps will provide scalability and process problems that small apps never will.</li><li>Are you an active member of any professional groups? --&gt; implies motivation</li><li>Have you ever been published (magazine, online journal, book)? --&gt; implies good communication</li><li>Do you have your own website or blog? --&gt; implies personal motivation and innovation</li><li>Do you contribute to any open-source projects? --&gt; implies hands-on coding and working with others</li><li>Since college, have you read more than three <a href="/why_i_still_read_technical_books.htm">technical books</a>? --&gt; implies continual, pro-active education, as opposed to just <a href="/a_reactive_learner_is_also_a_reactive_problem_solver.htm">re-actively</a> reading scattered blog posts.</li></ol><p>This is only a partial list, but you get the idea. Many developers can have &quot;X years experience&quot;, yet never do a single thing on this list. This list focuses on what you have <em>done</em>, not how long you&#39;ve sat in front of a computer.</p>]]></description><category>recruiting</category></item><item><title>Technical Debt is like a steep hill, not a brick wall</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/technical_debt_is_like_a_steep_hill_not_a_brick_wall.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/technical_debt_is_like_a_steep_hill_not_a_brick_wall.htm</link><pubDate>Fri, 08 May 2009 14:21:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=technical%5Fdebt%5Fis%5Flike%5Fa%5Fsteep%5Fhill%5Fnot%5Fa%5Fbrick%5Fwall</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>Overtime, bad software decisions (design, coding, process) get compounded, like interest on a loan, and effectively presents the team with a &quot;<a href="http://martinfowler.com/bliki/TechnicalDebt.html">technical debt</a>&quot; that yearns to be repaid. This debt weighs down the system, making it harder and harder to make changes or add new features. One way to measure technical debt is by lines of code that require maintenance. Therefore you can reduce debt by reducing lines of code (codeGen, refactor, automate, buy instead of build, etc...).</p><p>For example, a developer may copy and paste duplicate code a hundred times (like in HTML or SQL), or create thousands of lines of tedious plumbing code, or create an army of brittle JavaScript files, or write an entire app with no code coverage. Many of the best practices out there are designed to explicitly reduce technical debt.</p><p>One thing to note is that technical debt is like a steep hill that can go infinitely high. You can go fast bicycling on a flat road, but as that road turns into a steep hill that gets gradually steeper, you slow down. In software terms, because code may have been copied to 10 different places, making a single change requires 10 separate updates - so it takes longer.</p><p>I don&#39;t think technical debt is like a brick wall - where suddenly at a specific point you&#39;re blocked and you simply cannot go further. And that&#39;s part of the problem. As long as you&#39;re moving, albeit slower and slower, it&#39;s seductive to think that you can still keep making &quot;enough&quot; progress so you don&#39;t need to change yet. The stubborn leader can just keep pushing on: &quot;longer hours, more developers...&quot; There are two choices to make: keep going forward, or turn around. However, if you were to hit that brick wall, then it forces you to stop and reevaluate. It&#39;s easier in the sense that you now only have one choice - you must &quot;turn around&quot;.</p>]]></description><category>process</category></item><item><title>Cool Tool - NDepend for automated code metrics</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/cool_tool__ndepend_for_automated_code_metrics.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/cool_tool__ndepend_for_automated_code_metrics.htm</link><pubDate>Tue, 05 May 2009 13:06:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=cool%5Ftool%5F%5Fndepend%5Ffor%5Fautomated%5Fcode%5Fmetrics</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>Given human nature, and all the tedious things that go into coding, the <a href="/how_to_encourage_standardization.htm">coding standards</a> that survive are usually the ones that you can automate with some external tool. </p><p>Code Metrics is one such type of governance. Two of the most popular metrics are line count and cyclomatic complexity. Perhaps <em>the</em> best tool on the market to assist with these (and much more) is <a href="http://www.ndepend.com/"><strong>NDepend</strong></a>.</p><p>For example, say you want to prevent developers from writing huge methods, or huge files. You could use the <a href="http://www.ndepend.com/NDependConsole.aspx">command line for NDepend</a> to check for method-line-count, and then fail any check-in that doesn&#39;t meet this policy - just like you could fail a check-in that doesn&#39;t compile or breaks a unit test.</p><p><a href="http://www.ndepend.com/Metrics.aspx#CC">Cyclomatic code complexity</a> is another one - this (to simplify it) measures the number of dependencies. The more dependencies, the harder to instantiate something in a test harness, so this is actually a big deal. You could reduce dependencies by leveraging interfaces and abstract classes, using injections, or the like (<a href="/book_working_effectively_with_legacy_code.htm">whole books</a> are written about this).</p><p>This is just the tip of the iceberg. NDepend has <a href="http://www.ndepend.com/Metrics.aspx">dozens of these types of metrics</a>.</p><p>Initially I tried to use Visual Studio&#39;s &quot;code metrics&quot; feature, but for some reason I cannot fathom, you cannot run it from the command line - which of course makes it useless for an automated build (which is the whole point). At least VS code coverage had <a href="/automating_code_coverage_from_the_command_line.htm">undocumented techniques</a> to work around this.</p><p>I realize there are open-source options for basic file line count, but I personally haven&#39;t come across any that can effectively do the other metrics like method line count and cyclomatic complexity.</p><p>Bottom line - if you&#39;re trying to enforce automated governance through your build, consider checking out NDepend. Yes, there&#39;s a license fee, but if it saves you even 10 hours by preventing issues and bad design, then it&#39;s paid for itself. Also, being aware of these types of metrics is the kind of thing that helps take a developer to the next level.</p><p>[Disclaimer - I haven&#39;t fully implemented this myself yet, it&#39;s still in a research phase, and I&#39;m just sharing my findings]</p>]]></description><category>tools</category></item><item><title>Chicago Code Camp sessions and agenda are up</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/chicago_code_camp_sessions_and_agenda_are_up.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/chicago_code_camp_sessions_and_agenda_are_up.htm</link><pubDate>Mon, 04 May 2009 13:45:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=chicago%5Fcode%5Fcamp%5Fsessions%5Fand%5Fagenda%5Fare%5Fup</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>The Chicago Code Camp (at CLC in Grays Lake, IL), which will be May 30 (Saturday), has the speakers, sessions, and agenda up.</p><p>It&#39;s all all-star cast, including several MVPs.</p><ul><li><a href="http://www.chicagocodecamp.com/Sessions.html">Sessions</a></li><li><a href="http://www.chicagocodecamp.com/SpeakerBios.html">Speakers</a></li><li><a href="http://www.chicagocodecamp.com/Agenda.html">Agenda</a></li></ul><p>There&#39;s a huge variety, including TDD everything (even TDD for JavaScript and the iPhone!), UI, backend, many non-.Net platforms, and much more!</p>]]></description><category>events</category></item><item><title>Management decisions for good developer cost-benefit ratios</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/management_decisions_for_good_developer_costbenefit_ratios.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/management_decisions_for_good_developer_costbenefit_ratios.htm</link><pubDate>Thu, 30 Apr 2009 13:41:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=management%5Fdecisions%5Ffor%5Fgood%5Fdeveloper%5Fcostbenefit%5Fratios</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>I&#39;ve often seen development groups (or their managers) dismiss a good idea with &quot;we can&#39;t afford it.&quot; The irony is that the group is already &quot;affording&quot; other expenses - developer salaries, MSDN licenses, hardware, and office space - so the question really becomes not &quot;are there funds&quot;, but rather &quot;what is the best way to spend our funds&quot;. There are at least three common examples where, for some reason, many managers shun the best cost-benefit ratio.</p><p><strong>Problem 1: &quot;We cannot afford a star developer - let&#39;s get two average developers instead.&quot;</strong></p><p>The irony is that <a href="/why_are_the_good_devs_ten_times_faster_than_the_average_ones.htm">one star developer</a> is far more profitable than two average developers. The star will build complex things that a dozen average developers will never be able to dream of. The star will write more solid code that spares you costly production errors. The star will solve the same problems faster by leveraging advanced techniques (like code generation, refactoring, or just elegant solutions). So, if you&#39;re creating a team of more than 10 developers, exchanging the bottom two spots for 1 star is a good investment. <a href="http://www.thoughtworks.com/">ThoughtWorks</a>, a world-class consulting firm, does a good job of demonstrating the profitability of this business model.</p><p><strong>Problem 2: &quot;We cannot afford that tool - just do it another way instead.&quot;</strong></p><p>Say you spend somewhere between $70K-$120K on an average developer (not just salary, but benefits, payroll taxes, etc...).&nbsp; Let&#39;s use $100K for easy numbers. At 50 work-weeks (assume 2 weeks of vacation), that&#39;s $2000 a week to pay for a developer - i.e. $50 an hour. So, a $50 tool that saves your developer <em>one hour a year</em> is a break-even investment.</p><p>Now about the &quot;power tools&quot; out there - like <a href="http://www.codesmithtools.com/">CodeSmith</a> (for code generation), or <a href="http://www.jetbrains.com/resharper/">ReSharper</a> (for refactoring), or <a href="http://www.redhillconsulting.com.au/products/simian/">Simian</a> (for detecting code duplication), or <a href="http://www.ndepend.com/">NDepend</a> (for code metrics) - say it&#39;s a few hundred per tool (i.e. less than 0.5% of your developer labor cost). However, a tool like CodeSmith fundamentally <a href="/things_to_codegenerate_besides_the_data_access_layer.htm">changes the rules of the game</a>, and can save a development <em>team</em> hundreds of hours. Sure, you can try to find open-source alternatives to each of these, and if you find something that fills the niche you need - great. A similar problem applies to hardware (where&#39;s there&#39;s not an open-source alternative)- for example when management &quot;saves&quot; $200 by not providing sufficient memory on a laptop, such that every hour of coding is sluggish due to a slow machine. </p><p>For many groups, a manager refusing to fund this kind of software engineering &quot;equipment&quot; (sounds classier than just &quot;tools&quot;), is like telling a construction worker to dig a trench - but we can&#39;t afford a $20 shovel, so use this spoon instead. Again, if a company is creating a 5 person development team, better to have only four people, but funded with the right equipment, then five developers who need to dig with spoons.</p><p><strong>Problem 3: &quot;We cannot afford that book - just see if you can figure it out from free, online tutorials.&quot;</strong></p><p>Of course everyone knows that <a href="/does_your_team_culture_encourage_learning.htm">continuing education</a> is vital in software engineering. In the manager&#39;s perfect world, they have a team of self-motivated developers who study on their own time, paying for their own materials, and learning at their own expense. And then, the manager (who has contributed nothing) gets to benefit from having all these learned developers. While yes, a developer is ultimately responsible for their own learning and career, a wise manager would realize that the company has a huge vested interest in the developer&#39;s learning, and would hence do things to encourage that learning.</p><p>Perhaps the most basic thing a manager could do is to have the company pay for <a href="/why_i_still_read_technical_books.htm">a book that the developer is motivated to read</a>. A book costs between $30 and $50 dollars. If a developer spends 20 of their own hours (on nights and weekends) over a month reading and absorbing that book, such that they can now profit the company with a new skill, this is a no-brainer. It could cost management <em>thousands</em> to send a developer to training (plus the days off work). It could cost management <em>additional thousands</em> to fix mistakes resulting from the developer not knowing that profitable technology. A book is cheaper, can be re-read by other developers, and is often read off the clock. Money speaks, so if management can&#39;t even encourage a motivated developer&#39;s learning with a $30 every other month, they&#39;re effectively telling developers that management doesn&#39;t value learning.</p>]]></description><category>management</category></item><item><title>Bad estimate trick - playing people off of each other</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/bad_estimate_trick__playing_people_off_of_each_other.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/bad_estimate_trick__playing_people_off_of_each_other.htm</link><pubDate>Wed, 29 Apr 2009 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=bad%5Festimate%5Ftrick%5F%5Fplaying%5Fpeople%5Foff%5Fof%5Feach%5Fother</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>One estimating technique I occasionally saw in consulting, which I thought was pathetic, is as follows:</p><p>The consultant faces a domain-specific problem that they&#39;re not familiar with (say writing reports, or doing some database optimization, or wiring up a backend service). So, they intend to sub-contract it out. They interview two separate contractors, and ask each for an estimate. The consultant, in their sneaky mind, figures that they&#39;ll play the two contractors off of each other to get the &quot;real estimate&quot;, and whichever estimate is lower must be the honest and correct one.</p><p>The biggest mistake I see here is the bias that whatever is lower is more correct. Developers are notorious for low-balling estimates (especially if the manager demands a low estimate in order for the developer to continue), so this is historically a bad bias. It&#39;s just as likely, or more likely, that the higher estimate is actually closer to the truth.</p><p>I think a much better approach is to find a way to determine who the more reliable and experienced developer is, and go with their estimate, even if it&#39;s the higher one.</p>]]></description><category>management</category></item></channel></rss>