<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" version="2.0"><channel><title>Jose's Blog</title><link>http://blogs.msdn.com/josealmeida/default.aspx</link><description>Musings on Software Engineering and Architecture</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><title>Asus Eee PC 1000H</title><link>http://blogs.msdn.com/josealmeida/archive/2008/10/21/asus-eee-pc-1000h.aspx</link><pubDate>Tue, 21 Oct 2008 22:51:11 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9010261</guid><dc:creator>josealmeida</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/josealmeida/comments/9010261.aspx</comments><wfw:commentRss>http://blogs.msdn.com/josealmeida/commentrss.aspx?PostID=9010261</wfw:commentRss><description>&lt;p&gt;I’m currently writing this post on a newly acquired Asus 1000H mini-notebook. I have to say that, so far, I’m really impressed with the device. The first thing I’ve noticed is the weight - it weighs about 1.2 Kg. It has a nice screen (10 inches), that has a maximum resolution of 1024x600. However, if you connect the device to an external monitor, it is capable of doing 1280x1024. On top of the screen there’s also an integrated 1.3 megapixel camera for video conference. &lt;/p&gt;  &lt;p&gt;I’ve looked at several mini-notebooks and most ones have the sound speakers to the sides of the screen or the keyboard, which reduces screen size or requires smaller (or less) keys. The 1000H has the speakers on the underside of the case, facing the user. The keyboard is a 92% keyboard, meaning that the keys are just a bit smaller and has less keys than a regular laptop keyboard. However, after a few days writing on this keyboard, I’m almost up to my usual productivity level (I just have a hard time hitting the right Shift key).&lt;/p&gt;  &lt;p&gt;There is so much more about this equipment that I’m really enjoying. It comes with a 160Gb SATA drive and a 10Gb SSD (solid state drive) built in. It features a stereo microphone and a multi-touch track pad. It has Bluetooth and a wireless-B,G, draft N network card. The main feature is, of course, the Atom 1.6 GHz processor, which makes the six cell battery pack last for over five hours. It has an SD card reader, a VGA-out connector, three USB 2.0 ports, an Ethernet card and a Kensington lock port.&lt;/p&gt;  &lt;p&gt;The device comes with 1Gb of RAM, but I upgraded it to 2Gb. I’m running Windows Vista Business edition, with Office 2007 Ultimate. I’m using the notebook for meetings and note taking, for mail, editing some documents, doing presentations, and running Excel. I think this covers most professional uses. With the present configuration, the device gets a 2,8 Windows Experience Index (just due to the 3D acceleration capabilities of the graphics card). However, Windows runs with Aero glass smoothly and the overall experience is great (after a few tweaks).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/josealmeida/WindowsLiveWriter/AsusEeePC1000H_1204D/image_2.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="300" alt="image" src="http://blogs.msdn.com/blogfiles/josealmeida/WindowsLiveWriter/AsusEeePC1000H_1204D/image_thumb.png" width="419" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;When I’m at the office, I have the notebook connected to an external monitor with an USB Keyboard and mouse. It’s a really great, highly portable work machine. Not for the power user, or hard core developer. Also not for video editing or gaming. Strictly for office use – documents, spreadsheets and the occasional web surfing. &lt;/p&gt;  &lt;p&gt;The main thing with this device is, of course, that the price is unbeatable. It’s a really low price for a machine with these characteristics. It’s a great value for money.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9010261" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/msdn/josealmeida/~4/LGhX6YH_Mqg" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/josealmeida/archive/tags/General/default.aspx">General</category></item><item><title>Right-Brain Thinking In Software Development</title><link>http://blogs.msdn.com/josealmeida/archive/2008/10/09/right-brain-thinking-in-software-development.aspx</link><pubDate>Thu, 09 Oct 2008 20:07:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8991215</guid><dc:creator>josealmeida</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/josealmeida/comments/8991215.aspx</comments><wfw:commentRss>http://blogs.msdn.com/josealmeida/commentrss.aspx?PostID=8991215</wfw:commentRss><description>I absolutely love software development. And what I love the most in software development is it’s creative aspect. I believe there is not one developer in the world who hasn’t yet experienced, at least once, an “eureka” moment. You know, those insights...(&lt;a href="http://blogs.msdn.com/josealmeida/archive/2008/10/09/right-brain-thinking-in-software-development.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8991215" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/msdn/josealmeida/~4/MZw2T8K30BE" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://blogs.msdn.com/josealmeida/archive/tags/General/default.aspx">General</category></item><item><title>Entrepreneurs: How to get started</title><link>http://blogs.msdn.com/josealmeida/archive/2008/09/23/entrepreneurs-how-to-get-started.aspx</link><pubDate>Tue, 23 Sep 2008 14:27:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8962133</guid><dc:creator>josealmeida</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/josealmeida/comments/8962133.aspx</comments><wfw:commentRss>http://blogs.msdn.com/josealmeida/commentrss.aspx?PostID=8962133</wfw:commentRss><description>&lt;P&gt;&lt;A target=_blank href="http://www.guykawasaki.com/index.shtml" mce_href="http://www.guykawasaki.com/index.shtml"&gt;Guy Kawasaki&lt;/A&gt; is a venture capitalist and one of the greatest public speakers in our industry. From his experience as a venture capitalist Guy’s written a very interesting post advising young entrepreneurs on how best to start their software company. &lt;/P&gt;
&lt;P&gt;So, if you’re planning on starting up your own company, &lt;A target=_blank href="http://blogs.openforum.com/2008/09/09/plan-b-for-fund-raising/" mce_href="http://blogs.openforum.com/2008/09/09/plan-b-for-fund-raising/"&gt;here’s&lt;/A&gt; a piece of advice from someone who has surely seen the raise and fall of many potential great companies.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8962133" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/msdn/josealmeida/~4/tSdsl3DOUvY" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/josealmeida/archive/tags/General/default.aspx">General</category></item><item><title>Creating a Customized Guidance Repository</title><link>http://blogs.msdn.com/josealmeida/archive/2008/09/19/creating-a-customized-guidance-repository.aspx</link><pubDate>Fri, 19 Sep 2008 04:55:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8958034</guid><dc:creator>josealmeida</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/josealmeida/comments/8958034.aspx</comments><wfw:commentRss>http://blogs.msdn.com/josealmeida/commentrss.aspx?PostID=8958034</wfw:commentRss><description>&lt;P&gt;As a consultant part of my job is to provide guidance to our customers on the best way to use our technology, namely in terms of application development practices. Over time, you start to better understand the type of customer you’re working with, what works, what doesn’t and you start to optimize your own delivery processes. You reuse material and refine it the next time around. That’s the nature of our work in the Services organization.&lt;/P&gt;
&lt;P&gt;Lately I’ve been involved in several engagements in the &lt;A target=_blank href="http://www.microsoft.com/services/microsoftservices/srv_apo.mspx" mce_href="http://www.microsoft.com/services/microsoftservices/srv_apo.mspx"&gt;Application Platform Optimization&lt;/A&gt; space, mainly the Application Lifecycle Management suite of Offerings.&lt;/P&gt;
&lt;P&gt;At the present I’m working with one customer who has gone through the &lt;A target=_blank href="http://download.microsoft.com/download/e/f/6/ef63554d-1685-48de-b684-2cb61cc99f49/alm_assessment.pdf" mce_href="http://download.microsoft.com/download/e/f/6/ef63554d-1685-48de-b684-2cb61cc99f49/alm_assessment.pdf"&gt;Assessment&lt;/A&gt; phase and we’ve arrived at a six phases maturity growth roadmap that they’re starting to implement. One of the key aspects of this type of custom engagement is that all the experience gained by the customer and all the guidance delivered by the consulting team, should be persisted by the customer. We’re working with a small team within the customer and they are the ones who will have the responsibility of creating their own guidance and internal best practices and sharing all this information with the rest of the organization. So to collect, persist, distribute and, later on, update their in-house customized guidance for application architecture, development and lifecycle management, we’ve chosen to use the &lt;A target=_blank href="http://www.codeplex.com/guidanceExplorer" mce_href="http://www.codeplex.com/guidanceExplorer"&gt;Guidance Explorer&lt;/A&gt; tool available on &lt;a href="http://www.codeplex.com"&gt;Codeplex&lt;/a&gt;.&lt;/P&gt;
&lt;P&gt;The use of this tool turned out to be a great fit for this scenario. Instead of compiling one giant document, that would go through several versions and would quickly fall out of synch, the customer is now publishing and updating guidance, based on an existing database of industry and technology best practices. Guidance articles have their own metadata, the lifecycle of each piece of guidance is independent of each other and, if needed, all the guidance can be compiled into a Word document for a hardcopy reference. Additionally, one of my favorite features is the ability to subscribe to the guidance through a published RSS feed and receive a notification whenever guidance changes or a new best practice is published.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8958034" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/msdn/josealmeida/~4/bEHriKwA8gw" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Agile/default.aspx">Agile</category><category domain="http://blogs.msdn.com/josealmeida/archive/tags/General/default.aspx">General</category><category domain="http://blogs.msdn.com/josealmeida/archive/tags/SCM/default.aspx">SCM</category><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Application+Lifecycle+Management/default.aspx">Application Lifecycle Management</category></item><item><title>Application Architecture Guide 2.0</title><link>http://blogs.msdn.com/josealmeida/archive/2008/09/19/application-architecture-guide-2-0.aspx</link><pubDate>Fri, 19 Sep 2008 02:47:25 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8957951</guid><dc:creator>josealmeida</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/josealmeida/comments/8957951.aspx</comments><wfw:commentRss>http://blogs.msdn.com/josealmeida/commentrss.aspx?PostID=8957951</wfw:commentRss><description>&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/practices/default.aspx"&gt;Patterns &amp; Practices&lt;/a&gt; team is finally going to update their fantastic &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/ms954595.aspx"&gt;Application Architecture Guide&lt;/a&gt;. Since it’s release in 2002 this guide has been a favorite of mine. It’s somewhat dated but it contains sound design principles that stand the test of time.&lt;/p&gt;  &lt;p&gt;Now the team is working on V2, which is &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/practices/bb232643.aspx"&gt;planned&lt;/a&gt; for the first half of 2009. You can follow their work through the &lt;a target="_blank" href="http://www.codeplex.com/AppArch"&gt;Application Architecture 2.0 Knowledge Base&lt;/a&gt; on &lt;a href="http://www.codeplex.com"&gt;Codeplex&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;You can also follow the work and additional discussions on the subject through &lt;a target="_blank" href="http://blogs.msdn.com/jmeier/"&gt;J. D. Meier’s blog&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;I believe this is a great piece of guidance and am sure it will help shape the near future of application and service architecture on the Microsoft platform.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8957951" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/msdn/josealmeida/~4/gFoltLu_XgA" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Architecture/default.aspx">Architecture</category></item><item><title>Synching TFS with other Source Control systems</title><link>http://blogs.msdn.com/josealmeida/archive/2008/09/17/synching-tfs-with-other-source-control-systems.aspx</link><pubDate>Wed, 17 Sep 2008 15:33:42 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8955402</guid><dc:creator>josealmeida</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/josealmeida/comments/8955402.aspx</comments><wfw:commentRss>http://blogs.msdn.com/josealmeida/commentrss.aspx?PostID=8955402</wfw:commentRss><description>&lt;p&gt;Many of us in the field have come across heterogeneous source control environments within the same organization. Some organizations, having multiple source control systems, wish to have some way of synchronizing TFS with their other systems. I've seen this when development teams who are used to the Microsoft development tools tend to prefer Team Foundation Sever and sometimes operations teams, who are responsible for deploying and maintaining the software produced internally maintain a portfolio of versions of the software in other control systems, like ClearCase for instance.&lt;/p&gt;  &lt;p&gt;The &lt;a target="_blank" href="http://www.codeplex.com/MigrationSyncToolkit/"&gt;TFS Migration and Synchronization Toolkit&lt;/a&gt; allows developers to build custom tools that provide migration and synchronization capabilities with other version control systems.&lt;/p&gt;  &lt;p&gt;There's a new version of this toolkit available in Codeplex. &lt;a target="_blank" href="http://www.codeplex.com/MigrationSyncToolkit/Release/ProjectReleases.aspx?ReleaseId=17337"&gt;This release&lt;/a&gt; includes enhanced support for the migration of branches and merges.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8955402" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/msdn/josealmeida/~4/1b19fXtk1_w" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/josealmeida/archive/tags/SCM/default.aspx">SCM</category><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Source+Control/default.aspx">Source Control</category><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Application+Lifecycle+Management/default.aspx">Application Lifecycle Management</category></item><item><title>Economics of Agile Software Development</title><link>http://blogs.msdn.com/josealmeida/archive/2008/09/17/economics-of-agile-software-development.aspx</link><pubDate>Wed, 17 Sep 2008 04:12:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8954639</guid><dc:creator>josealmeida</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/josealmeida/comments/8954639.aspx</comments><wfw:commentRss>http://blogs.msdn.com/josealmeida/commentrss.aspx?PostID=8954639</wfw:commentRss><description>&lt;p&gt;&lt;a target="_blank" href="http://collaboration.csc.ncsu.edu/laurie/index.html"&gt;Dr. Laurie Williams&lt;/a&gt; has been a long-time researcher on Agile methods and their impact on software engineering.&lt;/p&gt;  &lt;p&gt;She and her students have published a number of very interesting papers on varied subjects, particularly on the economics of agile practices, like Test Driven Development (TDD) or Pair Programming.&lt;/p&gt;  &lt;p&gt;You can find a list of publications &lt;a target="_blank" href="http://collaboration.csc.ncsu.edu/laurie/publications.html"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8954639" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/msdn/josealmeida/~4/Sj9HVMyvh1o" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Agile/default.aspx">Agile</category></item><item><title>Design in Context</title><link>http://blogs.msdn.com/josealmeida/archive/2008/09/13/design-in-context.aspx</link><pubDate>Sat, 13 Sep 2008 22:10:46 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8950748</guid><dc:creator>josealmeida</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/josealmeida/comments/8950748.aspx</comments><wfw:commentRss>http://blogs.msdn.com/josealmeida/commentrss.aspx?PostID=8950748</wfw:commentRss><description>&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; padding-top: 0px" id="scid:8747F07C-CDE8-481f-B0DF-C6CFD074BF67:1a72a044-a9c8-4282-8553-b19edd46d6d7" class="wlWriterSmartContent"&gt;&lt;a href="http://blogs.msdn.com/blogfiles/josealmeida/WindowsLiveWriter/DesigninContext_123E8/FallingwaterWright-8x6.jpg" title="Fallingwater, Bear Run, Pennsylvania (1939)" rel="thumbnail"&gt;&lt;img border="0" src="http://blogs.msdn.com/blogfiles/josealmeida/WindowsLiveWriter/DesigninContext_123E8/FallingwaterWright_10.png" /&gt;&lt;/a&gt;&lt;/div&gt;  &lt;p&gt;I have always been fascinated by building design and architecture. My brother is an architect and we have long talks on the subject, where we discuss not only the works of particular architects or artists, but the nature and profession of building design. I find these talks stimulating because I can relate to most of these topics as well.&lt;/p&gt;  &lt;p&gt;When it comes to software, however, I find the role of the architect not as defined as it is in construction. At least not yet, as there seems to be a lot of discussion going on about the nature and role of an Architect. The IT industry is not just about software, it's also about the enterprise, the infra-structure and so on. In IT we find infra-structure architects, solution architects and enterprise strategy architects, each focused on one type of architecture. There is one other aspect that, in my mind, widens the gap between architecture in software and in construction, is that architecture in construction is more akin to art than to science, while architecture in IT traditionally stems from engineering and is deeply rooted in science.&lt;/p&gt;  &lt;p&gt;So, regarding architecture in IT I keep asking myself two questions:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Is software architecture art or science? &lt;/li&gt;    &lt;li&gt;With so many software engineers available how do we articulate the value of and need for an architect? &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I won't address the first question here as it is somewhat metaphysical (not to mention controversial) and is food for another post at a later time. I have to admit I don't have a clear answer to either of these questions, but I venture that to find an answer (if an answer is to be found) we should look at the meaning of architecture in construction and in building design.&lt;/p&gt;  &lt;p&gt;In the conversations I've had with my brother around architecture, I became distinctly aware of the great importance architects place on &lt;strong&gt;context&lt;/strong&gt;: topological context, social context, design context, material context.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; padding-top: 0px" id="scid:8747F07C-CDE8-481f-B0DF-C6CFD074BF67:e84f3995-4f95-4bb5-a9d7-0a9ba11ff37b" class="wlWriterSmartContent"&gt;&lt;a href="http://blogs.msdn.com/blogfiles/josealmeida/WindowsLiveWriter/DesigninContext_123E8/564px-Prag_ginger_u_fred_gehry-8x6.jpg" title="Dancing House, Prague, Czech Republic" rel="thumbnail"&gt;&lt;img border="0" src="http://blogs.msdn.com/blogfiles/josealmeida/WindowsLiveWriter/DesigninContext_123E8/564px-Prag_ginger_u_fred_gehry_10.png" /&gt;&lt;/a&gt;&lt;/div&gt;  &lt;p&gt;Take a look, for instance, at the work of architects like &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Tadao_Ando"&gt;Tadao Ando&lt;/a&gt;, &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Mies_Van_der_Rohe"&gt;Mies Van der Rohe&lt;/a&gt;, &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Frank_Lloyd_Wright"&gt;Frank Lloyd Wright&lt;/a&gt; or even &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Frank_Gehry"&gt;Frank Ghery&lt;/a&gt; and you can see and feel how their buildings either are inserted into the context of the surrounding landscape or they provide a new context to the surrounding landscape. Even when the buildings are disruptive, they are so contextually (i.e. the disruption provides a new context to the surrounding elements).&lt;/p&gt;  &lt;p&gt;I venture that one of the greatest values of a software architect's to an IT organization is to provide &lt;strong&gt;software design in context&lt;/strong&gt;. With this I mean, the right design that satisfies a number of propositions, those being the requirements for the software, but also the context in which that software is to be built and operated. This context can be defined in many different ways, for instance tying a business goal to IT capabilities and mapping technology to those capabilities or understanding a services strategy for a given enterprise and designing a LOB application according to that strategy. It might seem obvious and common sense, but I find that this context is frequently overlooked or dismissed, causing numerous disruptions, like constant feature redefinition, scope creep, cost overruns and client dissatisfaction.&lt;/p&gt;  &lt;p&gt;In a time where IT is seen as a cost center and there is a generalized idea that most software is built like a house of cards without much structural integrity, it seems like confidence in IT as a strategic asset is dwindling. IT spending is becoming tighter and IT managers have to prove the value of IT to business stakeholders. Architects are a valuable asset to any IT organization in defining the principles for the IT eco-system (the IT context for the enterprise), helping to align business goals and IT capabilities.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8950748" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/msdn/josealmeida/~4/Fnhw8vMD334" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Architecture/default.aspx">Architecture</category></item><item><title>How To: Extend the Network Types for a Visual Studio Load Test</title><link>http://blogs.msdn.com/josealmeida/archive/2008/08/20/how-to-extend-the-network-types-for-a-visual-studio-load-test.aspx</link><pubDate>Wed, 20 Aug 2008 16:14:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8881219</guid><dc:creator>josealmeida</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/josealmeida/comments/8881219.aspx</comments><wfw:commentRss>http://blogs.msdn.com/josealmeida/commentrss.aspx?PostID=8881219</wfw:commentRss><description>&lt;P&gt;Out-of-the-box Visual Studio allows testers to define a network mix for load tests with the following network profiles:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;LAN&lt;/LI&gt;
&lt;LI&gt;T3 6.0 Mps&lt;/LI&gt;
&lt;LI&gt;T1&lt;/LI&gt;
&lt;LI&gt;Cable/DSL 1.5Mbps&lt;/LI&gt;
&lt;LI&gt;Cable/DSL 768k&lt;/LI&gt;
&lt;LI&gt;Cable/DSL 384k&lt;/LI&gt;
&lt;LI&gt;Dial-up 56k&lt;/LI&gt;
&lt;LI&gt;Dial-up 33.6k&lt;/LI&gt;
&lt;LI&gt;Dial-up 28.8k&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;If we want to add an additional entry, say "Dial-up 128k", we'll have to add a new network profile definition file.&lt;/P&gt;
&lt;P&gt;These files can be found in the following folder:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;C:\Program Files\Microsoft Visual Studio 9.0\Common7\ide\Templates\LoadTest\Networks&lt;/STRONG&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Just select an appropriate file (say "Dial-up 56k.network"), copy and rename it (to "Dial-up 128k.network") and edit it's contents accordingly:&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BACKGROUND-COLOR: #f4f4f4"&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Network&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Dial-up 128k"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;BandwidthInKbps&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="128"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Network&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;You'll have to close all Visual Studio instances and re-open them so that it can reload all network profiles.&lt;/P&gt;
&lt;P&gt;Related Links:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A class="" href="http://blogs.infosupport.com/marcelv/archive/2005/10/23/1809.aspx" mce_href="http://blogs.infosupport.com/marcelv/archive/2005/10/23/1809.aspx"&gt;Adding Firefox browser to load test you websites in Team System&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8881219" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/msdn/josealmeida/~4/4hUIFRBZqwo" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Testing/default.aspx">Testing</category><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/josealmeida/archive/tags/How+To/default.aspx">How To</category></item><item><title>Setting up a Visual Studio 2008 PowerShell Prompt</title><link>http://blogs.msdn.com/josealmeida/archive/2008/07/29/setting-up-a-visual-studio-2008-powershell-prompt.aspx</link><pubDate>Tue, 29 Jul 2008 17:52:35 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8789018</guid><dc:creator>josealmeida</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/josealmeida/comments/8789018.aspx</comments><wfw:commentRss>http://blogs.msdn.com/josealmeida/commentrss.aspx?PostID=8789018</wfw:commentRss><description>&lt;p&gt;I finally got some time to setup a powershell script that mimics the vcvars32.bat file that the Visual Studio 2008 command prompt loads (if you're on a 32-bit machine) and sets up all the environment variables for using the development command-line tools.&lt;/p&gt;  &lt;p&gt;To create your own VS 2008 PowerShell Prompt just create a text file and call it &amp;quot;vcvars32.ps1&amp;quot; and add the following content:&lt;/p&gt;  &lt;div style="border-right: gray 1px solid; padding-right: 4px; padding-left: 4px; font-size: 8pt; border-top: gray 1px solid; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 100%; cursor: text; max-height: 400px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; height: 286px; background-color: #f4f4f4"&gt;   &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;Write-Host &lt;span style="color: #006080"&gt;&amp;quot;Setting Powershell environment for using Microsoft Visual Studio 2008 x86 tools.&amp;quot;&lt;/span&gt;
$Env:VSINSTALLDIR=&lt;span style="color: #006080"&gt;&amp;quot;C:\Program Files\Microsoft Visual Studio 9.0&amp;quot;&lt;/span&gt;
$Env:VCINSTALLDIR=&lt;span style="color: #006080"&gt;&amp;quot;C:\Program Files\Microsoft Visual Studio 9.0\VC&amp;quot;&lt;/span&gt;
$Env:FrameworkDir=&lt;span style="color: #006080"&gt;&amp;quot;C:\Windows\Microsoft.NET\Framework&amp;quot;&lt;/span&gt;
$Env:FrameworkVersion=&lt;span style="color: #006080"&gt;&amp;quot;v2.0.50727&amp;quot;&lt;/span&gt;
$Env:Framework35Version=&lt;span style="color: #006080"&gt;&amp;quot;v3.5&amp;quot;&lt;/span&gt;

$WinSdkInstallFolder = (get-itemproperty -path &lt;span style="color: #006080"&gt;&amp;quot;HKLM:\SOFTWARE\Microsoft\Microsoft SDKs\Windows&amp;quot;&lt;/span&gt; -name CurrentInstallFolder).CurrentInstallFolder

&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ($WinSdkInstallFolder &lt;span style="color: #cc6633"&gt;-ne&lt;/span&gt; &lt;span style="color: #006080"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)
{
    $Env:WinSdk = $WinSdkInstallFolder
    $Env:Path = $WinSdkInstallFolder + &lt;span style="color: #006080"&gt;&amp;quot;bin;&amp;quot;&lt;/span&gt; + $Env:Path
    $Env:INCLUDE = $WinSdkInstallFolder + &lt;span style="color: #006080"&gt;&amp;quot;include;&amp;quot;&lt;/span&gt; + $Env:INCLUDE
    $Env:LIB = $WinSdkInstallFolder + &lt;span style="color: #006080"&gt;&amp;quot;lib;&amp;quot;&lt;/span&gt; + $Env:LIB
}

$Env:Path=&lt;span style="color: #006080"&gt;&amp;quot;C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE;C:\Program Files\Microsoft Visual Studio 9.0\VC\BIN;C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools;C:\Windows\Microsoft.NET\Framework\v3.5;C:\Windows\Microsoft.NET\Framework\v2.0.50727;C:\Program Files\Microsoft Visual Studio 9.0\VC\VCPackages;&amp;quot;&lt;/span&gt; + $Env:Path
$Env:INCLUDE = &lt;span style="color: #006080"&gt;&amp;quot;INCLUDE=C:\Program Files\Microsoft Visual Studio 9.0\VC\ATLMFC\INCLUDE;C:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE;&amp;quot;&lt;/span&gt; + $Env:INCLUDE
$Env:LIB = &lt;span style="color: #006080"&gt;&amp;quot;C:\Program Files\Microsoft Visual Studio 9.0\VC\ATLMFC\LIB;C:\Program Files\Microsoft Visual Studio 9.0\VC\LIB;&amp;quot;&lt;/span&gt; + $Env:LIB
$Env:LIBPATH = &lt;span style="color: #006080"&gt;&amp;quot;C:\Windows\Microsoft.NET\Framework\v3.5;C:\Windows\Microsoft.NET\Framework\v2.0.50727;C:\Program Files\Microsoft Visual Studio 9.0\VC\ATLMFC\LIB;C:\Program Files\Microsoft Visual Studio 9.0\VC\LIB;&amp;quot;&lt;/span&gt; + $Env:LIBPATH&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;To be able to execute scripts from a powershell prompt you need to set the correct execution policy for your environment. The default execution policy is &amp;quot;Restricted&amp;quot; which does not allow scripts to be run.&lt;/p&gt;

&lt;p&gt;You can choose to set the execution policy to allow signed scripts to be run or to disable it altogether (usual disclaimer: This option will allow untrusted scripts to be run, so make sure you know the implications and choose wisely...)&lt;/p&gt;

&lt;p&gt;To set the execution policy you can use the command:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;Set-ExecutionPolicy -executionpolicy &amp;lt;policy&amp;gt;&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To sign the script, you must go through the steps described by the following article:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;Get-Help about_signing&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;All that's left is to create a shortcut that runs your &amp;quot;vcvars32.ps1&amp;quot; script at startup. So, just create a new shortcut and set the following Target property:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoLogo -NoExit -File &amp;lt;path to your &amp;quot;vcvars32.ps1&amp;quot; file&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;PowerShell is a great tool for developers. Hope this helps you take advantage of it.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8789018" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/msdn/josealmeida/~4/LJ-p6_hwM6U" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/josealmeida/archive/tags/PowerShell/default.aspx">PowerShell</category><category domain="http://blogs.msdn.com/josealmeida/archive/tags/How+To/default.aspx">How To</category></item><item><title>HowTo... Configure a connection string like a pro.</title><link>http://blogs.msdn.com/josealmeida/archive/2008/07/03/howto-configure-a-connection-string-like-a-pro.aspx</link><pubDate>Thu, 03 Jul 2008 03:17:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8682480</guid><dc:creator>josealmeida</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/josealmeida/comments/8682480.aspx</comments><wfw:commentRss>http://blogs.msdn.com/josealmeida/commentrss.aspx?PostID=8682480</wfw:commentRss><description>&lt;p&gt;Ever wondered how to configure a connection string using the Data Link properties dialog?&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/josealmeida/WindowsLiveWriter/HowTo.Configureaconnectionstringlikea_DF3/image_4.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/josealmeida/WindowsLiveWriter/HowTo.Configureaconnectionstringlikea_DF3/image_thumb_1.png" width="232" height="289" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Well, I have. And just last night I decided to check out exactly how to do this. Here's a simple list with all the required steps:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Add a reference to &amp;quot;Microsoft OLE DB Service Component 1.0 Type Library&amp;quot; (it&amp;#8217;s in the COM Tab)&lt;/li&gt;    &lt;li&gt;Add a reference to the Primary Interop Assembly (PIA) for ADO (Add References &amp;gt; &lt;em&gt;adodb&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;Add the following code (for instance to a button click event handler): &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div style="border-right: gray 1px solid; padding-right: 4px; padding-left: 4px; font-size: 8pt; border-top: gray 1px solid; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;   &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;     &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; ADODB.Connection conn = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ADODB.Connection(); &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; oConn = (&lt;span style="color: #0000ff"&gt;object&lt;/span&gt;)conn;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; MSDASC.DataLinks dlg = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MSDASC.DataLinks(); &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt; dlg.PromptEdit(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; oConn);&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt; txtConnectionString.Text = conn.ConnectionString;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;We can also pre-assign the ConnectionString property of the Connection object before we open up the Data Link dialog. &lt;/p&gt;

&lt;p&gt;If we do this, the dialog is already filled with the configuration from the connection string.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8682480" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/msdn/josealmeida/~4/BdHykBsyWvo" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.msdn.com/josealmeida/archive/tags/How+To/default.aspx">How To</category></item><item><title>Branching Strategies</title><link>http://blogs.msdn.com/josealmeida/archive/2008/01/10/branching-strategies.aspx</link><pubDate>Thu, 10 Jan 2008 21:48:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7060999</guid><dc:creator>josealmeida</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/josealmeida/comments/7060999.aspx</comments><wfw:commentRss>http://blogs.msdn.com/josealmeida/commentrss.aspx?PostID=7060999</wfw:commentRss><description>&lt;P&gt;Under Software Configuration Management, branching and merging are common features that help maintain stable code bases and scale the development effort by synchronizing parallel development. However, depending on the size of your product, the size of your team, your isolation requirements and your development cycle, parallel development can become quite overwhelming, so it's very important to define a good strategy for branching and merging that meets your needs. This isn't always straightforward, so here are a couple of guidelines I usually use to tackle this issue.&lt;/P&gt;
&lt;P&gt;The first thing I try to find out are the isolation requirements for parallel development, how many development teams there are and what are the stabilization protocols (how many quality gates there are and how many different test environments there are where these gates are checked).&lt;/P&gt;
&lt;P&gt;Having this information helps me to define the logical structure for the branching strategy as well as the physical source control structure to support it.&lt;/P&gt;
&lt;P&gt;One thing I always have to look out for, is to make sure that the logical structure is applicable to the physical structure. For this I usually define a set of use cases that act as a model that I "run" on both the physical and logical structures to check if they are supported.&lt;/P&gt;
&lt;P&gt;Here are a couple of scenarios I usually contemplate:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Fixes 
&lt;LI&gt;Release Stabilization 
&lt;LI&gt;Code Promotion&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;I try to check all of these scenarios, considering that a mix (or all) of them might occur simultaneously. Here's a possible scenario I try to work out:&lt;/P&gt;
&lt;P&gt;"Imagine there's a team working on a new release of feature A, part of another team is working on a fix of a previously released version of their feature (feature B) while the rest of the team is working on the next version. In the meanwhile, a third team is required to release feature C to a new test environment for functional testing by end-users."&lt;/P&gt;
&lt;P&gt;Some questions that I might ask for this scenario:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;How many teams/features are there?&lt;/LI&gt;
&lt;LI&gt;What should the physical structure of my source control repository be?&lt;/LI&gt;
&lt;LI&gt;How many independent branches do I need to make this scenario valid?&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The &lt;A href="http://www.codeplex.com/BranchingGuidance" mce_href="http://www.codeplex.com/BranchingGuidance"&gt;Branching Guidance&lt;/A&gt; by the P&amp;amp;P team is an excellent place for different approaches to these questions and many more.&lt;/P&gt;
&lt;P&gt;So, what do I really look out for when defining a branching strategy?&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Good Logical Structure&lt;/LI&gt;
&lt;LI&gt;Good Physical Structure&lt;/LI&gt;
&lt;LI&gt;Make sure the logical structure is applicable to the physical structure&lt;/LI&gt;
&lt;LI&gt;Run a model on both the logical and physical structures.&lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7060999" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/msdn/josealmeida/~4/7MXWfHKiYsg" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://blogs.msdn.com/josealmeida/archive/tags/SCM/default.aspx">SCM</category><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Source+Control/default.aspx">Source Control</category><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Application+Lifecycle+Management/default.aspx">Application Lifecycle Management</category></item><item><title>WiX: Managed Custom Actions</title><link>http://blogs.msdn.com/josealmeida/archive/2004/11/08/wix-managed-custom-actions.aspx</link><pubDate>Mon, 08 Nov 2004 15:33:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:253831</guid><dc:creator>josealmeida</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/josealmeida/comments/253831.aspx</comments><wfw:commentRss>http://blogs.msdn.com/josealmeida/commentrss.aspx?PostID=253831</wfw:commentRss><description>&lt;p&gt;I've added WiX to my build process to automate the production of windows installer packages for my product. I'm not very proficient with Windows Installer technology, so I thought I might get by with what I've seen is already a "traditional" approach: dark an MSI created by a Visual Studio Setup Project. Well, I knew that this was not the right approach the moment I laid eyes on the script file I got from the decompiler. &lt;/p&gt; &lt;p&gt;However, it was sufficient to familiarize myself with the general structure of a WiX script. Soon after I decided to drop that script and start fresh. After a few dead-ends (that's when I used to refer to the Windows Installer SDK) I got my script working.&lt;/p&gt; &lt;p&gt;My thoughts on the subject are:&lt;/p&gt; &lt;ol style="margin-top: 0in; margin-bottom: 0in; margin-left: 1in; direction: ltr; unicode-bidi: embed" type="1"&gt; &lt;li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle; mso-outline-level: 2" value="1"&gt;Don't rely on the script you get from dark. It's confusing and things like setting up a virtual directory on a web server can be done with the WiX built-in custom actions in a very simple way;  &lt;li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle; mso-outline-level: 2" value="2"&gt;Debugging isn't easy and most of the time errors are unclear (However, from Rob's brownbag video, I suppose this is only temporary as there are plans to hook the WiX compiler to Visual Studio);  &lt;li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle; mso-outline-level: 2" value="3"&gt;The WiX documentation (for the schema) and the Windows Installer SDK will be your best friends while writing the script, so keep them handy.&lt;/li&gt;&lt;/ol&gt; &lt;p style="font-weight: bold; margin: 0in; text-decoration: underline; mso-outline-level: 1" mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-weight: bold; margin: 0in; text-decoration: underline; mso-outline-level: 1"&gt;Using Managed Custom Actions with WiX&lt;/p&gt; &lt;p&gt;Incorporating managed Custom Actions in WiX is a relatively simple task. However, you have to pay attention to a few details to avoid ending up with a headache just trying to figure out what's wrong with the script.&lt;/p&gt; &lt;p&gt;The first thing I did was making sure that the installer class was in the package, so I added a file reference for the assembly with the installer type.&lt;/p&gt; &lt;div style="border-right: gray 1px solid; padding-right: 4px; padding-left: 4px; font-size: 8pt; border-top: gray 1px solid; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.52%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; height: 41px; background-color: #f4f4f4"&gt; &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;File&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="InstallerFile"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="SAMPLE~1.DLL"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;LongName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="SampleInstaller.dll"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="$(var.BinFolder)\SampleInstaller.dll"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Vital&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="yes"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;KeyPath&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="yes"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;DiskId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;What's worth noting here is the specific Id for the file. I did this because it was necessary to reference that specific file later in the script, otherwise I just stuck with the Ids I got from tallow (for the rest of the files in the package).&lt;/p&gt;
&lt;p&gt;To setup WiX to execute a managed installer class as a Custom Action, I used 'InstallUtil'. This tool can be run from the command-line ('installutil.exe'), but what I really wanted to use was 'InstallUtilLib.dll'. In order to do this I added the following reference to the script:&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; padding-left: 4px; font-size: 8pt; border-top: gray 1px solid; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; height: 37px; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Binary&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="InstallUtil"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='$(var.BinFolder)\Installer Assemblies\InstallUtilLib.dll'&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you've ever darked (decompiler in the WiX toolset) a VS Setup Project that uses managed custom actions, you're probably familiar with the following script entries:&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; padding-left: 4px; font-size: 8pt; border-top: gray 1px solid; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; height: 36px; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Binary&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="VSDNETCFG"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Binary\VSDNETCFG.ibd"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This entry is used to produce a variable that is passed as part of the command-line arguments of installutillib. The variable is [VSDFxConfigFile] in the darked script.&lt;/p&gt;
&lt;p&gt;Upon close inspection this embedded file (VSDNETCFG.ibd) is a simple config file that provides run-time binding information. So, I just added it to the installation package:&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; padding-left: 4px; font-size: 8pt; border-top: gray 1px solid; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; height: 37px; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;File&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="ConfigFile"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="SAMPLE~2.XML"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;LongName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="SampleInstaller.dll.config"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="$(var.BinFolder)\SampleInstaller.dll.config"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Vital&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="yes"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;DiskId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Setting up the Custom Action is simple, albeit not trivial. The Custom Actions are calls to installutillib. My advice is to always check these using "InstallUtil.exe" via the command-line, to make sure they're working ok.&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; padding-left: 4px; font-size: 8pt; border-top: gray 1px solid; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;CustomAction&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='Uninstall'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;BinaryKey&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='InstallUtil'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;DllEntry&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='ManagedInstall'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Execute&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='deferred'&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;CustomAction&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='UninstallSetProp'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Property&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='Uninstall'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=' /installtype=notransaction /action=uninstall /LogFile= "[#InstallerFile]" "[#ConfigFile]"'&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;CustomAction&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='Install'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;BinaryKey&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='InstallUtil'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;DllEntry&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='ManagedInstall'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Execute&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='deferred'&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;CustomAction&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='InstallSetProp'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Property&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='Install'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=' /installtype=notransaction /action=install /LogFile= /BinDir="[TARGETDIR]\" /Package="[ProductName]" "[#InstallerFile]" "[#ConfigFile]"'&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;CustomAction&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='Rollback'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;BinaryKey&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='InstallUtil'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;DllEntry&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='ManagedInstall'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Execute&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='rollback'&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;CustomAction&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='RollbackSetProp'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Property&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='Rollback'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=' /installtype=notransaction /action=rollback /LogFile= "[#InstallerFile]" "[#ConfigFile]"'&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;CustomAction&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='Commit'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;BinaryKey&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='InstallUtil'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;DllEntry&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='ManagedInstall'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Execute&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='commit'&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;CustomAction&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='CommitSetProp'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Property&lt;/span&gt;&lt;span style="color: #0000ff"&gt;='Commit'&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=' /installtype=notransaction /action=commit /LogFile= "[#InstallerFile]" "[#ConfigFile]"'&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;There are a few particulars to note in the script fragment above:&lt;/p&gt;
&lt;ol style="margin-top: 0in; margin-bottom: 0in; margin-left: 1in; direction: ltr; unicode-bidi: embed" type="1"&gt;
&lt;li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle; mso-outline-level: 2" value="1"&gt;The values of the properties are passed to the custom action due to the fact that the Id and Property attributes match (so, make sure they do).&lt;/li&gt;&lt;/ol&gt;
&lt;p style="margin: 0in 0in 0in 0.5in; mso-outline-level: 2" mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style="margin-top: 0in; margin-bottom: 0in; margin-left: 1in; direction: ltr; unicode-bidi: embed" type="1"&gt;
&lt;li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle; mso-outline-level: 2" value="2"&gt;Make sure that the last parameter is the config file mentioned before. If this file cannot be found you'll probably get the following error:&lt;/li&gt;&lt;/ol&gt;
&lt;p style="margin: 0in 0in 0in 1in; mso-outline-level: 3"&gt;&lt;strong&gt;
&lt;blockquote style="margin-right: 0px" dir="ltr"&gt;
&lt;blockquote style="margin-right: 0px" dir="ltr"&gt;
&lt;blockquote style="margin-right: 0px" dir="ltr"&gt;&lt;pre&gt;InstallUtilLib.dll: Unknown error in CorBindToRuntimeHost (0x80131700).&lt;/strong&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;
&lt;ol style="margin-top: 0in; margin-bottom: 0in; margin-left: 1in; direction: ltr; unicode-bidi: embed" type="1"&gt;
&lt;li style="margin-top: 0px; margin-bottom: 0px; vertical-align: middle; mso-outline-level: 2" value="3"&gt;If you wish to pass some data to your custom action, like the parameters /BinDir or /Package in the install Custom Action above, make sure that if you're passing some Windows Installer property that returns a directory you enclose it in quotes and include a trailing backslash (&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsintro7/html/vxgrfcustomactiondataproperty.asp" mce_href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsintro7/html/vxgrfcustomactiondataproperty.asp"&gt;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsintro7/html/vxgrfcustomactiondataproperty.asp&lt;/a&gt;). If you don't, you might find yourself struggling with the following error:&lt;/li&gt;&lt;/ol&gt;
&lt;blockquote style="margin-right: 0px" dir="ltr"&gt;
&lt;blockquote style="margin-right: 0px" dir="ltr"&gt;
&lt;blockquote style="margin-right: 0px" dir="ltr"&gt;&lt;strong&gt;System.IO.FileNotFoundException: File or assembly name &amp;lt;assembly&amp;gt;, or one of its dependencies, was not found.&lt;/strong&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;
&lt;p&gt;After defining the Custom Actions all that's left is to sequence them in InstallExecuteSequence:&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; padding-left: 4px; font-size: 8pt; border-top: gray 1px solid; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Custom&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Action&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="InstallSetProp"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;After&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="StartServices"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;$SampleComponent&lt;span style="color: #ff0000"&gt;&amp;amp;gt;&lt;/span&gt;2&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Custom&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Custom&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Action&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Install"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;After&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="InstallSetProp"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;$SampleComponent&lt;span style="color: #ff0000"&gt;&amp;amp;gt;&lt;/span&gt;2&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Custom&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Custom&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Action&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="UninstallSetProp"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;After&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="MsiUnpublishAssemblies"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;$SampleComponent=2&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Custom&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Custom&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Action&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Uninstall"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;After&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="UninstallSetProp"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;$SampleComponent=2&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Custom&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Custom&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Action&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="CommitSetProp"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;After&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Rollback"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;$SampleComponent&lt;span style="color: #ff0000"&gt;&amp;amp;gt;&lt;/span&gt;2&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Custom&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Custom&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Action&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Commit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;After&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="CommitSetProp"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;$SampleComponent&lt;span style="color: #ff0000"&gt;&amp;amp;gt;&lt;/span&gt;2&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Custom&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Custom&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Action&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="RollbackSetProp"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;After&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Install"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;$SampleComponent&lt;span style="color: #ff0000"&gt;&amp;amp;gt;&lt;/span&gt;2&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Custom&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Custom&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Action&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Rollback"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;After&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="RollbackSetProp"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;$SampleComponent&lt;span style="color: #ff0000"&gt;&amp;amp;gt;&lt;/span&gt;2&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Custom&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In the end I was surprised at how simple, compact and clean I got my script, especially when compared to the one I got from dark. On another note I have to say that the WiX built-in Custom Actions were a huge help.&lt;/p&gt;&lt;/span&gt;&lt;pre&gt;&lt;/pre&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=253831" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/msdn/josealmeida/~4/sK6vOlriJg8" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/josealmeida/archive/tags/How+To/default.aspx">How To</category></item><item><title>Unit testing session</title><link>http://blogs.msdn.com/josealmeida/archive/2004/07/05/173147.aspx</link><pubDate>Mon, 05 Jul 2004 19:06:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:173147</guid><dc:creator>josealmeida</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/josealmeida/comments/173147.aspx</comments><wfw:commentRss>http://blogs.msdn.com/josealmeida/commentrss.aspx?PostID=173147</wfw:commentRss><description>&lt;P&gt;During TechEd'04 in Amsterdam I attended a Birds Of a Feather session on how to integrate unit testing into the Software Development Life-Cycle. For those who are unfamiliar with the format of these sessions, it's a speaker moderated discussion, where we can ask questions and have them answered and commented by the speaker and other attendees. I enjoyed this session format very much as it's highly interactive.&lt;/P&gt;
&lt;P&gt;This session was moderated by James Newkirk. The audience placed a few questions that led to various discussions on unit testing and the correct way to do them (or not to do them), unit testing techniques and personal experiences both positive and negative when using these techniques.&lt;/P&gt;
&lt;P&gt;Below are the topics discussed during this session and I thought of placing them here, along with some of my personal impressions on the various subjects.&lt;/P&gt;
&lt;OL style="MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in; MARGIN-LEFT: 0.5in; DIRECTION: ltr; unicode-bidi: embed" type=1&gt;
&lt;LI style="MARGIN-TOP: 0px; FONT-WEIGHT: bold; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle" value=1&gt;Testing abstract classes with different implementations&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;How to test a virtual implementation of a class, when different implementations can spawn at any time ?&lt;/P&gt;
&lt;P&gt;James Newkirk was of the opinion that you should abstract the tests when a new implementation appears.&lt;/P&gt;
&lt;P&gt;My opinion on the subject follows along the same lines. If I'm doing TDD, I want to write test code for all my implementation (this is my opinion on testing privates as well, BTW). So, I'm a firm believer in testing the implementation not the contract, because that's where my logic will be. It's also my opinion that I should code my unit tests just like I do my production code. So, when there's the need to do some refactoring in my unit test code, I'll do it. This includes doing an Extract Interface, or Extract Class, or any other abstraction refactoring.&lt;/P&gt;
&lt;OL style="MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in; MARGIN-LEFT: 0.5in; DIRECTION: ltr; unicode-bidi: embed" type=1&gt;
&lt;LI style="MARGIN-TOP: 0px; FONT-WEIGHT: bold; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle" value=2&gt;How much to test / testing privates&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;This is a topic that has always had strong arguments pro and against as was also evident in this session. While James Newkirk's opinion is not to test privates, I'm not so sure we shouldn't. James doesn't like to test the private methods, because it hinders refactoring. But if you don't have a test for a piece of logic, how can you refactor it (this seems like a catch 22 to me) ?&lt;/P&gt;
&lt;P&gt;As I've stated above I'm not so sure we shouldn't test private members. I guess that this depends on how I do TDD. There are two different approaches here. Write code test-first only considering the publicly visible members (or the public interface), or write tests for all your logic and during refactoring, if a given method turns out not to be used by any other class other than the test class, use the Hide Method refactoring. I use this last approach, for two reasons: &lt;/P&gt;
&lt;OL style="MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in; MARGIN-LEFT: 1in; DIRECTION: ltr; unicode-bidi: embed" type=a&gt;
&lt;LI style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle" value=1&gt;If I'm only coding tests for the public interface, I'll have no idea how much logic I'll be having "under the hood" or beneath the public interface. But typically, as someone pointed out during this discussion, this is were most of the logic will be; 
&lt;LI style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle" value=2&gt;The other reason is that this allows me to code this (soon to be) "internal" logic, using a test-driven approach, which gives me confidence in the implementation and how I refactor it.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;This approach, however, leaves me with a bunch of orphaned test methods, since they can no longer access the methods they should be exercising. This is when I usually refactor the test code as well, replacing method invocation with reflective method discovery and invocation.&lt;/P&gt;
&lt;OL style="MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in; MARGIN-LEFT: 0.5in; DIRECTION: ltr; unicode-bidi: embed" type=1&gt;
&lt;LI style="MARGIN-TOP: 0px; FONT-WEIGHT: bold; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle" value=3&gt;Legacy code w/o tests&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;The scenario is the following. You have a large code-base for which you don't have any unit tests. You'd like to add unit tests, but where do you start ?&lt;/P&gt;
&lt;P&gt;James answered this question in a very pragmatic way IMO. "Don't add unit tests for anything you aren't about to change." He said.&lt;/P&gt;
&lt;P&gt;Well this seems a very sensible decision. He then elaborated on this by stating that it could be done by establishing a virtual "boundary" of unit tests defined by the things about to be changed. Tests can be written against this "boundary" and the changes made on the inside of the boundary.&lt;/P&gt;
&lt;OL style="MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in; MARGIN-LEFT: 0.5in; DIRECTION: ltr; unicode-bidi: embed" type=1&gt;
&lt;LI style="MARGIN-TOP: 0px; FONT-WEIGHT: bold; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle" value=4&gt;How to convince people to code test-first?&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;I see this issue as a very hot topic. Primarily because, I have been trying to convince people to adopt this way of developing. And I know from personal experience that it's hard to find the right arguments. Strangely enough, I've found that direct management (PMs or Dev Leads) are more receptive to the message of TDD than the actual developers.&lt;/P&gt;
&lt;P&gt;James Newkirk stated that developing software "...is not about the individual developer, it's about the team and the continuous maintainability of the code". Someone also pointed out that "blinking lights changing from red to green help a lot!" I couldn't agree more.&lt;/P&gt;
&lt;P&gt;Additionally, James pointed out a "technique" that I've also used with some success, which is to ask someone to test their own code. Most of the times people find it hard to write tests against their own code, because they usually don't write their code to be tested.&lt;/P&gt;
&lt;P&gt;This debate spawned another thread of discussion. If the developers write unit tests, which was usually a big chunk of the work that was done by QA teams (white-box testing), the QA teams must start testing at a different (higher) level.&lt;/P&gt;
&lt;OL style="MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in; MARGIN-LEFT: 0.5in; DIRECTION: ltr; unicode-bidi: embed" type=1&gt;
&lt;LI style="MARGIN-TOP: 0px; FONT-WEIGHT: bold; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle" value=5&gt;Mock Objects&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Just like &lt;A href="http://www.benjaminm.net/"&gt;Benjamin&lt;/A&gt; posted, "James described mock objects as the situation where object A interacts with objects B and you need some way of 'switching out' Object B to create a 'dummy response' from the calls of Object A."&lt;/P&gt;
&lt;P&gt;True, but it's necessary to determine why would we want to 'switch out' Object B. I usually 'switch out' object B if it isn't part of my domain code (maybe it's an object belonging to a third-party API). If my Object B is, for instance a DAL component and it uses ADO.NET to connect to the database, I would use (dynamic) mock objects to replace the ADO.NET's data access components in object B using the "Inversion of Control" pattern. It may be somewhat complex, but it promotes decoupling and testability, which rate very high in my trade-off scale, so I usually think it's worth it and end up implementing it.&lt;/P&gt;
&lt;OL style="MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in; MARGIN-LEFT: 0.5in; DIRECTION: ltr; unicode-bidi: embed" type=1&gt;
&lt;LI style="MARGIN-TOP: 0px; FONT-WEIGHT: bold; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle" value=6&gt;Testing against a DB.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Sometimes it's hard to mock out the data access layer components, someone pointed out. This is true and there's usually a tendency to end up testing against the database.&lt;/P&gt;
&lt;P&gt;Actually, James Newkirk says that there are situations where he prefers to test against the database. "When writing unit tests for DAL components use the actual database. When writing unit tests for components that use DAL components, mock out the DAL components." James said.&lt;/P&gt;
&lt;P&gt;I have a different point of view. If the DAL components where written by me, I'd like to test not only the components that use the DAL components, but also the interaction between them. On the other hand, data connectivity components supplied by the underlying API (system or third-party) are not part of my domain code and I can&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;(and probably should) mock them out.&lt;/P&gt;
&lt;OL style="MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in; MARGIN-LEFT: 0.5in; DIRECTION: ltr; unicode-bidi: embed" type=1&gt;
&lt;LI style="MARGIN-TOP: 0px; FONT-WEIGHT: bold; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle" value=7&gt;How long should tests run ?&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;This was an interesting point, as people have very different experiences. Someone said they had test that took 6 hours to complete, others have them built into the build process and run the whole suite nightly for as long as they take. Another delegate's tests took about 2 hours to complete.&lt;/P&gt;
&lt;P&gt;In James' opinion, 1 hour is too long, because tests should provide rapid feedback to the developer and promote a very fast turn around in the development lifecycle. The recommendation that came out of this debate was that in large projects we should separate developer unit tests and run all the tests (all test suites from all developers) during the daily build cycle. Some integration problems will arise only during build, but it's a trade-off.&lt;/P&gt;
&lt;OL style="MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in; MARGIN-LEFT: 0.5in; DIRECTION: ltr; unicode-bidi: embed" type=1&gt;
&lt;LI style="MARGIN-TOP: 0px; FONT-WEIGHT: bold; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle" value=8&gt;Automatic test generation.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Commercial products don't take into account the actual intention of the methods being tested and so usually create 'poor' tests. On the other hand, Visual Studio Team System has a built-in functionality to implement a boiler plate test for any given method.&lt;/P&gt;
&lt;OL style="MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in; MARGIN-LEFT: 0.5in; DIRECTION: ltr; unicode-bidi: embed" type=1&gt;
&lt;LI style="MARGIN-TOP: 0px; FONT-WEIGHT: bold; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle" value=9&gt;How do you unit test GUIs ?&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;In any discussion on unit testing this topic usually comes up. In this session people mentioned some commercial products that they've used with some success, although they couldn't survive for more than a few builds without breaking them. A pretty "standard" response to this issue is to use the Model View Controller design pattern to separate presentation and presentation control logic and eventually test them individually.&lt;/P&gt;
&lt;P&gt;The problem is that when we're coding unit tests against an API, the interface is programmatic, whilst when we are coding unit tests for a GUI, the interface is visual and designed for human and not machine interaction.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/josealmeida/archive/2004/06/15/UnitTestingUserInterfaces.aspx"&gt;I've used NUnitForms&lt;/A&gt; and NUnitASP with some success to get around this situation and exercise the visual elements of the GUI individually. The main drawback with both of these extensions to NUnit is the relatively small number of controls supported (granted that they are the most used).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Well, a few other questions and discussions came up, but were marginal to the previous ones that were the main thread of the session.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=173147" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/msdn/josealmeida/~4/XO9zg_xRDpc" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Testing/default.aspx">Testing</category></item><item><title>Unit Testing User Interfaces (Updated!)</title><link>http://blogs.msdn.com/josealmeida/archive/2004/06/15/UnitTestingUserInterfaces.aspx</link><pubDate>Tue, 15 Jun 2004 23:13:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:156101</guid><dc:creator>josealmeida</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/josealmeida/comments/156101.aspx</comments><wfw:commentRss>http://blogs.msdn.com/josealmeida/commentrss.aspx?PostID=156101</wfw:commentRss><description>Usually one of the major difficulties a developer faces when writing unit tests is how to write test code for User Interfaces. This is particularly important when we're doing Test-Driven Development....(&lt;a href="http://blogs.msdn.com/josealmeida/archive/2004/06/15/UnitTestingUserInterfaces.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=156101" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/msdn/josealmeida/~4/Y1IUnywWp3o" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Agile/default.aspx">Agile</category><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Testing/default.aspx">Testing</category><category domain="http://blogs.msdn.com/josealmeida/archive/tags/Post+Updates/default.aspx">Post Updates</category></item></channel></rss>
