<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Aaron Feng</title>
        <link>http://geekswithblogs.net/afeng/Default.aspx</link>
        <description>Agile Software Development (XP), Test Driven Development, .NET, etc.....</description>
        <language>en-US</language>
        <copyright>Aaron Feng</copyright>
        <managingEditor>aaron.feng@gmail.com</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <image>
            <title>Aaron Feng</title>
            <url>http://geekswithblogs.net/images/RSS2Image.gif</url>
            <link>http://geekswithblogs.net/afeng/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <item>
            <title>Moving...</title>
            <link>http://geekswithblogs.net/afeng/archive/2007/02/25/107268.aspx</link>
            <description>I'll be moving my blog to &lt;A href="http://www.aaronfeng.com"&gt;www.aaronfeng.com&lt;/A&gt;, please update your feed.&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=107268"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=107268" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/afeng/aggbug/107268.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Aaron Feng</dc:creator>
            <guid>http://geekswithblogs.net/afeng/archive/2007/02/25/107268.aspx</guid>
            <pubDate>Sun, 25 Feb 2007 22:28:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/afeng/comments/107268.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/afeng/archive/2007/02/25/107268.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/afeng/comments/commentRss/107268.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/afeng/services/trackbacks/107268.aspx</trackback:ping>
        </item>
        <item>
            <title>Script Schema and Data with Database Publishing Wizard</title>
            <category>Database</category>
            <link>http://geekswithblogs.net/afeng/archive/2007/01/18/103942.aspx</link>
            <description>&lt;p&gt;&lt;font size="2"&gt;It always annoyed me that there is no way to output schema to a file from SQL 2005 Management Studio.&amp;nbsp; It has the the basic functionality to script out simple objects like table, or database (just the creation of the database itself, nothing in it), but you have to do one object at a time.&amp;nbsp; On top of that, there is no way to output the data into a script either.&amp;nbsp; Sure, you can do a backup and restore your database, but this solution is just silly if you have to do it a few times each day.&amp;nbsp; I just want something that can output DDL and DML to a file for all the objects in the database.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;In the past, I wrote a &lt;/font&gt;&lt;a href="http://www.codesmithtools.com/"&gt;&lt;font size="2"&gt;CodeSmith&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; template to do this.&amp;nbsp; It took me a few days of&amp;nbsp;messing around to get everything generated correctly.&amp;nbsp; Basically it allows me to point&amp;nbsp;at an existing database to script the schema and data into a file.&amp;nbsp; The generated script goes into our MSI every build, so the client can create the complete schema during the installation.&amp;nbsp; The template did the job, but it did not do it the most efficient way, so it was a little bit slow when there&amp;nbsp;was a lot of data.&amp;nbsp; It can take three to eight minutes on a large database.&amp;nbsp; The output script&amp;nbsp;was not in the most robust form because it assumes that&amp;nbsp;you have a blank database (does not check if object already exists).&amp;nbsp; I am sure if I had more free time, I could have done it better.&amp;nbsp;(I enjoy my free time at home doing other stuff :-)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.codeplex.com/sqlhost/Wiki/View.aspx?title=Database%20Publishing%20Wizard"&gt;&lt;font size="2"&gt;Database Publishing Wizard&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; does exactly what I wanted and more.&amp;nbsp; I wish this tool would have came sooner.&amp;nbsp; I tested it out on one of our databases and it ran much faster then my &lt;/font&gt;&lt;a href="http://www.codesmithtools.com/"&gt;&lt;font size="2"&gt;CodeSmith&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; template, and the output script is much more robust.&amp;nbsp; It took just a few seconds to generate the whole database schema with a good&amp;nbsp;amount of data.&amp;nbsp; It also supports command line interface, so it is perfect for the build server.&amp;nbsp; I think we can actually speed up our build by using this tool instead.&amp;nbsp; Currently the tool&amp;nbsp;supports all unencrypted objects in the database.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;Schema generation is what I am mostly interested in, but it does more than that.&amp;nbsp; You can actually output the schema to a remote database via web service.&amp;nbsp; If you are interested, the full documentation can be found &lt;/font&gt;&lt;a href="http://www.codeplex.com/sqlhost/Project/FileDownload.aspx?DownloadId=4811"&gt;&lt;font size="2"&gt;here&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt;.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=103942"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=103942" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/afeng/aggbug/103942.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Aaron Feng</dc:creator>
            <guid>http://geekswithblogs.net/afeng/archive/2007/01/18/103942.aspx</guid>
            <pubDate>Fri, 19 Jan 2007 01:38:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/afeng/comments/103942.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/afeng/archive/2007/01/18/103942.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/afeng/comments/commentRss/103942.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/afeng/services/trackbacks/103942.aspx</trackback:ping>
        </item>
        <item>
            <title>Enterprise Application with Ruby on Rails?</title>
            <category>Ruby</category>
            <link>http://geekswithblogs.net/afeng/archive/2007/01/17/103852.aspx</link>
            <description>&lt;p&gt;&lt;font size="2"&gt;There has been a lot of &amp;ldquo;buzz&amp;rdquo; around &lt;/font&gt;&lt;a href="http://www.rubyonrails.org/"&gt;&lt;font size="2"&gt;Ruby on Rails&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; for a while now.&amp;nbsp; I have been following it since it hit the street.&amp;nbsp; I have to admit I have not done much with Rails except for reading and dreaming about it, but I hope to work with it someday.&amp;nbsp; However, in the&amp;nbsp;back of my mind, I always wondered&amp;nbsp;if I could build a real world application using this framework.&amp;nbsp; Now a day, everyone is building so called &amp;ldquo;Enterprise&amp;rdquo; (What is enterprise anyways?)&amp;nbsp;applications.&amp;nbsp; If I use Rails, can I say my application is enterprise ready?&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;I came across &lt;/font&gt;&lt;a href="http://jayfields.blogspot.com/"&gt;&lt;font size="2"&gt;Jay Field&amp;rsquo;s&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; post on &lt;/font&gt;&lt;a href="http://jayfields.blogspot.com/2007/01/rails-enterprise-ready.html"&gt;&lt;font size="2"&gt;Rails: Enterprise Ready&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt;.&amp;nbsp; One of the points he&amp;nbsp;made in his post is that&amp;nbsp;RoR right out of the box might not solve your problem (I do not think any framework can), but it can be easily extended.&amp;nbsp; Being easily extended is the key to any useful and sucessful framework.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;Besides all the enterprise worthyness stuff, I also found Jay&amp;rsquo;s approach to unit testing interesting.&amp;nbsp; On top of the &lt;a href="http://en.wikipedia.org/wiki/Model-view-controller"&gt;MVC&lt;/a&gt; layer, he inserted a &lt;/font&gt;&lt;a href="http://jayfields.blogspot.com/2006/09/rails-model-view-controller-presenter.html"&gt;&lt;font size="2"&gt;Presenter&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; abstraction in between the view and the controller.&amp;nbsp; The Presenter will be responsible for maintaining data for the view to consume.&amp;nbsp; Normally the controller would be responisble for this which might make testing a little bit messy.&amp;nbsp; Since the presenter maintains the data, it can be tested independently.&amp;nbsp; Of course the draw back is having to create and maintain&amp;nbsp;a separate class.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;He also mentioned all his unit tests run in less than a second.&amp;nbsp; Assuming he has more than a couple hundred tests, that number is amazingly fast!&amp;nbsp; One of the reasons he is able to achieve those numbers is because &lt;/font&gt;&lt;a href="http://jayfields.blogspot.com/2006/06/ruby-on-rails-unit-tests.html"&gt;&lt;font size="2"&gt;none of his tests actually hit the database&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt;.&amp;nbsp; This reminds me, our unit tests are running way too slow right now mostly because a lot of tests hit the database (especially when we run it on Oracle, it is killing me).&amp;nbsp; I am going to take off my RoR hat and try to see if I can make our tests faster :-)&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=103852"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=103852" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/afeng/aggbug/103852.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Aaron Feng</dc:creator>
            <guid>http://geekswithblogs.net/afeng/archive/2007/01/17/103852.aspx</guid>
            <pubDate>Thu, 18 Jan 2007 03:51:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/afeng/comments/103852.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/afeng/archive/2007/01/17/103852.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/afeng/comments/commentRss/103852.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/afeng/services/trackbacks/103852.aspx</trackback:ping>
        </item>
        <item>
            <title>Upgrading Strategy Using WiX</title>
            <category>Installer</category>
            <link>http://geekswithblogs.net/afeng/archive/2007/01/14/103611.aspx</link>
            <description>&lt;p&gt;&lt;font size="2"&gt;As described in the &lt;/font&gt;&lt;a href="http://www.tramontana.co.hu/wix/lesson4.php"&gt;&lt;font size="2"&gt;WiX (Windows Installer XML) tutorial&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt;,&amp;nbsp;upgrades can be categorized into three following categories:&lt;/font&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;font size="2"&gt;&lt;strong&gt;Small Updates:&amp;nbsp;&lt;/strong&gt;&amp;nbsp;Very small changes to existing files.&amp;nbsp; Version number stays the same.&lt;/font&gt;&lt;/li&gt;
&lt;li&gt;&lt;font size="2"&gt;&lt;strong&gt;Minor Ugrades: &lt;/strong&gt;Small changes, but no new files&amp;nbsp;are added or removed.&amp;nbsp; Change the the version number (most likely, change the minor or the build).&lt;/font&gt;&lt;/li&gt;
&lt;li&gt;&lt;font size="2"&gt;&lt;strong&gt;Major Ugrades:&amp;nbsp;&lt;/strong&gt;New files are added or removed.&amp;nbsp; Definitely change the version number (major, minor or build).&lt;/font&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;font size="2"&gt;In my opinion, the first two options are not as useful for a typical upgrade when new features are added.&amp;nbsp; One of the biggest restrictions&amp;nbsp;for the first two options is that you can not add or remove new files.&amp;nbsp; This is especially true when the creation of MSI is automated.&amp;nbsp; On top of that, you cannot setup upgrade conditions.&amp;nbsp; For example, an upgrade from 1.0.0 to 1.0.1 if 1.0.0 is installed.&amp;nbsp; This feature only works for major upgrades.&amp;nbsp; Normally, the user can click on the MSI to install the software. If you do a small update or minor upgrades you cannot simply just click on the MSI.&amp;nbsp; The only way to invoke the upgrade mode&amp;nbsp;is to pass command line arguments to the MSI.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;I prefer to always do the&amp;nbsp;the major&amp;nbsp;upgrade to have maximum flexibility and avoid all the problems described above.&amp;nbsp; Of course there are down sides to this approach as well.&lt;/font&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;font size="2"&gt;All the files must be deployed every time in order to do an upgrade.&lt;/font&gt;&lt;/li&gt;
&lt;li&gt;&lt;font size="2"&gt;By MSI definition, major versions can live side by side with an older version.&lt;/font&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;font size="2"&gt;The first one is not a big deal if your upgrade contains significant change because chances are MSI will force you to do a major upgrade anyway.&amp;nbsp; The second problem is a little bit more annoying because it might be undesireable to have many old versions lingering around.&amp;nbsp; One way to solve this problem is to transparently uninstall the old version before the new version.&amp;nbsp; This works fine except it probably will wipe out any user defined settings&amp;nbsp;if&amp;nbsp;they are stored in a file that was deployed by the original&amp;nbsp;MSI&amp;nbsp;during an uninstall.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;Overall, I still prefer the major updates strategy over the other two.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=103611"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=103611" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/afeng/aggbug/103611.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Aaron Feng</dc:creator>
            <guid>http://geekswithblogs.net/afeng/archive/2007/01/14/103611.aspx</guid>
            <pubDate>Mon, 15 Jan 2007 04:09:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/afeng/comments/103611.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/afeng/archive/2007/01/14/103611.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/afeng/comments/commentRss/103611.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/afeng/services/trackbacks/103611.aspx</trackback:ping>
        </item>
        <item>
            <title>Encrypting Web.config and App.config</title>
            <category>.NET</category>
            <link>http://geekswithblogs.net/afeng/archive/2006/12/10/100821.aspx</link>
            <description>&lt;p&gt;&lt;font size="2"&gt;Recently I got a chance to play around with the Data Protection Application Programming Interface (DPAPI).&amp;nbsp; With .NET 2.0 installed, you can encrypt your Web.config just by using aspnet_regiis.exe on the command line.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;font size="2"&gt;aspnet_regiis.exe -pe "connectionStrings" -app &amp;ldquo;/YourWebSite&amp;rdquo; &amp;ndash;prov "DataProtectionConfigurationProvider"&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;You can read the ConnectionStrings section back using ConfigurationManager as if the file is not encrypted.&amp;nbsp; That is all you have to do, the encryption is transparent to your application.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;This encryption works great for Web.config, however, it does not work if you want to encrypt the App.config for non web based applications.&amp;nbsp; The aspnet_regiis is hardcoded to look for Web.config.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;One can programatically encrypt just as easily:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;&lt;font color="#008080"&gt;Configuration&lt;/font&gt; configuration = &lt;font color="#008080"&gt;ConfigurationManager&lt;/font&gt;.OpenExeConfiguration(appConfig);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;&lt;font color="#008080"&gt;ConfigurationSection&lt;/font&gt; section = &lt;font color="#0000ff"&gt;this&lt;/font&gt;.configuration.GetSection(&lt;font color="#800000"&gt;"connectionStrings"&lt;/font&gt;);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt; (!section.SectionInformation.IsProtected) {&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;section.SectionInformation.ProtectSection(&lt;font color="#800000"&gt;"DataProtectionConfigurationProvider"&lt;/font&gt;);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;section.SectionInformation.ForceSave = &lt;font color="#0000ff"&gt;true&lt;/font&gt;;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;configuration.Save(&lt;font color="#008080"&gt;ConfigurationSaveMode&lt;/font&gt;.Modified);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;To decrypt just do the oposite:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt; (section.SectionInformation.IsProtected) {&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;// &amp;hellip;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;section.SectionInformation.UnprotectSection();&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;// &amp;hellip;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;}&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;The same code above can work for Web.config and App.config.&amp;nbsp;&amp;nbsp;For Web.config I would use&amp;nbsp; &lt;/font&gt;&lt;font size="2"&gt;&lt;font color="#008080"&gt;WebConfigurationManager&lt;/font&gt;.OpenWebConfiguration(webConfig).&amp;nbsp; For our environment we have a web project and some winform projects, so it is easier for us to create a simple tool to maintain both configuration file types.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=100821"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=100821" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/afeng/aggbug/100821.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Aaron Feng</dc:creator>
            <guid>http://geekswithblogs.net/afeng/archive/2006/12/10/100821.aspx</guid>
            <pubDate>Mon, 11 Dec 2006 03:18:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/afeng/comments/100821.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/afeng/archive/2006/12/10/100821.aspx#feedback</comments>
            <slash:comments>7</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/afeng/comments/commentRss/100821.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/afeng/services/trackbacks/100821.aspx</trackback:ping>
        </item>
        <item>
            <title>Got Amazon Milk?</title>
            <category>Random</category>
            <link>http://geekswithblogs.net/afeng/archive/2006/11/30/100091.aspx</link>
            <description>&lt;p&gt;You can buy almost anything on Amazon, ranging from books to hairdryers.&amp;nbsp; Now you can even buy your milk!&amp;nbsp; &lt;a href="http://www.amazon.com/Tuscan-Whole-Milk-Gallon-128/dp/B00032G1S0/sr=8-1/qid=1164939123/ref=pd_bbs_sr_1/104-0147330-8729546?ie=UTF8&amp;amp;s=gourmet-food"&gt;Check it out for yourself&lt;/a&gt;.&amp;nbsp; Read the comments and look at the images, it is funny as hell.&amp;nbsp; It is probably a joke, but it is still funny.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=100091"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=100091" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/afeng/aggbug/100091.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Aaron Feng</dc:creator>
            <guid>http://geekswithblogs.net/afeng/archive/2006/11/30/100091.aspx</guid>
            <pubDate>Fri, 01 Dec 2006 02:16:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/afeng/comments/100091.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/afeng/archive/2006/11/30/100091.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/afeng/comments/commentRss/100091.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/afeng/services/trackbacks/100091.aspx</trackback:ping>
        </item>
        <item>
            <title>Hacking Democracy</title>
            <category>Random</category>
            <link>http://geekswithblogs.net/afeng/archive/2006/11/29/99511.aspx</link>
            <description>&lt;font size="2"&gt;A couple of weeks ago, I saw a documentary on &lt;/font&gt;&lt;a href="http://www.hbo.com/"&gt;&lt;font size="2"&gt;HBO&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; called &lt;/font&gt;&lt;a href="http://www.hbo.com/apps/schedule/ScheduleServlet?ACTION_DETAIL=DETAIL&amp;amp;FOCUS_ID=633258"&gt;&lt;font size="2"&gt;Hacking Democracy&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt;.&amp;nbsp; As software developersbg, we all know there are tons of crappy software out there.&amp;nbsp; I could not believe how terrible the supposedly &amp;ldquo;high tech&amp;rdquo; and &amp;ldquo;top secret&amp;rdquo; voting machine software actually is.&amp;nbsp; You do not have to be geeky to understand the documentary.&amp;nbsp; Check it out, if you have not seen it.&lt;/font&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=99511"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=99511" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/afeng/aggbug/99511.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Aaron Feng</dc:creator>
            <guid>http://geekswithblogs.net/afeng/archive/2006/11/29/99511.aspx</guid>
            <pubDate>Thu, 30 Nov 2006 03:37:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/afeng/comments/99511.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/afeng/archive/2006/11/29/99511.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/afeng/comments/commentRss/99511.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/afeng/services/trackbacks/99511.aspx</trackback:ping>
        </item>
        <item>
            <title>BindingSource Calling Equals</title>
            <category>.NET</category>
            <link>http://geekswithblogs.net/afeng/archive/2006/10/30/95562.aspx</link>
            <description>&lt;p&gt;&lt;font size="2"&gt;Last week, we noticed our data grid (an Infragistics&amp;nbsp;UltraGrid)&amp;nbsp;was behaving very slow during data population and filtering.&amp;nbsp; At first I assumed we were doing something wrong in our code to cause the slow down.&amp;nbsp; After a few minutes of poking around I did not see anything obvious.&amp;nbsp; Someone noticed the equals method was called frequently when the data is being populated in the grid.&amp;nbsp; It seems like the equals method was being invoked when the BindingSource is being set.&amp;nbsp; I decided to do a&amp;nbsp;simple little&amp;nbsp;experiment to figure out what was going on.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt 9pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: blue; mso-no-proof: yes"&gt;class&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt; &lt;span style="COLOR: teal"&gt;Program&lt;/span&gt; {&lt;?xml:namespace prefix ="" o ns ="" "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; NumberOfItemsAdded = 1000;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; &lt;?xml:namespace prefix ="" u1 /&gt;&lt;u1:place u2:st="on"&gt;&lt;?xml:namespace prefix ="" st1 ns ="" "urn:schemas-microsoft-com:office:smarttags" /&gt;&lt;st1:place w:st="on"&gt;Main&lt;/u1:place&gt;&lt;/st1:place&gt;(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;[] args) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: teal"&gt;BindingSource&lt;/span&gt; bindingSource = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;BindingSource&lt;/span&gt;();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: teal"&gt;List&lt;/span&gt;&lt;span style="COLOR: black"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: teal"&gt;User&lt;/span&gt;&lt;span style="COLOR: black"&gt;&amp;gt; users = &lt;/span&gt;&lt;span style="COLOR: blue"&gt;new&lt;/span&gt;&lt;span style="COLOR: black"&gt; &lt;/span&gt;&lt;span style="COLOR: teal"&gt;List&lt;/span&gt;&lt;span style="COLOR: black"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: teal"&gt;User&lt;/span&gt;&lt;span style="COLOR: black"&gt;&amp;gt;();&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;for&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;int&lt;/span&gt; i = 0; i &amp;lt; NumberOfItemsAdded; i++) users.Add(&lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;User&lt;/span&gt;());&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;bindingSource.DataSource = users;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: teal"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="COLOR: maroon"&gt;"Equals was called: "&lt;/span&gt; + &lt;span style="COLOR: teal"&gt;User&lt;/span&gt;.NumOfTimesEqualsCalled);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: teal"&gt;Console&lt;/span&gt;.ReadLine();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: teal"&gt;User&lt;/span&gt; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; NumOfTimesEqualsCalled = 0;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt; &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; Equals(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; obj) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;NumOfTimesEqualsCalled++;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: blue"&gt;base&lt;/span&gt;.Equals(obj);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;
&lt;p&gt;&lt;font size="2"&gt;I started out with 1000 objects in my list then set it to the binding source.&amp;nbsp; The equals method was not called once.&amp;nbsp; This seemed weird to me because in our application the equals method is definitely being called.&amp;nbsp; I decided to add a property to the User class and see what happens.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-FAMILY: ProggyTinyTTSZ; mso-no-proof: yes"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp; &lt;font face="Times New Roman"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: blue; mso-no-proof: yes"&gt;public&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; Prop1 {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;font face="Times New Roman"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: maroon"&gt;""&lt;/span&gt;; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;font face="Times New Roman"&gt;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;By adding a property to the User class, the equals method is being invoked 4 times.&amp;nbsp; I added a couple more properties and, sure enough, the equals method is being called 4 times per property.&amp;nbsp; If you have 10 properties, the equals will be called 40 times.&amp;nbsp; I decided to change the implementation of the equals method to see if that would change number of times being invoked.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: blue; mso-no-proof: yes"&gt;&amp;nbsp;&amp;nbsp; public&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt; &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; Equals(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; obj) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;NumOfTimesEqualsCalled++;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: blue"&gt;true&lt;/span&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-FAMILY: ProggyTinyTTSZ; mso-no-proof: yes"&gt;&lt;span style="mso-tab-count: 1"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;&lt;font size="2"&gt;Nothing seemed to change when the equals is always returning true.&amp;nbsp; How about the opposite?&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: blue; mso-no-proof: yes"&gt;&amp;nbsp; &amp;nbsp;public&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt; &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; Equals(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; obj) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &lt;/span&gt;NumOfTimesEqualsCalled++;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: blue"&gt;false&lt;/span&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-FAMILY: ProggyTinyTTSZ; mso-no-proof: yes"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;font size="2"&gt;When equals is always returning false it became&amp;nbsp;a little bit more interesting&amp;nbsp;&amp;nbsp;Now it calls&amp;nbsp;equals on multiples of 18 times per property.&amp;nbsp; It is not realistic for equals to always return false, so&amp;nbsp;I decided to try a mixture of both, half true and half false.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: blue; mso-no-proof: yes"&gt;&amp;nbsp;&amp;nbsp; public&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt; &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; Equals(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; obj) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;/span&gt;NumOfTimesEqualsCalled++;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: teal"&gt;Random&lt;/span&gt; random = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;Random&lt;/span&gt;();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;int&lt;/span&gt; randomInt = random.Next();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;return&lt;/span&gt; randomInt % 2 == 0;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-FAMILY: ProggyTinyTTSZ; mso-no-proof: yes"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;font size="2"&gt;This time it was&amp;nbsp;not so straight forward with the number of time the equals method is being invoked.&amp;nbsp; With one property it is called 13 times.&amp;nbsp; With two properties, it is called 21 times.&amp;nbsp; From this point on, it seems to be multiples of 4 times per property.&amp;nbsp; What happens if equals return a value randomly?&amp;nbsp; It depends on how many properties you have when you set it to be a binding source.&amp;nbsp; If you are lucky, the equals method will be invoked 4 times per property.&amp;nbsp; If you have 10 properties, it will be called 40 times.&amp;nbsp; But in many cases it could be a lot worse.&amp;nbsp; The equals could be invoked 18 times per property which is 180 times if you have 10 properties.&amp;nbsp; All that work is done just to set the binding source&amp;rsquo;s data source.&amp;nbsp; It is not even displaying in the grid.&amp;nbsp; &lt;/font&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;In my example I created a list with 1000 objects, but that actually does not matter.&amp;nbsp; The list could contain&amp;nbsp;one object and the outcome will be the exactly same.&amp;nbsp; In our application the slow down is more exaggerated because we are using reflection to perform the equals.&amp;nbsp; The only reason we are using reflection is because we only use equals to perform dirty checking on the object after the user has performed an edit.&amp;nbsp; This is not a performance issue because at most you are only doing reflection&amp;nbsp;on object.&amp;nbsp; However, if the binding source is calling it hundreds of times, this becomes an issue.&amp;nbsp; Since we are only using equals for dirty checking, we can create a separate dirty checking equals method&amp;nbsp;to get around the binding source calling equals.&amp;nbsp; I guess I do not understand why setting the data source to a binding source would call equals at all.&amp;nbsp; To make the matter worse, if you are manipulating the binding source, the equals method will be invoked again.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=95562"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=95562" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/afeng/aggbug/95562.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Aaron Feng</dc:creator>
            <guid>http://geekswithblogs.net/afeng/archive/2006/10/30/95562.aspx</guid>
            <pubDate>Tue, 31 Oct 2006 03:02:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/afeng/comments/95562.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/afeng/archive/2006/10/30/95562.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/afeng/comments/commentRss/95562.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/afeng/services/trackbacks/95562.aspx</trackback:ping>
        </item>
        <item>
            <title>Ruby on Rails Migration</title>
            <category>Ruby</category>
            <link>http://geekswithblogs.net/afeng/archive/2006/09/30/92832.aspx</link>
            <description>&lt;p&gt;&lt;img alt="" hspace="2" src="http://geekswithblogs.net/images/geekswithblogs_net/afeng/5511/o_rails2.jpg" align="left" vspace="2" border="2" /&gt;Recently I decided to check out the &lt;a href="http://www.pragmaticprogrammer.com/title/rails/"&gt;beta version of Agile Web Development with Rails book&lt;/a&gt;, which is targeted to be released this fall.&amp;nbsp; It is very interesting that the authors also brought agility into book writing.&amp;nbsp; It allows readers to provide feedback to new material during the development of the book.&amp;nbsp; I am also glad to see that the migration part of the framework has become a big part of the book, even having a separate chapter dedicated to it.&amp;nbsp; It uses migration instead of DDL in the entire demo application.&amp;nbsp; Besides the migration, there are many significant updates to various parts of the book. But in this post, I will focus mostly on the migration tool.&lt;/p&gt;
&lt;p&gt;The migration tool is targeting Rails applications, but it can also be useful outside the Rails world.&amp;nbsp; There are some people out there already (includes us, &lt;a href="http://aaronfeng.blogspot.com/2006_01_01_aaronfeng_archive.html"&gt;here is my old post on it&lt;/a&gt;) experimenting using Rails migration as "Enterprise glue" to maintain database schemas.&amp;nbsp; I hope the final release version of the book will have something on this topic.&lt;/p&gt;
&lt;p&gt;I will outline the basics of rails migration below for those are not familiar with it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is Ruby on Rails Migration?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;At the most simple level, it allows developers to change the database schema as the application requires it in a simple and easy manner.&amp;nbsp; Instead of writing DDL scripts, you use Ruby as a DSL (domain specific language) to describe what the schema should look like when the changes are&amp;nbsp;required.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why use it?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The migration tool allows developers to upgrade or downgrade a schema version without loosing data (of course, if you drop stuff it will be lost).&amp;nbsp; Sure, you can write DDL that does the same thing for you (sort of, but not really without some external tooling), but it will take a lot more effort especially when you are supporting more than one database.&amp;nbsp; In theory, the migration script you write for one database should work on other databases as long as the operation is supported (currently, it supports all major databases including open source alternatives).&amp;nbsp; I said in theory because not all databases behave exactly the same way for a given operation. There might be some minor differences, but that's for another post.&amp;nbsp; If you need to extend or change&amp;nbsp;the existing migration functionality, it is usually very easy to do so.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How does it work?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You basically write a Ruby class that inherits from ActiveRecord::Migration to describe what needs to be accomplished.&amp;nbsp; There are only two methods you need to write, up and down.&amp;nbsp; Up method will be called during an upgrade, and down method for downgrading.&lt;/p&gt;
&lt;p&gt;class AddTable &amp;lt; ActiveRecord::Migration&lt;br /&gt;&amp;nbsp; def self.up&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; create_table :cars do |t|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t.column :model,&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;:string&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t.column :year,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; :int&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t.column :make,&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; :string&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t.column :comments, :text&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;br /&gt;&amp;nbsp; end&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; def self.down&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; drop_table :cars&lt;br /&gt;&amp;nbsp; end&lt;br /&gt;end&lt;/p&gt;
&lt;p&gt;In this trivial example, it creates a cars table with model, year, make, and comments columns.&amp;nbsp; One interesting thing to note about model and make columns are both string type.&amp;nbsp; This is not DDL we are working with.&amp;nbsp; Migration uses Ruby classes to encapsulate the internal database types in order to abstract out the databases.&amp;nbsp; Depending on what type of database you are using, string type might vary, but it tends to be pretty consistant across&amp;nbsp;different databases.&amp;nbsp; In the down method, it just does exactly the opposite, as if the script has never been run.&lt;/p&gt;
&lt;p&gt;On the command line, if you run &amp;ldquo;rake db:migrate&amp;rdquo;, your database will be upgraded to the latest version.&amp;nbsp; In this case, the cars table will be added.&amp;nbsp; Each migration script will have a 3 digit number in the start of the file name which represents the schema version of the script.&amp;nbsp; That same version number is also stored in the database you are using.&amp;nbsp; That is how migration knows which script to run during an upgrade or downgrade.&amp;nbsp; Using the example above, the file name would look something like the following:&lt;/p&gt;
&lt;p&gt;001_create_cars.rb&lt;/p&gt;
&lt;p&gt;Lets say you are currently on version four but you need to roll back to version one, you can run the following command:&lt;/p&gt;
&lt;p&gt;rake db:migration VERSION=1&lt;/p&gt;
&lt;p&gt;Migration supports most of the operations you would need to perform on the daily basis.&amp;nbsp;&amp;nbsp;But if you need to do something it does not support you can always execute DDL in your migration script.&lt;/p&gt;
&lt;p&gt;One of the really cool things about using Ruby as a DSL is that you have the power of a real programming language to create your migration scripts. This comes in really handy when you need to create test data.&lt;/p&gt;
&lt;p&gt;I only scratched the surface on the stuff I covered on Rails migration.&amp;nbsp; I would encourage anyone that is interested to read the Rails book.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=92832"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=92832" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/afeng/aggbug/92832.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Aaron Feng</dc:creator>
            <guid>http://geekswithblogs.net/afeng/archive/2006/09/30/92832.aspx</guid>
            <pubDate>Sun, 01 Oct 2006 01:30:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/afeng/comments/92832.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/afeng/archive/2006/09/30/92832.aspx#feedback</comments>
            <slash:comments>9</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/afeng/comments/commentRss/92832.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/afeng/services/trackbacks/92832.aspx</trackback:ping>
        </item>
        <item>
            <title>This is where the magic happens</title>
            <category>Agile</category>
            <link>http://geekswithblogs.net/afeng/archive/2006/09/11/90909.aspx</link>
            <description>&lt;p&gt;&lt;img alt="" src="http://geekswithblogs.net/images/geekswithblogs_net/afeng/5348/o_new_office.JPG" border="0" /&gt;&lt;/p&gt;
&lt;p&gt;We finally moved into our highly anticipated new office space.&amp;nbsp; It was designed to be &lt;a title="" href="http://en.wikipedia.org/wiki/Agile_software_development" target="_blank"&gt;&lt;/a&gt; friendly with plenty of white boards and space to move around.&amp;nbsp; The whole back wall in our development area can be used as a white board, so we no longer have to erase our designs until&amp;nbsp;they are&amp;nbsp;no longer needed.&amp;nbsp; In our old office, all the developers were packed into a small area, so there&amp;nbsp;was&amp;nbsp;no room for the product team.&amp;nbsp; Now the product team is located behind the development team,which makes it easier to communicate with each other.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=90909"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=90909" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/afeng/aggbug/90909.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Aaron Feng</dc:creator>
            <guid>http://geekswithblogs.net/afeng/archive/2006/09/11/90909.aspx</guid>
            <pubDate>Tue, 12 Sep 2006 00:34:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/afeng/comments/90909.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/afeng/archive/2006/09/11/90909.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/afeng/comments/commentRss/90909.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/afeng/services/trackbacks/90909.aspx</trackback:ping>
        </item>
        <item>
            <title>Is the C# Party Over?</title>
            <category>.NET</category>
            <link>http://geekswithblogs.net/afeng/archive/2006/08/29/89715.aspx</link>
            <description>&lt;p&gt;After a month of a busy schedule, I finally have time to go though my blog aggregator today. I noticed a few people in my feed mentioned &lt;a href="http://it.sys-con.com/read/117741.htm"&gt;&lt;u&gt;&lt;font color="#0000ff"&gt;this interesting article&lt;/u&gt;&lt;/font&gt;&lt;/a&gt;. If you have not read it yet, go read it. I think this guy is smoking something, but you can be the judge.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=89715"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=89715" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/afeng/aggbug/89715.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Aaron Feng</dc:creator>
            <guid>http://geekswithblogs.net/afeng/archive/2006/08/29/89715.aspx</guid>
            <pubDate>Wed, 30 Aug 2006 00:24:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/afeng/comments/89715.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/afeng/archive/2006/08/29/89715.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/afeng/comments/commentRss/89715.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/afeng/services/trackbacks/89715.aspx</trackback:ping>
        </item>
        <item>
            <title>Agile Retrospectives</title>
            <category>Agile</category>
            <link>http://geekswithblogs.net/afeng/archive/2006/08/27/89465.aspx</link>
            <description>&lt;p&gt;&lt;img alt="" src="http://geekswithblogs.net/images/geekswithblogs_net/afeng/5348/r_agile_retrospectives.JPG" align="left" border="0" /&gt;Retrospectives&amp;nbsp;are a way for a software development teams to discuss and figure out ways to resolve issues when an increment of work is done.&amp;nbsp; The strength of the retrospective comes from focusing on the team members and how to improve as a team.&amp;nbsp; For the team I am working on, the increment of work just so happens to be one week.&amp;nbsp; Our retrospective definitely helped us fine tune our team on the iteration basis.&amp;nbsp; At times, I feel like our retrospective has become routine and rushed because the&amp;nbsp;sooner we can finish, the&amp;nbsp;sooner we can start coding since we are on a short iteration.&amp;nbsp; I decided to check out &lt;a title="" href="http://en.wikipedia.org/wiki/Agile_software_development" target="_blank"&gt;&lt;/a&gt; &lt;a href="http://www.bookpool.com/ss?qs=agile+retrospectives&amp;x=0&amp;y=0"&gt;Retrospective by Esther Derby and Diana Larsen &lt;/a&gt;to see if there is anything we can do to revitalize our retrospective.&amp;nbsp; Overall, I found the book to be really helpful and easy to read and understand.&amp;nbsp; The book encourages very structured and well planned out retrospectives, which I feel is our weak point.&amp;nbsp; The book suggested five phases listed below: &lt;/p&gt;
&lt;p&gt;1.&amp;nbsp; Set the stage&lt;br /&gt;2.&amp;nbsp; Gather data&lt;br /&gt;3.&amp;nbsp; Generate insights&lt;br /&gt;4.&amp;nbsp; Decide what to do&lt;br /&gt;5.&amp;nbsp; Close the retrospective&lt;/p&gt;
&lt;p&gt;Set the stage phase: Basically an ice breaker that the retrospective leader will facilitate in an environment that allows the team members to focus and participate on the retrospective.&amp;nbsp; According to the book, this is one of the most import phases of the retrospective, and many teams usually skip it.&amp;nbsp; As you can guess, we also skipped this phase with our past retrospectives as well.&amp;nbsp; In order to have a successful retrospective, all team members need to participate early, otherwise people&amp;nbsp;are less likely to say anything in the later phase.&lt;/p&gt;
&lt;p&gt;Gather data phase: This s a great way to put everyone on the same page before getting to the meat of the retrospective even if you are on a short iteration.&amp;nbsp; It is much easier to determine shifts and patterns by looking at hard data.&amp;nbsp; On our team, most of the time we do not have hard data, so at times we rely on&amp;nbsp;team members&amp;rsquo;&amp;nbsp;subjective feelings&amp;nbsp;as to&amp;nbsp;how things went.&amp;nbsp; This can be problematic because it is hard to have a constructive discussion when people have different views on what went on.&lt;/p&gt;
&lt;p&gt;Once the team starts to see some patterns and shifts, it is now time to move into generating insights by looking at the big picture and figuring out root causes.&amp;nbsp; We&amp;nbsp;tend to&amp;nbsp;have&amp;nbsp;pretty good discussions in this phase, but it usually went on longer than needed because we do not have hard data to help us.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Deciding&amp;nbsp;what to do is the meat of the retrospective.&amp;nbsp; This stage is pretty self explanatory, but the important point here is whatever the team decides to do, the team must commit to it.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Closing the retrospective is very helpful for the team to fine tune the next retrospective.&amp;nbsp; Like anything else, it needs to be tuned every once in a while, so&amp;nbsp;do the retrospectives.&lt;/p&gt;
&lt;p&gt;The description I provided above is by no means comprehensive.&amp;nbsp; If you feel your retrospective is not as effective any more, this book is for you.&amp;nbsp; The book provides many activities for each phase of the retrospective, so you do not have to stick with the same old activity over and over again.&amp;nbsp; We followed the format of the book, and ran two retrospectives with&amp;nbsp;a great deal of&amp;nbsp;positive feedback from the team members.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=89465"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=89465" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/afeng/aggbug/89465.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Aaron Feng</dc:creator>
            <guid>http://geekswithblogs.net/afeng/archive/2006/08/27/89465.aspx</guid>
            <pubDate>Sun, 27 Aug 2006 17:37:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/afeng/comments/89465.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/afeng/archive/2006/08/27/89465.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/afeng/comments/commentRss/89465.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/afeng/services/trackbacks/89465.aspx</trackback:ping>
        </item>
        <item>
            <title>NLog</title>
            <category>.NET</category>
            <link>http://geekswithblogs.net/afeng/archive/2006/07/31/86759.aspx</link>
            <description>&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;Logging is one of those things where once you have it, you never really pay much attention to it.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Today I decided to investigate what is new in the logging world since the last time I looked at it.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;I heard of &lt;a href="http://www.nlog-project.org/"&gt;NLog&lt;/a&gt; some time ago, but never took the time to test drive it.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;In the past I have always used &lt;a href="http://logging.apache.org/log4net/"&gt;log4net&lt;/a&gt;, so I decided to compare &lt;a href="http://www.nlog-project.org/"&gt;NLog&lt;/a&gt; to it.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Here are some of the things that I really like about &lt;a href="http://www.nlog-project.org/"&gt;NLog&lt;/a&gt;, and it might not be possible or &amp;ldquo;easy&amp;rdquo; to do with &lt;a href="http://logging.apache.org/log4net/"&gt;log4net&lt;/a&gt;:&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;?xml:namespace prefix ="" o ns ="" "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;strong&gt;Asynchronous Processing:&lt;/strong&gt;&lt;/o:p&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;/o:p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;a href="http://nlog-project.org/"&gt;NLog&lt;/a&gt; provider wrapper and compound targets for asynchronous processing, loading balancing, buffering, and etc.&lt;/o:p&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;/o:p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;Easy Configuration:&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;The configuration file structure is simple and easier to write.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;If you do not remember all the options, no worries, you will receive Intellisense in Visual Studio.&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;Include Files:&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;You can split up the configuration to multiple files by using the &amp;lt;include /&amp;gt;.&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;Contextual Information:&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;Like all other logging frameworks, &lt;a href="http://www.nlog-project.org/"&gt;NLog&lt;/a&gt; is able to add contextual information when each message is logged.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;You can use the contextual information to create a log file for each user, create one log file per day, one file per logger, or any combination.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Stack trace can also be included when each message is logged.&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;Not Swallowing Exceptions:&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;Sometimes it is useful to know when the logging framework is throwing an exception to prevent logging from happening; &lt;a href="http://www.nlog-project.org/"&gt;NLog&lt;/a&gt; can be configured not to swallow any exceptions.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;It is useful to troubleshoot problems during deployment.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;Defining Variables in Configuration File:&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;Common value can be stored in a variable.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Great way to keep you configuration file DRY.&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;Note:&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;This is a superficial look at some of the features of &lt;a href="http://www.nlog-project.org/"&gt;NLog&lt;/a&gt;, and I have not worked with &lt;a href="http://www.nlog-project.org/"&gt;NLog&lt;/a&gt; extensively.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=86759"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=86759" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/afeng/aggbug/86759.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Aaron Feng</dc:creator>
            <guid>http://geekswithblogs.net/afeng/archive/2006/07/31/86759.aspx</guid>
            <pubDate>Tue, 01 Aug 2006 00:53:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/afeng/comments/86759.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/afeng/archive/2006/07/31/86759.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/afeng/comments/commentRss/86759.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/afeng/services/trackbacks/86759.aspx</trackback:ping>
        </item>
        <item>
            <title>Presentation Layer Testing Thoughts</title>
            <category>TDD</category>
            <link>http://geekswithblogs.net/afeng/archive/2006/07/05/84187.aspx</link>
            <description>&lt;p class="MsoNormal"&gt;For anyone doing &lt;a href="http://www.agiledata.org/essays/tdd.html"&gt;Test Driven Development&lt;/a&gt;, mocks (stubs) are commonly used.&amp;nbsp; Whether you hand roll your own mocks, or use a mock framework like &lt;a href="http://www.codeproject.com/useritems/Rhino_Mocks_Version_20.asp"&gt;Rhino Mocks&lt;/a&gt;, stubs are&amp;nbsp;used&amp;nbsp;to in order to isolate the code we want to test.&amp;nbsp; Before we can isolate our code, proper separations of concerns are required; such as implementing the &lt;a href="http://www.martinfowler.com/eaaCatalog/modelViewController.html"&gt;Model View Controller&lt;/a&gt; or &lt;a href="http://www.martinfowler.com/eaaDev/ModelViewPresenter.html"&gt;Model View Presenter &lt;/a&gt;pattern for UI testing.&amp;nbsp; After you practice TDD for a few months, and write countless tests, you start to see a pattern of how to make your presentation layer testable and everything becomes&amp;nbsp;automatic and second nature.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;One of the big benefits of TDD is&amp;nbsp;using tests to guide your design.&amp;nbsp; Have you ever stopped and wondered if your design has really&amp;nbsp;improved by structuring your code in a manner that is testable?&amp;nbsp; Are you creating more duplication or allowing too much accessibility?&amp;nbsp; Let&amp;rsquo;s examine how&amp;nbsp;the presentation layer&amp;nbsp;can be tested using the MVP pattern.&amp;nbsp; I will use a simple example where the customer information can enter entered.&amp;nbsp; I purposely omitted the presenter&amp;nbsp;interaction with the view&amp;nbsp;in order to put more&amp;nbsp;focus on the view.&lt;/p&gt;&lt;font color="#0000ff"&gt;&lt;font color="#0000ff"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: ProggyTinyTTSZ; mso-no-proof: yes"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: ProggyCleanTT; mso-no-proof: yes"&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;font face="Times New Roman"&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;public&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; &lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;interface&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; &lt;/span&gt;&lt;span style="COLOR: teal; mso-no-proof: yes"&gt;ICustomerDetailsView&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; {&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;?xml:namespace prefix ="" u1 /&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;?xml:namespace prefix ="" o /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;?xml:namespace prefix ="" u2 /&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font face="Times New Roman"&gt;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Times New Roman"&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;string&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; CustomerFirstName { &lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;get&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;; }&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font face="Times New Roman"&gt;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Times New Roman"&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;string&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; CustomerLastName { &lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;get&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;;}&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font face="Times New Roman"&gt;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Times New Roman"&gt;&lt;span style="COLOR: teal; mso-no-proof: yes"&gt;List&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: teal; mso-no-proof: yes"&gt;Order&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&amp;gt; Orders { &lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;get&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;; }&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;font face="Times New Roman"&gt;}&lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;font face="Times New Roman"&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;font face="Times New Roman"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font face="Times New Roman"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; &lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;class&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; &lt;/span&gt;&lt;span style="COLOR: teal; mso-no-proof: yes"&gt;CustomDetailsView&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; : &lt;/span&gt;&lt;span style="COLOR: teal; mso-no-proof: yes"&gt;UserControl&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;, &lt;/span&gt;&lt;span style="COLOR: teal; mso-no-proof: yes"&gt;ICustomerDetailsView&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; {&lt;u2:p&gt;&amp;nbsp;&lt;/u2:p&gt;&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;font face="Times New Roman"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;public&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; &lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;string&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; CustomerFirstName {&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font face="Times New Roman"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Times New Roman"&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;get&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; { &lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;return&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; &lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;this&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;.firstNameTextBox.Text; }&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;font face="Times New Roman"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;u2:p&gt;&lt;font face="Times New Roman"&gt;&amp;nbsp;&lt;/font&gt;&lt;/u2:p&gt;&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;font face="Times New Roman"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;public&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; &lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;string&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; CustomerLastName {&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font face="Times New Roman"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Times New Roman"&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;get&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; { &lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;return&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; &lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;this&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;.lastNameTextBox.Text; }&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;font face="Times New Roman"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;u2:p&gt;&lt;font face="Times New Roman"&gt;&amp;nbsp;&lt;/font&gt;&lt;/u2:p&gt;&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;font face="Times New Roman"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;public&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; &lt;/span&gt;&lt;span style="COLOR: teal; mso-no-proof: yes"&gt;List&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: teal; mso-no-proof: yes"&gt;Order&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&amp;gt; Orders {&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font face="Times New Roman"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Times New Roman"&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;get&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; {&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font face="Times New Roman"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Times New Roman"&gt;&lt;span style="COLOR: teal; mso-no-proof: yes"&gt;List&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: teal; mso-no-proof: yes"&gt;Order&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&amp;gt; orders = &lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;new&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; &lt;/span&gt;&lt;span style="COLOR: teal; mso-no-proof: yes"&gt;List&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: teal; mso-no-proof: yes"&gt;Order&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&amp;gt;();&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font face="Times New Roman"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Times New Roman"&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;foreach&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; (&lt;/span&gt;&lt;span style="COLOR: teal; mso-no-proof: yes"&gt;Order&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; order &lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;in&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; &lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;this&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;.ordersComboBox.Items) {&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;font face="Times New Roman"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;orders.Add(order);&lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;font face="Times New Roman"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font face="Times New Roman"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Times New Roman"&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;return&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; orders;&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;font face="Times New Roman"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;font face="Times New Roman"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;font face="Times New Roman"&gt;}&lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: ProggyTinyTTSZ; mso-no-proof: yes"&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-FAMILY: ProggyTinyTTSZ; mso-no-proof: yes"&gt;&lt;font color="#000000"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;We&amp;nbsp;start with an&amp;nbsp;interface called &lt;font color="#008080"&gt;ICustomerDetailsView&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt; &lt;/font&gt;&lt;font color="#000000"&gt;to describe behaviors of the view.&amp;nbsp; Now we can use the interface to create our mock view.&amp;nbsp; In the MVP pattern, the presenter is an extension to the view, so all the interactions occuring in the view will be delegated to the presenter.&amp;nbsp; With the delgation to the presenter, we would only have to explicitly test the presenter.&amp;nbsp; The reason the view is not tested is because all the logic lives inside of the presenter, so we end up testing the API.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;&lt;/font&gt;&amp;nbsp;&lt;/p&gt;&lt;font color="#0000ff"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: ProggyTinyTTSZ; mso-no-proof: yes"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: ProggyTinyTTSZ; mso-no-proof: yes"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: ProggyCleanTT; mso-no-proof: yes"&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;font face="Times New Roman"&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;public&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; &lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;class&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; &lt;/span&gt;&lt;span style="COLOR: teal; mso-no-proof: yes"&gt;MockCustomDetailsView&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; : &lt;/span&gt;&lt;span style="COLOR: teal; mso-no-proof: yes"&gt;ICustomerDetailsView&lt;/span&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt; {&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;&lt;u2:p&gt;&lt;/u2:p&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font face="Times New Roman"&gt;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face="Times New Roman"&gt;&lt;span style="COLOR: green; mso-no-proof: yes"&gt;// implement ICustomerDetailsView &lt;u2:p&gt;&lt;/u2:p&gt;&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;font face="Times New Roman"&gt;&lt;span style="COLOR: green; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;// you can have setters here so values can be injected for testing&lt;u2:p&gt;&lt;/u2:p&gt;&lt;/span&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;&lt;u1:p&gt;&lt;/u1:p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;font face="Times New Roman"&gt;&lt;span style="COLOR: black; mso-no-proof: yes"&gt;}&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;/span&gt;&lt;/p&gt;&lt;u1:p&gt;&lt;/u1:p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-FAMILY: ProggyCleanTT"&gt;&lt;o:p&gt;&lt;font color="#000000"&gt;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#000000"&gt;The presenter&amp;nbsp;can now use the mock view during automated testing and will not know a difference from the real thing.&amp;nbsp; All your tests pass and&amp;nbsp;life is good.&amp;nbsp; Before you checkin your code, you decide to smoke your application.&amp;nbsp; To your surprise, your view does not behave correctly.&amp;nbsp; You poke around for a few seconds and you remember your tests actually use the mock view, so you never wired up the real thing.&amp;nbsp; In this simple scenario, when all your tests pass it&amp;nbsp;does not mean your application will work correctly if you never wire it up.&amp;nbsp; Sometimes it can feel a little awkward when you are writing the mock view to mimic the real view, so your tests can pass.&amp;nbsp; On top of that, the interface was only added to make the mock possible in this scenario.&amp;nbsp; I understand creating an interface&amp;nbsp;is considered &amp;ldquo;best practice&amp;rdquo; to loosen up the coupling, but in this case, the interface was created&amp;nbsp;to make stubbing possible.&amp;nbsp; It is a little smelly to me because&amp;nbsp;files were added only to make testing possible, and the real view was treated like a&amp;nbsp;second class citizen.&amp;nbsp; Maybe this is not so bad, and I should not lose sleep over it.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#000000"&gt;Maybe life would be a whole lot better if we could use the real view in this case for testing.&amp;nbsp; That would eliminate our problem of forgetting to wire things up.&amp;nbsp; It would also reduce the number of files we have to write, and would achieve the same outcome.&amp;nbsp; Let&amp;rsquo;s&amp;nbsp;see if we can create another implementation of &lt;font color="#008080"&gt;CustomerDetailsView&lt;/font&gt; to&amp;nbsp;accomplish this.&amp;nbsp; We will call&amp;nbsp;the new view&amp;nbsp;&lt;font color="#008080"&gt;ICustomerDetailsView2&lt;/font&gt;:&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="COLOR: blue; mso-no-proof: yes"&gt;public&lt;/span&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;class&lt;/span&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;span style="COLOR: teal"&gt;CustomDetailsView2&lt;/span&gt;&lt;font color="#000000"&gt; : &lt;/font&gt;&lt;span style="COLOR: teal"&gt;UserControl&lt;/span&gt;&lt;font color="#000000"&gt; {&lt;?xml:namespace prefix ="" o ns ="" "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color="#000000"&gt;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&lt;font color="#000000"&gt; CustomerFirstName {&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;get&lt;/span&gt;&lt;font color="#000000"&gt; { &lt;/font&gt;&lt;span style="COLOR: blue"&gt;return&lt;/span&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;&lt;font color="#000000"&gt;.firstNameTextBox.Text; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;set&lt;/span&gt;&lt;font color="#000000"&gt; { &lt;/font&gt;&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;&lt;font color="#000000"&gt;.firstNameTextBox.Text = &lt;/font&gt;&lt;span style="COLOR: blue"&gt;value&lt;/span&gt;&lt;font color="#000000"&gt;; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;font color="#000000"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;o:p&gt;&lt;font color="#000000"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color="#000000"&gt;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&lt;font color="#000000"&gt; CustomerLastName {&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;get&lt;/span&gt;&lt;font color="#000000"&gt; { &lt;/font&gt;&lt;span style="COLOR: blue"&gt;return&lt;/span&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;&lt;font color="#000000"&gt;.lastNameTextBox.Text; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;set&lt;/span&gt;&lt;font color="#000000"&gt; { &lt;/font&gt;&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;&lt;font color="#000000"&gt;.lastNameTextBox.Text = &lt;/font&gt;&lt;span style="COLOR: blue"&gt;value&lt;/span&gt;&lt;font color="#000000"&gt;; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;font color="#000000"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;o:p&gt;&lt;font color="#000000"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color="#000000"&gt;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;span style="COLOR: teal"&gt;List&lt;/span&gt;&lt;font color="#000000"&gt;&amp;lt;&lt;/font&gt;&lt;span style="COLOR: teal"&gt;Order&lt;/span&gt;&lt;font color="#000000"&gt;&amp;gt; Orders {&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;get&lt;/span&gt;&lt;font color="#000000"&gt; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: teal"&gt;List&lt;/span&gt;&lt;font color="#000000"&gt;&amp;lt;&lt;/font&gt;&lt;span style="COLOR: teal"&gt;Order&lt;/span&gt;&lt;font color="#000000"&gt;&amp;gt; orders = &lt;/font&gt;&lt;span style="COLOR: blue"&gt;new&lt;/span&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;span style="COLOR: teal"&gt;List&lt;/span&gt;&lt;font color="#000000"&gt;&amp;lt;&lt;/font&gt;&lt;span style="COLOR: teal"&gt;Order&lt;/span&gt;&lt;font color="#000000"&gt;&amp;gt;();&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt;&lt;font color="#000000"&gt; (&lt;/font&gt;&lt;span style="COLOR: teal"&gt;Order&lt;/span&gt;&lt;font color="#000000"&gt; order &lt;/font&gt;&lt;span style="COLOR: blue"&gt;in&lt;/span&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;&lt;font color="#000000"&gt;.ordersComboBox.Items) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;font color="#000000"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;orders.Add(order);&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;font color="#000000"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;return&lt;/span&gt;&lt;font color="#000000"&gt; orders;&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;font color="#000000"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;o:p&gt;&lt;font color="#000000"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;set&lt;/span&gt;&lt;font color="#000000"&gt; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt;&lt;font color="#000000"&gt; (&lt;/font&gt;&lt;span style="COLOR: teal"&gt;Order&lt;/span&gt;&lt;font color="#000000"&gt; order &lt;/font&gt;&lt;span style="COLOR: blue"&gt;in&lt;/span&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;value&lt;/span&gt;&lt;font color="#000000"&gt;) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;font color="#000000"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;&lt;font color="#000000"&gt;.ordersComboBox.Items.Add(order);&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;font color="#000000"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;font color="#000000"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;font color="#000000"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue; FONT-FAMILY: ProggyTinyTTSZ; mso-no-proof: yes"&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-FAMILY: ProggyCleanTT"&gt;&lt;o:p&gt;&lt;font color="#000000"&gt;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#000000"&gt;We can use this view for both testing and production code, but the side effect is that we have to expose setters only for testing purposes.&amp;nbsp; In&amp;nbsp;our first implementation, we were able to put the setters only on the mock, so our real view is not polluted.&amp;nbsp; The reason&amp;nbsp;the setter is unnecessary for &lt;/font&gt;&lt;font color="#008080"&gt;CustomerDetailsView2 &lt;/font&gt;&lt;font color="#000000"&gt;is because we would never programmatically call the setter.&amp;nbsp; The setter is used to simulate data input from the user.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;font color="#000000"&gt;&lt;/font&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;font color="#000000"&gt;Either way&amp;nbsp; you look at it, there are some drawbacks to both techniques.&amp;nbsp; This really depends on what&amp;nbsp;you consider the lesser of the evils.&amp;nbsp; I know there are ways to solve this problem by using a mock framework, but then&amp;nbsp;again are you adding&amp;nbsp;&lt;span style="FONT-SIZE: 12pt; COLOR: black; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;technology&lt;/span&gt; in order to make testing possible?&amp;nbsp; Let&amp;rsquo;s say we live in&amp;nbsp;a world where we do not need to do any testing.&amp;nbsp; Whatever&amp;nbsp;code we write will always work.&amp;nbsp; Would you have&amp;nbsp;implemented &lt;font color="#008080"&gt;CustomerDetailsView&lt;/font&gt; the same way?&amp;nbsp; The second example exposes&amp;nbsp;setters when the real system will never use it.&amp;nbsp;&amp;nbsp;Is that breaking the accessibility of the view?&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;font color="#000000"&gt;&lt;/font&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;font color="#000000"&gt;I understand the ability to mock things out is good because that means your system has enough abstractions.&amp;nbsp; I am just not sure mocks should be used every where in order to make testing possible.&amp;nbsp; &lt;/font&gt;&lt;font color="#000000"&gt;I know there is a fine line here, like many good things in the Computer Science world, but I often struggle&amp;nbsp;to&amp;nbsp;choose the optimal way.&amp;nbsp; I hope no one got the impression that I am bashing on TDD or mock objects. In fact, it is quiet the opposite.&lt;/font&gt;&lt;/p&gt;&lt;/font&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=84187"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=84187" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/afeng/aggbug/84187.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Aaron Feng</dc:creator>
            <guid>http://geekswithblogs.net/afeng/archive/2006/07/05/84187.aspx</guid>
            <pubDate>Thu, 06 Jul 2006 01:52:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/afeng/comments/84187.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/afeng/archive/2006/07/05/84187.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/afeng/comments/commentRss/84187.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/afeng/services/trackbacks/84187.aspx</trackback:ping>
        </item>
        <item>
            <title>Who’s the Mole – The Leader Game</title>
            <category>Agile</category>
            <link>http://geekswithblogs.net/afeng/archive/2006/07/02/83893.aspx</link>
            <description>Like many &lt;a title="" href="http://en.wikipedia.org/wiki/Agile_software_development" target="_blank"&gt;&lt;/a&gt; teams, we always fine tune our process, so we can consistently be better.  &lt;a href= http://steve.emxsoftware.com/&gt;Steve Eichert&lt;/a&gt; has a great &lt;a href= http://steve.emxsoftware.com/Agile+-+Scrum/How+to+prevent+an+agile+face+plant&gt;post&lt;/a&gt; that describes our process in detail.  In addition to what Steve described, we also play a game that I feel has become part of our process.  We call it “the leader game”.  A person is chosen to be the “leader” for the iteration.  The “leader” is in charge of tasks (not story tasks) that would normally fall through the cracks.  It can be as simple as making sure time is tracked on each story task, or something more like leading a discussion on a particular part of the system in our software.  Basically, the leader makes sure things get done in general.  

The game seems pretty straight forward, right?  There is one catch; no one knows who the leader is until end of the iteration.  At the end of the iteration, everyone votes the person they think was the leader.  The goal of the game is to be voted as the leader even though you are not the real “leader”.  The leader game is a spin off  &lt;a href= http://abc.go.com/primetime/themole/mole_abouttheshow.html&gt;The Mole&lt;/a&gt;.&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=83893"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=83893" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/afeng/aggbug/83893.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Aaron Feng</dc:creator>
            <guid>http://geekswithblogs.net/afeng/archive/2006/07/02/83893.aspx</guid>
            <pubDate>Mon, 03 Jul 2006 00:26:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/afeng/comments/83893.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/afeng/archive/2006/07/02/83893.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/afeng/comments/commentRss/83893.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/afeng/services/trackbacks/83893.aspx</trackback:ping>
        </item>
    </channel>
</rss>