<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Ivo Manolov's Blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/ivo_manolov/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/ivo_manolov/feed.xml</link>
    <description>.NET, WPF and Win32 Programming</description>
    <lastBuildDate>Thu, 02 Apr 2015 18:52:17 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Model-View-ViewModel (MVVM) Applications: General Introduction</title>
      <link>https://docs.microsoft.com/archive/blogs/ivo_manolov/model-view-viewmodel-mvvm-applications-general-introduction</link>
      <pubDate>Sat, 17 Mar 2012 16:35:31 GMT</pubDate>
      <dc:creator><![CDATA[ivom1]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ivo_manolov/2012/03/17/model-view-viewmodel-mvvm-applications-general-introduction/</guid>
      <description><![CDATA[MVVM is a central concept in WPF, Silverlight, WindowsPhone and Windows 8 development, so I...]]></description>
      <content:encoded><![CDATA[<blockquote>   <p><em>MVVM is a central concept in WPF, Silverlight, WindowsPhone and Windows 8 development, so I decided to take some time and bubble up some of the content in the </em><a href="https://wpf.codeplex.com/wikipage?title=WPF%20Model-View-ViewModel%20Toolkit&amp;referringTitle=Home"><em>WPF MVVM Toolkit</em></a><em>, which we created some time ago.</em></p> </blockquote>  <p>Model-View separation is by no means a novel idea in the software engineering industry—the idea has been around for at least 25 years. In the past few years, there has been a lot of interest in model-view architectures, fuelled both by the growing complexity of modern software systems and by the necessity to display UI on various devices, while reusing the same underlying business logic.</p>  <p>This post outlines the benefits of model-view separation. It is essentially the same content as the content included in Part 1 of the documentation, which goes with the WPF MVVM Toolkit. </p>  <h1>1. Introduction to the Model-View-X Paradigm</h1>  <p>A well-designed application is an application that is easy to develop, test, maintain, and evolve. Creating such an application typically involves some form of <i>separation and encapsulation of responsibilities</i>. A common approach involves separation of the UI (the views) from the business logic (the model). In fact, that approach is so common that there are a number of stock solutions, collectively known as the <i>model-view design patterns:</i></p>  <ul>   <li><u>Model-View-Controller (MVC)</u> is the granddaddy of them all, dating back to 1979. In MVC, the Controller creates the Views and the Model. The Views register with the Controller, which also has a reference to the Model. A View notifies the Controller of user interactions, and the Controller in turn queries the View for its state and updates the Model appropriately. The Controller notifies the Views when there are changes in the Model, and the Views query the controller to update their states.       <br />      <br /></li>    <li><u>Model-View-ViewModel (MVVM)</u> is a derivative of MVC that takes advantage of particular strengths of the Windows Presentation Foundation (WPF) architecture to separate the Model and the View by introducing an abstract layer between them: a “Model of the View,” or ViewModel. The pattern was first introduced by <strong>John Gossman</strong> – the architect on the Blend/WPF/Silverlight team – and derives from the Smalltalk ApplicationModel pattern, as does the PresentationModel pattern described by Martin Fowler. It was first utilized by the Expression team (John was part of that team at the time) as they developed version 1 of Expression Blend. Without the WPF/Silverlight-specific aspects, the Model-View-ViewModel pattern is identical to PresentationModel.       <br />      <br />In MVVM, the View and the ViewModel are typically instantiated by the container application. The View keeps a reference to the ViewModel. The ViewModel exposes commands and observable entities (“bindables”) that the View binds to (or to put it in programming terms, view.DataContext = viewModel;). User interactions with the View trigger commands on the ViewModel, and updates in the ViewModel are propagated to the View through data binding. </li> </ul>  <h1>&#160;</h1>  <h1>2. Justification</h1>  <h2>2.1. Simplistic Application Design</h2>  <p>To demonstrate the use of the Model-View-X architecture, let’s consider a simple contacts application. The application has two windows (views): a table view, where you can see all entries in the contact book in a table, and a record view, where you can see individual records. </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/6507.clip_image002_46B4FC7F.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/6507.clip_5F00_image002_5F00_46B4FC7F.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="clip_image002" border="0" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/8255.clip_image002_thumb_25C189D8.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/8255.clip_5F00_image002_5F00_thumb_5F00_25C189D8.jpg" width="623" height="249" /></a></p>  <p align="center"><strong>Fig. 1</strong> UI of the contacts application</p>  <p>The Model-View separation for this particular problem feels natural, where the Model is the contact book and the Views are the two windows shown in Figure 1. So the trivial design (which is a two-tier Model-View-only design) would look as shown on Figure 2.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/5432.clip_image002_7A10BFDB.gif" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/5432.clip_5F00_image002_5F00_7A10BFDB.gif"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="clip_image002" border="0" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/3465.clip_image002_thumb_247CF0F9.gif" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/3465.clip_5F00_image002_5F00_thumb_5F00_247CF0F9.gif" width="595" height="377" /></a></p>  <p align="center"><strong>Fig. 2</strong> Simplistic application design – the views are directly connected to the model</p>  <p>As shown, ContactBook keeps a list of views (which are added and removed with AttachView and DetachView). When a contact changes, ContactBook notifies all views by calling their Update methods, and all views update themselves by calling the model's GetContacts method. Upon instantiation, RecordView and TableView are given a reference to ContactBook, which they keep as a field (contactBook). </p>  <blockquote>   <p><font color="#c0504d"><em>Notice how the two views are tightly coupled with the <b>ContactBook</b> class. Addition of business logic would only increase the level of coupling.</em></font></p> </blockquote>  <h2>&#160;</h2>  <h2>2.2. Simplistic Application Design – WPF/Silverlight Version </h2>  <p>Before examining the design further, let’s convert the design to a WPF/Silverlight-friendly design. WPF/Silverlight provides the following native facilities that can be utilized directly:</p>  <ul>   <li><i>Databinding</i> is the ability to bind UI elements to any data. </li>    <li><i>Commands</i> provide the ability to notify the underlying data of changes in the UI. </li> </ul>  <p>Using these facilities, the WPF/Silverlight-friendly design is changed as follows:</p>  <p><b><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/0652.clip_image0026_7CD674CE.gif" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/0652.clip_5F00_image0026_5F00_7CD674CE.gif"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="clip_image002[6]" border="0" alt="clip_image002[6]" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/2308.clip_image0026_thumb_6A217B17.gif" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/2308.clip_5F00_image0026_5F00_thumb_5F00_6A217B17.gif" width="595" height="205" /></a></b></p>  <p align="center"><strong>Fig. 3</strong> WPF/Silverlight-friendly simplistic application design</p>  <p>In the modified design in Figure 3, the views derive from <b>UserControl</b> (there is no need for an abstract View class) and ContactBook no longer needs to maintain a list of views—ContactBook no longer needs to know about the views. Instead, the views point to ContactBook as their <b>DataContext</b> and use WPF data-binding to bind to the list of contacts. </p>  <p>You will also notice that List&lt;Contact&gt; has been replaced with <a href="https://msdn.microsoft.com/en-us/library/ms668604.aspx">ObservableCollection</a>&lt;Contact&gt; to allow the views to bind to the ContactBook using WPF data-binding mechanisms.</p>  <blockquote>   <p><em><font color="#c0504d">Notice how WPF’s data-binding mechanism allows us to create a much more a loosely coupled design (at least until further addition of business logic).</font></em></p> </blockquote>  <h2>&#160;</h2>  <h2>2.3. Problems with the Simplistic Design</h2>  <p>Things get more complicated if we introduce the following new functionality:</p>  <ol>   <li>Track the selected item, so that we update RecordView whenever the selection in TableView changes, and vice versa. </li>    <li>Enable or disable parts of the UI of RecordView and TableView based on some rule (for example, highlight any entry that has an e-mail in the live.com domain). </li> </ol>  <p>Feature (a) can be implemented by adding a<b> </b>CurrentEntry property directly in ContactBook. This solution breaks down, however, if you have more than one instance of the UI connected to the same ContactBook. Feature (b) can be implemented in the views (RecordView and TableView). The problem if we do that, however, is that if we want to change the rule, then we would need to change both views. </p>  <p>Gradually it becomes apparent that we need a third layer in our application. We need a layer between the views and ContactBook that stores state shared by the views. We need a <i>meta-view</i> of sorts.</p>  <h2>&#160;</h2>  <h2>2.4. Enter Model-View-ViewModel (MVVM)</h2>  <p>A ViewModel can serve as the third layer, providing an abstraction that acts as a meta-view<i> </i>(a model of a view), storing state and policy that are shared by a group of views. By introducing the concept of a ViewModel, our design changes to the following:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/0714.clip_image0028_427AFEED.gif" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/0714.clip_5F00_image0028_5F00_427AFEED.gif"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="clip_image002[8]" border="0" alt="clip_image002[8]" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/7242.clip_image0028_thumb_61BDA5C0.gif" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/7242.clip_5F00_image0028_5F00_thumb_5F00_61BDA5C0.gif" width="659" height="203" /></a></p>  <p align="center"><strong>Fig. 4</strong> Application design using a ViewModel</p>  <p>In this design, the views know of the ViewModel and bind to its data, to be able to reflect any changes in it. The ViewModel has no reference to the views—it holds only a reference to the model. </p>  <p>For the views, the ViewModel acts both as a façade to the model, but also as a way to share state between views (selectedContacts in the example). In addition, the ViewModel often exposes commands that the views can bind to and trigger.This use of commands is covered in the next section.</p>  <h2>&#160;</h2>  <h2>2.5. The use of commanding in MVVM Applications</h2>  <p>WPF and Silverlight introduce a new input programming mechanism: <a href="https://msdn.microsoft.com/en-us/library/ms752308.aspx">commanding</a>. Commands allow loose coupling between the origin and the handling of an action. Multiple sources can invoke the same command, and the same command can be handled differently depending on the target. All commands implement the <a href="https://msdn.microsoft.com/library/system.windows.input.icommand.aspx">ICommand</a> interface. </p>  <p>For UI actions, WPF provides a specialized <a href="https://msdn.microsoft.com/en-us/library/system.windows.input.routedcommand.aspx">RoutedCommand</a> class. A <b>RoutedCommand</b> is routed through the UI element tree, so the target of a <b>RoutedCommand</b> must be part of the UI element tree. In MVVM designs, however, command targets are often implemented in the ViewModels, which in turn are not typically part of the UI element tree. This requires the introduction of a different kind of command—the <a href="https://msdn.microsoft.com/en-us/library/cc707894.aspx">DelegateCommand</a>—that implements <b>ICommand</b> and can have non-UI elements as its target. </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/1374.clip_image00210_2EED9F4C.gif" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/1374.clip_5F00_image00210_5F00_2EED9F4C.gif"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="clip_image002[10]" border="0" alt="clip_image002[10]" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/5187.clip_image00210_thumb_2042F367.gif" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/5187.clip_5F00_image00210_5F00_thumb_5F00_2042F367.gif" width="660" height="279" /></a></p>  <p align="center"><strong>Fig. 5</strong> Application design using a ViewModel, exposing bindable commands</p>  <p>The DelegateCommand construct was originally introduced during the development of Microsoft Expression Blend version 1. A generic version of DelegateCommand was later released as part of the <a href="https://msdn.microsoft.com/en-us/library/dd458807.aspx">Composite Application Guidance for WPF</a> on MSDN. Note that some MVVM sources refer to the same construct as RelayCommand.</p>  <p>A <b>DelegateCommand</b> is an <b>ICommand</b> that allows the views to bind to the ViewModel. Even though the diagram above does not show this explicitly, all ICommands exposed by the ViewModel are DelegateCommands. For example, the code for the AddContactCommand in the ViewModel may look as follows:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/0218.image_54771CAD.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/0218.image_5F00_54771CAD.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/2451.image_thumb_37FA2ACD.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/2451.image_5F00_thumb_5F00_37FA2ACD.png" width="648" height="238" /></a></p>  <p>&#160;</p>  <h1>3. Benefits and Consequences of Using MVVM</h1>  <p>The benefits of MVVM are the following:</p>  <ul>   <li>A ViewModel provides a single store for presentation policy and state, thus improving the reusability of the Model (by decoupling it from the Views) and the replaceability of the Views (by removing specific presentation policy from them). </li>    <li>The Model-View-ViewModel design improves the overall testability of the application. One can easily create unit tests that target the Model and the ViewModel layers. The MVVM design also improves the “mockability” of the application, by allowing easy run-time simulation of the tiers, which is crucial to testing complex software products. </li>    <li>The Model-View-ViewModel design is a very loosely coupled design. The View holds a reference to the ViewModel, and the ViewModel holds a reference to the Model. The rest is done by the data-binding and commanding infrastructure of WPF. </li> </ul>  <p>The consequences of MVVM are the following:</p>  <ul>   <li>The typical relationship between a ViewModel and the corresponding Views is one-to-many, but there are also situations where that is not necessarily true. In general, any business logic and input-handling business logic (selection tracking, and so on) is kept in the ViewModel. </li>    <li>There are situations when one ViewModel is aware of another ViewModel within the same application. Such situations arise when there is a master-subordinate relationship between two ViewModels or when a ViewModel represents a single item (for example, the visual representation state of a single contact). When this happens, one ViewModel can represent a collection of ViewModels. Such a case in demonstrated in the 2nd part of documentation that comes with the <a href="https://wpf.codeplex.com/wikipage?title=WPF%20Model-View-ViewModel%20Toolkit&amp;referringTitle=Home">WPF MVVM Toolkit</a>. </li> </ul>  <h1>&#160;</h1>  <h1>4. Next Steps and References</h1>  <p>Hopefully this post provides a simple introduction to the pattern. As a next step, download the <a href="https://wpf.codeplex.com/wikipage?title=WPF%20Model-View-ViewModel%20Toolkit&amp;referringTitle=Home">WPF MVVM Toolkit</a>, review the walk-through and the provided code and go write some apps. </p>  <p>It is important to note that there are a number of other (more full-featured) MVVM toolkits out there. Perhaps the most popular one is <a href="https://mvvmlight.codeplex.com/">Laurent Bugnion’s MVVM Light</a>, but there are many others <a href="https://www.codeplex.com/site/search?query=mvvm&amp;ac=8">on Codeplex</a>. You should be using those for your WPF / Silverlight / Windows Phone and Windows 8 applications. Here are a few additional references that may help too:</p>  <ul>   <li><a href="https://martinfowler.com/eaaDev/PresentationModel.html">Presentation Model</a> by Martin Fowler, July 2004. </li>    <li><a href="https://blogs.msdn.com/johngossman/archive/2005/10/08/478683.aspx">Introduction to Model/View/ViewModel pattern for building WPF apps</a> by John Gossman, October 2005. </li>    <li><a href="https://www.martinfowler.com/eaaDev/SeparatedPresentation.html">Separated Presentation</a> by Martin Fowler, June 2006. </li>    <li><a href="https://blogs.sqlxml.org/bryantlikes/archive/2006/09/27/WPF-Patterns.aspx">WPF Patterns</a> by Bryan Likes, September 2006. </li>    <li><a href="https://www.orbifold.net/default/?p=550">WPF patterns: MVC, MVP or MVVM or…?</a> by the Orbifold, December 2006. </li>    <li><a href="https://blogs.msdn.com/mikehillberg/archive/2008/05/21/Model-see_2C00_-model-do.aspx">Model-see, Model-do, and the Poo is Optional</a> by Mike Hillberg, May 2008. </li>    <li><a href="https://msdn.microsoft.com/en-us/magazine/cc785479.aspx">PRISM: Patterns for Building Composite Applications with WPF</a> by Glenn Block, September 2008. </li>    <li><a href="https://blogs.msdn.com/dphill/archive/2009/01/31/the-viewmodel-pattern.aspx">The ViewModel Pattern</a> by David Hill, January 2009. </li>    <li><a href="https://msdn.microsoft.com/en-us/magazine/dd419663.aspx">WPF Apps with the Model-View-ViewModel Design Pattern</a> by Josh Smith, February 2009. </li> </ul>]]></content:encoded>
    </item>
    <item>
      <title>Principles 5: End-to-End Development Process (for Large Projects)</title>
      <link>https://docs.microsoft.com/archive/blogs/ivo_manolov/principles-5-end-to-end-development-process-for-large-projects</link>
      <pubDate>Thu, 21 Apr 2011 23:21:00 GMT</pubDate>
      <dc:creator><![CDATA[ivom1]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ivo_manolov/2011/04/21/principles-5-end-to-end-development-process-for-large-projects/</guid>
      <description><![CDATA[Series Index     Principles 1: The Essence of Driving – A Crash Course in Project Management...]]></description>
      <content:encoded><![CDATA[<h1>Series Index</h1>  <ul>   <li><a href="https://blogs.msdn.com/b/ivo_manolov/archive/2010/07/18/10039624.aspx">Principles 1: The Essence of Driving – A Crash Course in Project Management</a> </li>    <li><a href="https://blogs.msdn.com/b/ivo_manolov/archive/2010/07/23/10042059.aspx">Principles 2: Principles of Software Testing</a> </li>    <li><a href="https://blogs.msdn.com/b/ivo_manolov/archive/2010/08/01/10044780.aspx">Principles 3: Principles of Software Development</a> </li>    <li><a href="https://blogs.msdn.com/b/ivo_manolov/archive/2010/09/10/10060204.aspx">Principles 4: End-to-End Development Process</a> </li>    <li><a href="https://blogs.msdn.com/b/ivo_manolov/archive/2011/04/21/10136580.aspx" target="_blank">Principles 5: End-to-End Development Process&#160;&#160; (for Large Projects)</a> </li> </ul>  <p align="center">+++</p>  <p align="left">This fifth post discusses and end-to-end development process for large software projects. </p>  <p align="left">The only difference between large and small projects is that large projects require more “supporting infrastructure” (more processes, etc.) than small projects, due to the fundamentally imperfect communication between the team members. The “supporting infrastructure” is a tax we have to pay when we develop software. We can minimize it, but we can never really avoid it completely.</p>  <blockquote>   <p align="left"><strong><em>Larger projects require larger teams, which (due to accumulated communication imperfections) require larger process tax. </em></strong></p> </blockquote>  <p align="left">On one hand, we like short product cycles, because they get the product out in the market quickly; on another hand, the shorter the cycle, the higher the ratio between process tax and actual productive time. This is a classic case of an optimization problem, which can be defined as…</p>  <blockquote>   <p align="left"><strong><font color="#0000ff"><em><font size="3">“Find the shortest possible project cycle, that keeps the process tax at a reasonably low level</font></em>“.</font></strong></p> </blockquote>  <p>Clearly, there’s a variety of other factors that we need to consider when we talk about project and product cycles. To list a few, we need to factor in the general product business model, pre-existing contractual obligations, specific calendar events such as conferences or trade shows, the competitive landscape, etc. For the purpose of this article we can assume that all of these additional factors have already been taken into consideration.</p>  <p>&#160;</p>  <h1>Single Project Rhythm</h1>  <p>I am a big believer in having a single, transparent, well-socialized and strictly enforced project rhythm. All products that an organization delivers in my opinion should be aligned to this single rhythm.&#160; The rhythm (or cycle) should be short enough, so that it can accommodate all products in development. In this model, different products can take different number of cycles. At the end of every cycle, one or more products get released. </p>  <p>Having a single cycle in my opinion dramatically decreases the complexity (and ultimately the process tax) that a team has to pay. It helps create well-aligned, synchronized and cohesive organizations, reduces dramatically the release management costs of a product, practically eliminates context switching for the individual engineers, drives ownership deep into the organization, improves communication with supporting disciplines (docs, localization, support, sustained engineering), and so on.</p>  <p>&#160;</p>  <h1>Agility</h1>  <p>In this model, agility is achieved by having an appropriately-sized cycle. For example, for a desktop OS the right cycle may be 6 months or 12 months. In contrast, a web site would probably need to have a release valve every 2 to 4 weeks. Agility doesn’t mean lack of planning – agility means a reasonably short cycle capable of getting high quality products out in a predictable, controlled fashion.</p>  <p>&#160;</p>  <h1>Process Summary</h1>  <p>The process of developing a large software project can be organized in 4 major phases (see Fig. 1 below):</p>  <ol type="A">   <li>MQ </li>    <li>Pre-planning and Planning </li>    <li>1 or more Development Cycles </li>    <li>Stabilization and Release </li> </ol>  <p>(A) and (B) happen simultaneously. (A) is “Milestone for Quality” targeted at constructing a high-quality “software production factory”. This milestone gives the engineering organization a chance to optimize and simplify the tools and processes that it uses to product the product. (B) follows a predefined planning process. Planning is a whole other topic in itself. (C) consists of one or more close-looped development cycles.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/5488.image_21C68533.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/5488.image_5F00_21C68533.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="Figure 1  Development Process Outline" border="0" alt="Development Process Outline" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/1072.image_thumb_52E5BFD3.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/1072.image_5F00_thumb_5F00_52E5BFD3.png" width="589" height="229" /></a></p>  <p align="center"><strong>Figure 1</strong>&#160; Development Process Outline</p>  <p>Obviously this is just a general outline. The size of the different phases has to be determined by the development organization, based on deep understanding of what needs to happen in these phases and on the current state of the business and of the development factory. Some phases (specifically A and B) may shrink if there is no need for them. </p>  <p>Below I show an actual implementation of this general outline. Each small rectangle represents one week. Weeks in green are “stabilization weeks” (stabilization has different meaning for the different milestones – see tables below). Note again that the size of the actual milestones and phases that I show below are just a specific implementation of the general outline. You can have development cycles that are as short as a week, if you think that the ratio of dev time to process tax associated with managing every cycle is reasonable. You can also have longer cycles, although I personally wouldn’t recommend cycles that are significantly longer that 18 weeks or so. </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/7026.image_4E6F3F0C.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/7026.image_5F00_4E6F3F0C.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Figure 2  Development Process - Detailed View" border="0" alt="Development Process - Detailed View" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/5861.image_thumb_391189A4.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/5861.image_5F00_thumb_5F00_391189A4.png" width="100%" /></a></p>  <p align="center"><strong>Figure 2&#160; </strong>Development Process - Detailed View</p>  <p>With these sizes we have…</p>  <ul>   <li>About 18 weeks (4 months) of pre-planning and planning activities. </li>    <li>One or more dev cycles of 15 weeks (3.5 months) </li>    <li>Final stabilization of 10 weeks (2.5 months) </li> </ul>  <p>I.e. a release with 1 dev cycle takes about 9.5 months; a release with 2 dev cycles takes about 13 months, etc.</p>  <p>The number of the actual development cycles can vary and is a purely business decision. At the end of every development cycle, the organization delivers shippable functionality. When management deems that the available payload makes sense as a next major version of the product, they switch the team to the RTM (RTW) phase, and drive to an actual release. </p>  <p>Before we delve in MQ, it’s important to note that all of these phases are divided in “red weeks” and “green weeks” (a block denotes a week). “Red weeks” are weeks of active development, “green weeks” are weeks of stabilization. Obviously the actual activities that happen in these weeks depend on the phase of the project.</p>  <p>&#160;</p>  <h1>MQ</h1>  <p>MQ is the Quality Milestone. The role of MQ is ensuring that we have a working high-quality “production factory” before we embark on producing the next version of the product. </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/8816.image_7F8E79AC.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/8816.image_5F00_7F8E79AC.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="Figure 3  MQ and Planning" border="0" alt="MQ and Planning" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/6355.image_thumb_383923BA.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/6355.image_5F00_thumb_5F00_383923BA.png" width="453" height="255" /></a></p>  <p align="center"><strong>Figure 3</strong>&#160; MQ and Planning</p>  <p>The breakdown of MQ is as follows:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/7024.image_1ED12080.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/7024.image_5F00_1ED12080.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="Figure 4  Breakdown of MQ" border="0" alt="Breakdown of MQ" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/8816.image_thumb_654E1088.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/8816.image_5F00_thumb_5F00_654E1088.png" width="684" height="495" /></a></p>  <p align="center"><strong>Figure 4 </strong> Breakdown of MQ</p>  <p>MQ is all-inclusive collaborative effort between the 3 disciplines. The majority of PM, Dev and Test will be working on MQ activities during MQ. A few PMs and Devs will be working on planning / prototyping in parallel. MQ is planned and rigorously project-managed. MQ has a set of exit criteria that the org needs to hit before exiting the milestone.</p>  <h4></h4>  <p>&#160;</p>  <h1>The Dev Cycle</h1>  <p>All features are developed during the dev cycle, which looks as follows:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/6355.image_16D97E1E.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/6355.image_5F00_16D97E1E.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="Figure 5  Dev Cycle" border="0" alt="Dev Cycle" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/8510.image_thumb_4F84282B.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/8510.image_5F00_thumb_5F00_4F84282B.png" width="462" height="254" /></a></p>  <p align="center"><strong>Figure 5</strong>&#160; Dev Cycle</p>  <p>There is a single prioritized feature backlog that captures all features that are being worked on in the current development cycle or can be worked on in future cycles. The list of features that comprise the current development cycle is <u>stable throughout the cycle</u> i.e. <u>Management does not change the list beyond M0</u> – they have to wait for the next M0.</p>  <p>Any feature that cannot be completed is “cut” until the new dev cycle. Features that take more than one dev cycle to complete will be split into smaller manageable “featurettes” can be completed within the constraints of a dev cycle. Several featurettes may comprise the final feature. At the start of the development new cycle the feature is re-evaluated again against the other features in the backlog.</p>  <p>The start of every new dev cycle is a clean slate. All bugs and features are automatically “cut” and need to be reevaluated and brought back (can be evaluated and brought back during)</p>  <blockquote>   <p align="left"><font color="#000000"><em><strong>IMPORTANT: The development cycle is a contained unit of delivery of added value. We can have as many development cycles as necessary to build a compelling value for the “big release”, but every one of them ends with high quality features that are ready to ship.</strong> </em></font></p> </blockquote>  <p>The breakdown of the development cycle is as follows:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/2630.image_4F17F536.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2630.image_5F00_4F17F536.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="Figure 6  Breakdown of a Dev Cycle" border="0" alt="Breakdown of a Dev Cycle" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/6431.image_thumb_23672B3A.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/6431.image_5F00_thumb_5F00_23672B3A.png" width="689" height="722" /></a></p>          <p align="center"><strong>Figure 6</strong>&#160; Breakdown of a Dev Cycle</p>  <p>The M0 to M4 cycle can be repeated multiple times within a release. Every time in M0 (but only in M0), executive management gets to redefine the feature backlog.</p>  <p>&#160;</p>  <h1>Stabilization and Release</h1>  <p>The final phase in the development process (disregarding the various post-release activities for now) is the “Stabilization and Release” phase or “RTM”. </p>  <p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/2727.image_49C90E85.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2727.image_5F00_49C90E85.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Figure 7  Stabilization and Release (&quot;RTM&quot;)" border="0" alt="Stabilization and Release (&quot;RTM&quot;)" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/6763.image_thumb_346B591D.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/6763.image_5F00_thumb_5F00_346B591D.png" width="453" height="201" /></a></p>  <p align="center"><strong>Figure 7</strong>&#160; Stabilization and Release (“RTM”)</p>  <p>This phase is about fixing bugs, integration (if necessary) and managing the final quality of the release. The breakdown is as follows:</p>  <p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/3730.image_48F0A89B.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/3730.image_5F00_48F0A89B.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Figure 8  Breakdown of Stabilization and Release" border="0" alt="Breakdown of Stabilization and Release" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/0564.image_thumb_214A2C71.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/0564.image_5F00_thumb_5F00_214A2C71.png" width="685" height="207" /></a></p>  <p align="center"><strong>Figure 8</strong>&#160; Breakdown of Stabilization and Release</p>  <p>&#160;</p>  <h1>QFEs (Hotfixes)</h1>  <p>Every large software project needs to have a mechanism to deal with hotfixes (also known as <a href="https://en.wikipedia.org/wiki/QFE" target="_blank">QFEs</a>). The nature of these fixes requires reactive delivery (as opposed to the proactive approach described above). Teams typically maintain a separate source code branch (or branches) for QFEs and that is typically the same as the branch that contains the currently shipping version of the software. </p>  <p>Due to their reactive nature QFEs are delivered on demand with a release schedule that looks as follows:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/1641.image_6BD16A4B.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/1641.image_5F00_6BD16A4B.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="Figure 9  QFE Release and RI Schedule" border="0" alt="QFE Release and RI Schedule" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/2727.image_thumb_2724D00A.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2727.image_5F00_thumb_5F00_2724D00A.png" width="533" height="294" /></a></p>  <p align="center"><strong>Figure 9</strong>&#160; QFE Release and RI Schedule</p>  <p>Typically, fixes introduced in the QFE branch must make their way into the Main product branch, which is done with a series of regular reverse integrations (or RIs) as shows above. QFEs also get packaged as larger packages and released as service packs (or SPs).</p>  <p>Every QFE is subjected to a root-cause analysis, following a simple standard template, to help the team avoid similar situations in the future.&#160; </p>  <p>&#160;</p>        <h1>Templates and Artifacts</h1>  <p>Last but not least I wanted to provide a quick list with some of the fundamental documents that are required to bootstrap a development process for a larger product. Note that this list is nothing more than a reasonable starting point – at least according to me. </p>  <p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/0574.image_71AC0DE4.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/0574.image_5F00_71AC0DE4.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Figure 10  Key Templates and Artifacts" border="0" alt="Key Templates and Artifacts" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/6740.image_thumb_05C52A6E.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/6740.image_5F00_thumb_5F00_05C52A6E.png" width="713" height="493" /></a></p>  <p align="center"><strong>Figure 10</strong>&#160; Key Templates and Artifacts</p>  <p>&#160;</p>  <h1>Conclusion</h1>  <p>There are many ways to ship software products. Large products require more pampering and more scaffolding, at least until a critical mass of the team adopts a coherent product development culture. If you want to ship high quality products, you need to invest in rationalizing your product development cycle. The best way to do that is to plan, using a series of thought experiments (e.g. “imagine that we have achieved code complete, what are the steps from CC to release ready and how long are they realistically going to take”), and a guiding principle of lowest possible overhead costs and highest possible simplicity. </p>]]></content:encoded>
    </item>
    <item>
      <title>Updating Your WP7 (and Dealing with Error 800705B4)</title>
      <link>https://docs.microsoft.com/archive/blogs/ivo_manolov/updating-your-wp7-and-dealing-with-error-800705b4</link>
      <pubDate>Thu, 21 Apr 2011 16:44:00 GMT</pubDate>
      <dc:creator><![CDATA[ivom1]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ivo_manolov/2011/04/21/updating-your-wp7-and-dealing-with-error-800705b4/</guid>
      <description><![CDATA[I have had a Samsung Focus WP7 device for several months now and I absolutely love it. I love the...]]></description>
      <content:encoded><![CDATA[<p>I have had a Samsung Focus WP7 device for several months now and I absolutely love it. I love the hardware (fantastic bright display, sleek look, etc.), I love the Metro UI, and I love the development tools. VS 2010 and Silverlight for WP7 are a ton of fun.</p>  <p>Like many of you I patiently waited for the February and March updates and just yesterday, at the end of April, I finally got prompted to install them. Unfortunately, as I hooked up the phone to my PC to update it, I hit error 800705B4.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/2350.clip_image001_05972D74.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2350.clip_5F00_image001_5F00_05972D74.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="clip_image001" border="0" alt="clip_image001" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/7462.clip_image001_thumb_19441708.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/7462.clip_5F00_image001_5F00_thumb_5F00_19441708.jpg" width="378" height="435" /></a></p>  <p>Error code 800705B4 resolves to the following:</p>  <p><code>0:000&gt; !error 800705B4 Error code:      <br />(HRESULT) 0x800705b4 (2147943860) - This operation returned because the timeout period expired.</code> </p>  <p>Since it took me a bit of digging to recover from it, I wanted to share here the fast way to overcoming this error:</p>  <ol>   <li>Go to <a title="https://support.microsoft.com/kb/2530409" href="https://support.microsoft.com/kb/2530409">https://support.microsoft.com/kb/2530409</a> and download the <strong>Windows Phone Support Tool</strong> for your PC platform.</li>    <li>Follow the instructions in the tool. You won’t lose any of your information.</li>    <li>After the tool is done recovering your phone, hook it up to Zune again and get the update successfully.</li> </ol>  <p>Hopefully, that’ll save folks out there some time reading through MSDN docs.</p>]]></content:encoded>
    </item>
    <item>
      <title>TestApi v0.6 Released!</title>
      <link>https://docs.microsoft.com/archive/blogs/ivo_manolov/testapi-v0-6-released</link>
      <pubDate>Mon, 07 Feb 2011 16:19:12 GMT</pubDate>
      <dc:creator><![CDATA[ivom1]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ivo_manolov/2011/02/07/testapi-v0-6-released/</guid>
      <description><![CDATA[I am happy to announce that we have just released version 0.6 of TestApi – the API library for...]]></description>
      <content:encoded><![CDATA[<p>I am happy to announce that we have just released version 0.6 of <a href="https://testapi.codeplex.com/releases/view/60572" target="_blank"><strong>TestApi</strong></a> – the API library for testing – on Codeplex. Version 0.6 contains the following additions and modifications:</p>  <ul>   <li>Starting with this release, we are <strong>moving all of the development of the library to Codeplex</strong>. We have also moved the solution to VS 2010;</li>    <li><u>Jared Moore</u> made several important modifications to our <strong>Fault Injection API</strong>, including but not limited to support for in-process fault injection, support for MethodInfo-based method identification, various performance improvements and bug fixes. In addition, we are releasing the complete source code of the unmanaged FaultInjectionEngine.dll, which now builds cleanly at warning level 4;</li>    <li><u>Dennis Deng</u> extended the <strong>Input Simulation API</strong> with support for injection of non-ASCII strings in Keyboard.Type(…). We have also added support for Mouse.DragTo(…);</li>    <li>We have added support for 64-bit in our <strong>Leak Detection API</strong>;</li>    <li><u>Andrey Arkharov</u> extended the <strong>Object Comparison API</strong> with support for encoding and decoding object graphs from arbitrary streams, annotating object graph nodes with custom comparison strategies and type-specific object graph factories, together with several additional tests;</li>    <li>We extended our <strong>String Generation API</strong> with support for string generation from regular expressions. We have also added a CommonRegularExpressions class, to speed up test development;</li>    <li>We have added lots of <strong>additional tests</strong>, and have refactored the existing tests into namespaces for better discoverability.</li>    <li>Last, but not least we have made some important <strong>API documentation improvements</strong> – the API documentation now sports namespace docs.</li> </ul>  <p>Check out the <a href="https://testapi.codeplex.com/releases/view/60572" target="_blank"><strong>TestApi v0.6 release notes</strong></a> for a more detailed version of the above. Then let us know what you think and <a href="https://testapi.uservoice.com/" target="_blank"><strong>vote</strong></a> for features.</p>]]></content:encoded>
    </item>
    <item>
      <title>Registering Your WP7 as a Developer Device</title>
      <link>https://docs.microsoft.com/archive/blogs/ivo_manolov/registering-your-wp7-as-a-developer-device</link>
      <pubDate>Tue, 07 Dec 2010 23:12:00 GMT</pubDate>
      <dc:creator><![CDATA[ivom1]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ivo_manolov/2010/12/07/registering-your-wp7-as-a-developer-device/</guid>
      <description><![CDATA[Update: Shortly after I posted this article, Peter Henry noted that he had a very similar article...]]></description>
      <content:encoded><![CDATA[<p><strong><em></em></strong></p>  <p><strong><em><u>Update</u>: Shortly after I posted this article, Peter Henry noted that he had a very similar article out already. Here is the link to it – it has good additional information – check it out: </em></strong><a href="https://www.pchenry.com/Home/tabid/36/EntryID/389/Default.aspx"><strong><em>https://www.pchenry.com/Home/tabid/36/EntryID/389/Default.aspx</em></strong></a></p>  <p>So you got your Windows Phone 7 device, you downloaded the free development tools and now you are itching to write your first “Hello World” app for WP7. You fire up VS 2010, create a quick phone app, connect your WP7 device to your development PC, select “Windows Phone 7 Device” as a target and attempt running your first app on your phone.</p>  <p>You will get the following message…</p>  <blockquote>   <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/1803.image_3F7F5E29.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/1803.image_5F00_3F7F5E29.png"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/5428.image_thumb_36AF55DD.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/5428.image_5F00_thumb_5F00_36AF55DD.png" width="820" height="218" /></a></p> </blockquote>  <p>You have to make sure your device is ”developer unlocked” before you can deploy applications to it. Here’s how you unlock your device:</p>  <ol>   <li>Connect your device to your PC through USB. </li>    <li>Start the Zune desktop software. </li>    <li>Start the “Windows Phone Developer Registration” software. </li> </ol>  <blockquote>   <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/6505.image_4F3EF32D.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/6505.image_5F00_4F3EF32D.png"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/1321.image_thumb_3B456097.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/1321.image_5F00_thumb_5F00_3B456097.png" width="501" height="592" /></a></p> </blockquote>  <ol>   <li>At this point, provided you have a developer account (which you get on <a href="https://developer.WindowsPhone.com">https://developer.WindowsPhone.com</a>) you can register your device. Once registered you’ll be able to use it for development purposes. </li> </ol>  <blockquote>   <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/2311.image_52906508.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2311.image_5F00_52906508.png"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/4848.image_thumb_66A98191.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/4848.image_5F00_thumb_5F00_66A98191.png" width="514" height="464" /></a></p> </blockquote>  <p>&#160;</p>  <p>Easy! (not necessarily straightforward though :) )</p>]]></content:encoded>
    </item>
    <item>
      <title>Performing Code Reviews in TFS 2010</title>
      <link>https://docs.microsoft.com/archive/blogs/ivo_manolov/performing-code-reviews-in-tfs-2010</link>
      <pubDate>Mon, 29 Nov 2010 01:15:00 GMT</pubDate>
      <dc:creator><![CDATA[ivom1]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ivo_manolov/2010/11/29/performing-code-reviews-in-tfs-2010/</guid>
      <description><![CDATA[The past few days I moved the development of TestApi to the Codeplex TFS servers. Previously, we...]]></description>
      <content:encoded><![CDATA[<p>The past few days I moved the development of <a href="https://testapi.codeplex.com/" target="_blank">TestApi</a> to the Codeplex TFS servers. Previously, we used to develop TestApi in the internal WPF branch at Microsoft, which had become a bit of a drag due to the need to support contributors from various teams across the company.</p>  <p>As part of the move, I needed to set up a code review process. Turns out that it’s a bit of a struggle to figure out how to set up a simple CR process using standard tools – mostly due to poor documentation – so I thought I’d share what I did in this post. Hopefully, that will save someone out there some time.</p>  <p>&#160;</p>  <h1>Code Review Process</h1>  <p>The general CR process goes as follows:</p>  <ol>   <li>The developer creates a new shelveset (see the <a href="https://msdn.microsoft.com/en-us/library/ms181403(VS.80).aspx" target="_blank">TFS documentation</a> for a definition of “shelveset”) with his/her changes and sends the shelveset for CR. </li>    <li>The code reviewer performs the CR, sending back feedback. </li>    <li>The developer revises his/her code based on the CR feedback and generates a new shelveset. </li>    <li>Steps 1-3 get repeated until the code reviewer approves the code change for checkin. </li>    <li>The developer checks in the code. </li> </ol>  <p>The tools we use for CR are VS 2010 itself and <a href="https://www.microsoft.com/downloads/en/details.aspx?FamilyID=49ae8576-9bb9-4126-9761-ba8011fabf38" target="_blank">WINDIFF</a>. The latter is a diffing tool used for step 2 of the CR process.</p>  <p>&#160;</p>  <h1>Initial Setup</h1>  <p>To set up WINDIFF as your diff-ing tool, in VS 2010 go to <b>Tools</b> &gt; <b>Options…</b>, scroll down to the <b>Source Control</b> item and configure your compare tool to be WINDIFF as shown below:</p>  <p><b></b><b></b></p>  <p><b></b><b></b></p>  <blockquote>   <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/7266.image_4099C8AE.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/7266.image_5F00_4099C8AE.png"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/3365.image_thumb_063E52CD.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/3365.image_5F00_thumb_5F00_063E52CD.png" width="517" height="302" /></a></p> </blockquote>  <blockquote>   <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/4442.image_3E7CC9E5.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/4442.image_5F00_3E7CC9E5.png"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/3301.image_thumb_4BE2DCEB.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/3301.image_5F00_thumb_5F00_4BE2DCEB.png" width="517" height="211" /></a></p> </blockquote>  <blockquote>   <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/2311.image_44576D7E.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2311.image_5F00_44576D7E.png"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/8255.image_thumb_38C1B03F.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/8255.image_5F00_thumb_5F00_38C1B03F.png" width="296" height="159" /></a></p> </blockquote>  <p>&#160;</p>  <h1>Shelving</h1>  <p><i>Shelving</i> is the act of storing pending changes on the TFS server (see <a href="https://msdn.microsoft.com/en-us/library/ms181403(VS.80).aspx">this link</a> for more). To create a shelveset, in <b>Source Control Explorer</b>, right-click on the folder, containing all pending changes, and choose <b>Shelve Pending Changes…</b> in the displayed context menu. This will bring up a dialog that you can use to shelve your changes.</p>  <blockquote>   <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/5432.image_3C5FCB1C.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/5432.image_5F00_3C5FCB1C.png"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/3465.image_thumb_7BBD7EAC.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/3465.image_5F00_thumb_5F00_7BBD7EAC.png" width="506" height="248" /></a></p> </blockquote>  <p>Once you shelve your proposed changes, send an email to the code reviewer, with your username and the name of your shelveset.</p>  <p>&#160;</p>  <h1>Unshelving, Diffing and Code Review </h1>  <p>When you get a CR request, go to <b>File</b> &gt; <b>Source Control</b> &gt; <b>Unshelve Pending Changes…</b> and in the displayed <b>Unshelve</b> dialog, discover the shelveset that you need to review and click <b>Details…</b></p>  <blockquote>   <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/5428.image_16F5D7AE.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/5428.image_5F00_16F5D7AE.png"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/6505.image_thumb_617D1588.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/6505.image_5F00_thumb_5F00_617D1588.png" width="498" height="227" /></a></p> </blockquote>  <p>In the displayed <b>Shelveset Details</b> dialog, right click the file you want to review and compare it to its unmodified version. This will trigger WINDIFF as a comparison tool. Record your comments in an email and send them back to the developer (or approve the checkin if you agree to it). </p>  <blockquote>   <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/7563.image_6EE3288E.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/7563.image_5F00_6EE3288E.png"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/2476.image_thumb_473CAC64.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2476.image_5F00_thumb_5F00_473CAC64.png" width="503" height="288" /></a></p> </blockquote>  <p>&#160;</p>  <h1>Conclusion</h1>  <p>That’s pretty much it. Obviously, this is a poor man’s solution, but it’s certainly better than nothing. There are a bunch of more advanced solutions out there providing code annotation, review workflows, etc. that you may find valuable too. <a href="https://www.controlstatements.com/2009/01/team-system-code-review-presentation.html" target="_blank">This post by JB Brown</a> may be a good starting point for those who want to go further.</p>]]></content:encoded>
    </item>
    <item>
      <title>Principles 4: End-to-End Development Process</title>
      <link>https://docs.microsoft.com/archive/blogs/ivo_manolov/principles-4-end-to-end-development-process</link>
      <pubDate>Fri, 10 Sep 2010 02:11:34 GMT</pubDate>
      <dc:creator><![CDATA[ivom1]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ivo_manolov/2010/09/10/principles-4-end-to-end-development-process/</guid>
      <description><![CDATA[Series Index     Principles 1: The Essence of Driving – A Crash Course in Project Management...]]></description>
      <content:encoded><![CDATA[<h1>Series Index</h1>  <ul>   <li><a href="https://blogs.msdn.com/b/ivo_manolov/archive/2010/07/18/10039624.aspx">Principles 1: The Essence of Driving – A Crash Course in Project Management</a> </li>    <li><a href="https://blogs.msdn.com/b/ivo_manolov/archive/2010/07/23/10042059.aspx">Principles 2: Principles of Software Testing</a> </li>    <li><a href="https://blogs.msdn.com/b/ivo_manolov/archive/2010/08/01/10044780.aspx">Principles 3: Principles of Software Development</a> </li>    <li><a href="https://blogs.msdn.com/b/ivo_manolov/archive/2010/09/10/10060204.aspx" target="_blank">Principles 4: End-to-End Development Process</a> </li>    <li><a href="https://blogs.msdn.com/b/ivo_manolov/archive/2011/04/21/10136580.aspx" target="_blank">Principles 5: End-to-End Development Process (for Large Projects)</a> </li> </ul>  <p align="center">+++</p>  <p align="left">This fourth post discusses an end-to-end development process. Obviously, there are many ways to develop software. While a lot of the basic principles apply almost universally, every sufficiently autonomous organization needs to figure out what works for itself, and then progressively refine it.</p>  <p align="left">It is important to note that this process is the same process we used to manage several projects and has resulted in delivery of high-quality products, in a controlled manner, on time (actually ahead of time in a few cases). In other words, this is a real, proven process, not a theoretical construct.&#160; I’ll actually show two versions of the process – a simple one - for smaller orgs, and a more involved one - for larger orgs.</p>  <p>&#160;</p>  <h1>Guiding Principles</h1>  <p>Before going further, I want to once again reiterate the <a href="https://blogs.msdn.com/b/ivo_manolov/archive/2010/08/01/10044780.aspx" target="_blank">Principles of Software Development</a>. These principles are the underlying “Constitution”. In summary, they are:</p>  <ul>   <li><em>Everybody on the team fully understands the plan.</em> </li>    <li><em>Deliver features in a gradual, close-looped manner.</em> </li>    <li><em>Define release criteria at the start of the cycle. Track visibly.</em> </li>    <li><em>Exercise defect prevention – whenever possible.</em> </li>    <li><em>Have a stable, fully-transparent, committed schedule from the start.</em> </li>    <li><em>No code while planning the “What”. No code without spec.</em> </li>    <li><em>Fully working and timed setup on day 1 of M0.</em> </li>    <li><em>Strict and reliable reverse- and forward-integration gates from day 1 of M0.</em> </li>    <li><em>Start together, work together, finish together.</em> </li>    <li><em>No work happens outside of the main development cycle.</em> </li>    <li><em>Every major system has an owner.</em> </li> </ul>  <p align="left">&#160;</p>  <h1 align="left">Goals</h1>  <p align="left">At the high level, we want to be able to produce high-quality, compelling software, in a well-organized, intentional, cost-effective, and predictable manner. In order to pull that off, we need the following:</p>  <ol type="A">   <li>Commitment, at all levels of the organization, to “do the right thing”. Full management sponsorship. </li>    <li>A well-designed organization; </li>    <li>A well-designed “business cycle”; </li>    <li><strong>A well-designed development process;</strong> </li>    <li>A well-designed and working “engineering factory”; </li>    <li>A high-powered and high-morale team; </li> </ol>  <p>This post talks about “D”, but it goes without saying that “A” to “F” represent a system of connected vessels and need to be designed, implemented, and refined together.</p>  <p>This post also makes the assumption that you have a working “Planning Process” that generates compelling product value propositions. Clearly, without a compelling product that addresses a customer need, it doesn’t matter how excellent you are in delivery. There are various ways to plan a product. At Microsoft, we use a bunch of different approaches, with a lot of folks now gravitating towards the so called “Sinofsky model”. At any rate, this post does not discuss the planning process (I may do this in a future post).</p>  <p>In order to deliver a high-quality product, you need to plan and design before you code. On the other hand, you don’t want to get stuck in planning for a prolonged period of time, because time may erode the value prop of your product and because you need fast and frequent customer feedback – you may be working in the wrong direction. Clearly, we need to “marry” these two competing priorities and clearly this is an optimization problem. What follows is our solution to the optimization problem, but solutions will vary based on specific product, business, industry and team considerations. Treat this as a starting point – take it and make it your own.</p>  <p>&#160;</p>  <h1>Process 1 – Simple Projects</h1>  <p>We used this simple version of the process to develop <a href="https://testapi.codeplex.com/" target="_blank">TestApi</a> – the API library for test and tool developers. TestApi is a relatively small and simple project. With this process, we released five versions of the library and we released all of them on time or ahead of time. </p>  <p>The development schedule looks as follows:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/3527.image21_30BED639.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/3527.image21_5F00_30BED639.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" class="wlDisabledImage" title="Figure 1  Simple development schedule" border="0" alt="Simple development schedule" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/2538.image21_thumb_3705ACC7.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2538.image21_5F00_thumb_5F00_3705ACC7.png" width="645" height="464" /></a></p>  <br />  <p align="center"><strong>Figure 1</strong>. Simple development schedule</p>  <p>The schedule consists of 5 major milestones:</p>  <ul>   <li><strong>M0 – Planning</strong> – in this phase, we finalize the list of features we’d like to deliver in the release. Every feature has an owner. All owners understand the schedule. The necessary prototyping is done. At the end of M0 we have a backlog for the release, to which we have committed. Once we commit to the backlog. We do not allow feature creep after the end of M0. </li>    <li><strong>M1 – Design</strong> – in this phase every owner delivers a “conceptual document” that explains the usage of their feature accompanied if necessary by a design document. In the case of an API library such as TestApi, this is a API usage document and API design document.&#160; The usage and design gets reviewed and approved by the Architecture review body (3 people in the case of TestApi). Once the design has been approved, the owner checks in the empty stubs (e.g. of the API) and the corresponding acceptance tests, together with an initial version of the XML documentation and gets stubs, tests and documentation to build cleanly. The documentation (both docs generated from XML comments as well as the conceptual documentation) gets sent to the Documentation team for editing. The Legal team (LCA) gets engaged. </li>    <li><strong>M2 – Implementation</strong> – in this phase, the owner implements the tests, code, fixes the documentation (based on editorial feedback from the Docs team) and drives to ZBB (zero bugs) </li>    <li><strong>M3 – LCA and Samples</strong> – in this phase the owner implements stand-alone samples (if applicable) and discussed the product with LCA (legal) if applicable. Legal signs off. </li>    <li><strong>M4 – Stabilization and Release</strong> – final stabilization, release checklist (we have a predefined checklist) and final release. </li>    <li><strong>Prep</strong> – At the end of every release cycle, we have about 4 weeks of “padding”. During that period, we do various post release activities (blogging, etc.), we invest in our engineering “factory” and we engage on preliminary planning for the next release (identifying possible participants, defining dates, etc.) This is a fairly relaxed period and that is by design. </li> </ul>  <p>All features associated with a release are tracked in a table similar to the <a href="https://blogs.msdn.com/b/ivo_manolov/archive/2010/07/18/10039624.aspx" target="_blank">TestApi Feature Backlog table presented in this post</a>:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/8535.image_5C6599AE.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/8535.image_5F00_5C6599AE.png"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" class="wlDisabledImage" title="Figure 2  Feature readiness checklist" border="0" alt="Feature readiness checklist" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/2287.image_thumb_1437DDD2.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2287.image_5F00_thumb_5F00_1437DDD2.png" width="503" height="438" /></a></p>  <p align="center"><strong>Figure 2</strong>. Feature readiness checklist</p>  <p>All source code is static analysis clean by default (FxCop, StyleCop, etc.) – checking in a violation results in a build break. There is a FAQ for commonly asked questions (e.g. “I can’t be done with a feature on time, what do I do?”, etc.) that evolves with every release. </p>  <p>As a general rule, the timelines above are rigorously adhered to. If you “fall off the train” (meaning – fail to meet a deadline), you don’t get back on the train until the next version (which is always no more than 3 months away, and of course you tend to deliver larger payload for it). We have a dedicated project manager who drives every release (for TestApi that was Alexis Roosa).</p>  <p>The tasks associated with every milestone are done in the order in which they are presented here. For example, we write the acceptance tests against the empty stubs <strong>before</strong> we write the actual code. Another thing that should be obvious is that we spend a lot of effort on planning and design. We are extremely rigorous in our design review, we look at the API from various different angles (we consider different options, we discuss naming, usage, simplicity, statelessness, future evolveability, etc.) employing both scenario-based design and producing various short-lived and long-lived documents. We have found that this saves us a lot of time during development and significantly increases the confidence of our dates. </p>  <p>&#160;</p>  <h1>Simple, Predictable, Agile</h1>  <p>The simplicity and predictability of this process have a lot of positive effects – from team morale and cohesion to delivery on time with high quality. To date, we have always been done with M4 on time or ahead of time! The process does, however, have a waterfallish feel, so every once in a while I get questions about agility. Put simply, we believe that design and planning is important, but so is time to market and getting frequent customer feedback.&#160; We resolve that tension by having short release cycles (3 months or less). There is noting that is preventing us from making these cycles even shorter, but we have found that 3 months works well for us.</p>  <p>My experiences shows that you can’t achieve agility by cutting proven engineering practices such as solid design and code reviews – that only leads to fire-drills, death marches and low quality. You achieve agility by having a reasonably rapid development cycle, aligned to solid business considerations.</p>  <p>&#160;</p>  <h1>To Be Continued…</h1>  <p>In my next post, I will introduce a process that is suitable for larger, more complex products and organizations. </p>]]></content:encoded>
    </item>
    <item>
      <title>The 3 Questions</title>
      <link>https://docs.microsoft.com/archive/blogs/ivo_manolov/the-3-questions</link>
      <pubDate>Wed, 04 Aug 2010 22:13:00 GMT</pubDate>
      <dc:creator><![CDATA[ivom1]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ivo_manolov/2010/08/04/the-3-questions/</guid>
      <description><![CDATA[A key goal for every manager is building a happy, productive team. One technique I use when building...]]></description>
      <content:encoded><![CDATA[<p>A key goal for every manager is building a happy, productive team. One technique I use when building teams is asking folks on the team the following three questions:</p>
<ul>
<li><strong>Q1</strong>. What do you do, and like doing? </li>
<li><strong>Q2</strong>. What do you do, and don&rsquo;t like doing? </li>
<li><strong>Q3</strong>. What do you not do, but would like to start doing? </li>
</ul>
<p>I ask folks to give these questions some thought and ideally send me a bulletized list of items before we meet in person to discuss them. I explain that I will try my best to minimize the items that fall under Q2, and maximize opportunities for items that fall under Q3.</p>
<p>Even though this technique is extremely simple, I have found it to be a great tool to anchor and guide career conversations. It provides just enough structure to facilitate the conversation, for a very low overhead cost. </p>
<p>Clearly, this technique also gives me the ability to intelligently balance responsibilities within the organization. Very often the old adage that &ldquo;one man&rsquo;s garbage is another man&rsquo;s treasure&rdquo; proves to be true, which of course makes everybody in the org happier. And happy people are productive people. </p>]]></content:encoded>
    </item>
    <item>
      <title>Principles 3: Principles of Software Development (aka Principles of Shipping)</title>
      <link>https://docs.microsoft.com/archive/blogs/ivo_manolov/principles-3-principles-of-software-development-aka-principles-of-shipping</link>
      <pubDate>Sun, 01 Aug 2010 22:36:00 GMT</pubDate>
      <dc:creator><![CDATA[ivom1]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ivo_manolov/2010/08/01/principles-3-principles-of-software-development-aka-principles-of-shipping/</guid>
      <description><![CDATA[Series Index     Principles 1: The Essence of Driving – A Crash Course in Project Management...]]></description>
      <content:encoded><![CDATA[<h1>Series Index</h1>  <ul>   <li><a href="https://blogs.msdn.com/b/ivo_manolov/archive/2010/07/18/10039624.aspx">Principles 1: The Essence of Driving – A Crash Course in Project Management</a> </li>    <li><a href="https://blogs.msdn.com/b/ivo_manolov/archive/2010/07/23/10042059.aspx">Principles 2: Principles of Software Testing</a> </li>    <li><a href="https://blogs.msdn.com/b/ivo_manolov/archive/2010/08/01/10044780.aspx">Principles 3: Principles of Software Development</a> </li>    <li><a href="https://blogs.msdn.com/b/ivo_manolov/archive/2010/09/10/10060204.aspx" target="_blank">Principles 4: End-to-End Development Process</a> </li>    <li><a href="https://blogs.msdn.com/b/ivo_manolov/archive/2011/04/21/10136580.aspx" target="_blank">Principles 5: End-to-End Development Process (for Large Projects)</a> </li> </ul>  <p align="center">+++</p>  <p>The third and fourth posts from my series on “Principles” outline a system of shipping of software, that takes into account the various lessons I have learned during my years as a manager at Microsoft, dating back to the first product I worked on – Windows XP. The post lists a set of guiding engineering principles that result in stable, high quality releases, delivered on time.</p>  <p>Before we jump into the principles, I want to call out a few things:</p>  <ol>   <li><strong>No exceptions to the rules</strong>: There is <u>no such thing as partial implementation</u> of these principles. Even though I take a lot of time socializing these principles in the organizations I manage and worked in, I and my managers tend to take a fairly assertive approach when implementing these principles and we <u>apply them fully, 100% of the time</u>. Yes, it takes a while to socialize these and yes, we get a few “you are not being agile” (see more on “agile” at the end of this post), “you don’t understand our reality, we are a special organization” and “can we make an exception for XYZ” comments. We still treat these principles as a Constitution and we (management) support them 100% of the time.       <br /></li>    <li><strong>Real products get shipped with these principles</strong>: Everybody wants to ship a high-quality product, with compelling customer value, on schedule or ahead of schedule. As involved as these principles may sound, they are a very simple scaffolding that gets you to ship predictably with high quality.       <br /></li>    <li><strong>Top management sponsorship, commitment and calibration is key</strong>: You cannot really achieve any significant change in an organization unless you have first-class sponsorship and commitment by the top of the organization. The top management team needs to be committed as well as well-calibrated i.e. different members of the top management team should come up with consistent answers when approached with the same problem.       <br /></li>    <li><strong>Commitment eventually leads to organic adoption</strong>:&#160; Solid principles and processes inevitably lead to cultural changes in the organization. As managers, that’s exactly what we want to achieve – a cultural shift in the organization that results in organic rejection of bad practices, and an appetite for continuous improvement.&#160; </li> </ol>  <p align="center">+++</p>  <h1>Everybody on the team fully understands the plan.</h1>  <p>For a team to be successful, <u>everybody on the team needs to (at all times) understand “the plan”</u> for the release and his/her role in its various cycles and milestones. The litmus test here is asking a random person on the team what “the plan” (schedule, owners, feature set) is. </p>  <p>&#160;</p>  <h1>Deliver features in a gradual, close-looped manner.</h1>  <p>A common theme during software releases is a fire-drill towards the end of the release, due to the syndrome of “biting more than we can chew” and due to managing the deliverables in an open-ended, “agile” fashion. One way to overcome this situation is ensuring that we deliver features in smaller “sets”, on a more frequent cadence. <u>Every “feature set” represents a meaningful collection, which gets developed and stabilized together before proceeding to the next set</u>. </p>  <p>Thus, we end up with a number of “feature set development cycles”, producing stable sets that integrated together comprise our release. I like to use the metaphor of “putting features in the freezer” i.e. we start working on the new feature set only when we have gotten the current feature set to high shippable quality.</p>  <p>&#160;</p>  <h1>Define release criteria at the start of the release cycle. Track regularly.</h1>  <p>This sounds like a common sense “must do”, but it is regularly not done sufficiently well. The release criteria generally fall into two groups: (a) RI release criteria, necessary to RI (reverse integrate) a feature into the main product branch and (b) shipping release criteria, necessary to release a feature or a set of features. We need to have the complete list of both <u>before</u> we check in a single line of code. That helps us understand the true cost of every feature.</p>  <p>&#160;</p>  <h1>Defect prevention – whenever possible.</h1>  <p>A lot of our effort is spent on <u>generating and fixing defects that could have been prevented in the first place</u>. We need to make heavy use of all available tools in an attempt to prevent as many defects as possible from entering the product in the first place.</p>  <p>Examples of such defect prevention opportunities are enabling of tools such as FXCOP in the build environment, by default.</p>  <p>&#160;</p>  <h1>Have a stable, fully-transparent, committed schedule from the start.</h1>  <p>Another common challenge in software releases is the lack of a stable, transparent, predictable schedule. Our product schedule mimics our features. It starts as a very “low-quality” feature, progressively solidifying throughout the release, as a result of “we are not on track” realizations.</p>  <p>I have heard claims that the schedule of the parent organization (division, company, etc.) is too “fluxy” which in turn affects the ability of the team to build a predictable, stable and transparent schedule. Even if we assume that this claim is true (it probably is, but it should not be – large companies and divisions prove that they can ship with a stable schedule), <u>the local team still has the ability to be in control of its own fate by defining stable sub-schedules</u> to combat randomization from the larger organization.</p>  <p>Having a <u>stable, transparent, fully-internalized and fully-embraced schedule</u> is a key ingredient to the success of any product – big and small.</p>  <p>&#160;</p>  <h1>No code while planning the “What”. No code without spec.</h1>  <p>PM spends the first milestone in the product cycle (MQ – the quality milestone) on defining the “what” for the release. Dev and Test complete engineering debt work, preparing the engineering system for execution. While there may be limited prototype code generated during this milestone, none of this code is allowed to be reverse-integrated in any official branch. Dev and Test should spend the majority of their time stabilizing the engineering system (builds, static analysis tools, unit tests, functional tests and infra, stress tests and infra, performance tests and infra, meaningful reverse-integration tests to prevent other teams from breaking us, etc.) <u>Having a stable factory will ensure producing a stable product</u>.</p>  <p>Dev and Test start working together on the features in M0 (not earlier) once the “what” has been defined, scratching any previously generated code.</p>  <p>&#160;</p>  <h1>Fully working and timed setup on day 1 of M0.</h1>  <p>Another common problem teams face is Setup instability that typically carries on, way into the release. Not having a stable Setup complicates significantly lab operations and prevents the team to self-host the build and discover issues early, so it is something that needs to be addressed.</p>  <p><u>Setup must always be stable and must visibly display the important metrics that we are optimizing against</u>. Metrics such as speed (of setup), number of custom setup actions, etc. should be visible to the whole team from the start.</p>  <p>&#160;</p>  <h1>Strict and reliable reverse- and forward-integration gates from day 1 of M0.</h1>  <p>If we believe that reverse- and forward-integration (RI and FI) gates have a valuable role in ensuring the health of the team branch, then we must ensure that the gates that we have in place are reasonable and that they are strictly adhered to. This simplifies immensely feature development, by defining a simple “rule” for RI-ing and FI-ing code that can be easily understood and embraced by the team. </p>  <p>No code changes in the team branch will be allowed without a fully operational test and validation systems (unit tests passing, test infra running, functional tests at 99.5% pass rate, Perf lab running, Stress lab running, Code Coverage generating results).</p>  <p>&#160;</p>  <p><em></em></p>  <h1>Start together, work together, finish together.</h1>  <p>A company or a division ships a successful product by getting all team to adhere to the same fundamental schedule and gates. A development organization can and should be doing the same. Having a single schedule with a single set of expectations for all teams simplifies management of the release and creates synergy between the feature owners. </p>  <p>Some claim that “agility” is achieved by having different feature teams work against different schedules. My experience is that such pseudo-agility results in a fragmented organization, that is confused about its own deliverables and that delivers low-quality products, because products are not built with the same rhythm. Management of the product deliverables in such situations often degrades to “managing exceptions” as opposed to “managing by the rules”.</p>  <p>We can and will achieve agility through the power of contained, incremental milestones, not through randomization.</p>  <p>All teams in the development organization should start together, work together and finish together, adhering to a common schedule, RI gates and exit criteria. All disciplines (Dev, Test, PM) should do that too, working side by side as opposed to serializing work.</p>  <p>&#160;</p>  <h1>No work happens outside of the main development cycle.</h1>  <p>“Out-of-band” releases and “off-the-books” investments are good and necessary, but they must be planned as all other work and managed within the constraints of the main development cycle. </p>  <p>This means that they never appear randomly in the middle of a development cycle (they can appear on the backlog to be considered for the next dev cycle). This includes dev work, test work, prototypes, forum engagement, conference prep work, etc. </p>  <p>&#160;</p>  <h1>Every major system has an owner.</h1>  <p>Every major system on the team (“system” being a generic name for anything that needs an owner) has clearly defined and documented ownership. This includes, but is not limited to fundamentals, lab systems, build systems, test systems, infrastructures, etc.</p>  <p>&#160;</p>  <p align="center">+++</p>  <h1>A final word on AGILITY.</h1>  <p>AGILE is a magic word in our industry these days that gets thrown around somewhat lightly in my opinion. Some people hide behind the term AGILITY to justify the lack of basic structure, basic process, and basic planning adequacy in their organization. Invariably such pseudo-agility leads to constant fire-drills, regular death marches, and the eventual burn out of the team. </p>  <p>It is my strong belief that every project and team needs basic “scaffolding”. Larger projects and teams tend to need a bit more of that, at least until the scaffolding gets transformed into “team culture”.&#160; </p>  <p>Clearly, the team leaders have to be accountable for providing that basic scaffolding. Success is easy to define – if you have a happy, productive organization that delivers high-quality products on time, then you have provided the necessary basic structure. </p>  <p>I am of course aware of the goals of the agile movement, which I am very much supportive of. The best way to achieve agility in my opinion, is by sizing of your development cycle appropriately – a technique that I will demonstrate in my next post.</p>]]></content:encoded>
    </item>
    <item>
      <title>Introduction to TestApi – Part 8: Object Comparison API</title>
      <link>https://docs.microsoft.com/archive/blogs/ivo_manolov/introduction-to-testapi-part-8-object-comparison-api</link>
      <pubDate>Thu, 29 Jul 2010 12:48:00 GMT</pubDate>
      <dc:creator><![CDATA[ivom1]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ivo_manolov/2010/07/29/introduction-to-testapi-part-8-object-comparison-api/</guid>
      <description><![CDATA[Series Index     Overview of TestApi     Part 1: Input Injection APIs     Part 2: Command-Line...]]></description>
      <content:encoded><![CDATA[<h1>Series Index</h1>  <ul>   <li><a href="https://blogs.msdn.com/ivo_manolov/archive/2009/10/14/9907447.aspx">Overview of TestApi</a> </li>    <li><a href="https://blogs.msdn.com/ivo_manolov/archive/2008/12/15/9223397.aspx">Part 1: Input Injection APIs</a> </li>    <li><a href="https://blogs.msdn.com/ivo_manolov/archive/2008/12/17/9230331.aspx">Part 2: Command-Line Parsing APIs</a> </li>    <li><a href="https://blogs.msdn.com/ivo_manolov/archive/2009/04/20/9557563.aspx">Part 3: Visual Verification APIs</a> </li>    <li><a href="https://blogs.msdn.com/ivo_manolov/archive/2009/08/26/9884004.aspx">Part 4: Combinatorial Variation Generation APIs</a> </li>    <li><a href="https://blogs.msdn.com/ivo_manolov/archive/2009/11/25/9928447.aspx">Part 5: Managed Code Fault Injection APIs</a> </li>    <li><a href="https://blogs.msdn.com/ivo_manolov/archive/2010/04/14/9995847.aspx">Part 6: Text String Generation APIs</a> </li>    <li><a href="https://blogs.msdn.com/ivo_manolov/archive/2010/04/14/9995880.aspx">Part 7: Memory Leak Detection APIs</a> </li>    <li><a href="https://blogs.msdn.com/b/ivo_manolov/archive/2010/07/29/10043968.aspx">Part 8: Object Comparison APIs</a></li> </ul>  <p align="center">+++</p>  <p>Comparing two objects for equivalence is a relatively common task during test validation. For example, you might test whether a type follows the rules that are required by a particular serializer by saving and loading the object and comparing the two. In a deep object comparison, all the properties and their sub-properties are compared repeatedly until primitives are reached. The .NET Framework provides mechanisms to perform deep comparisons, but requires the types to implement part of the comparison logic (IComparable, .Equals). Obviously some types do not use these mechanisms. This API provides a mechanism to perform a deep comparison of two objects by using reflection, regardless of whether or not they implement IComparable. </p>  <h1>TestApi Object Comparison</h1>  <p>TestApi provides an API to create compare operations. The API separates the comparison operation into two parts: </p>  <ul>   <li><strong>ObjectGraphFactory</strong>: Builds an intermediate representation from the object that describes what needs to be compared. </li>    <li><strong>ObjectComparer</strong>: Uses a reusable compare mechanism to compare the intermediate representations of the objects, generated by the factory. </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/6523.image_1B9197A6.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/6523.image_5F00_1B9197A6.png"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" class="wlDisabledImage" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/37/metablogapi/1348.image_thumb_15D6~.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/1348.image_5F00_thumb_5F00_15D67E00.png" width="652" height="278" /></a></p>  <br />  <h1>Example #1</h1>  <p>This example demonstrates how to use the object comparer to compare two objects. Assuming we have the following simple class...</p>  <pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">class</span> Person
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">{
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">public</span> Person(<span style="color: #0000ff">string</span> name) 
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    { 
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        Name = name;
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        Children = <span style="color: #0000ff">new</span> Collection&lt;Person&gt;();
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    }
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> Name { <span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">public</span> Collection&lt;Person&gt; Children { <span style="color: #0000ff">get</span>; <span style="color: #0000ff">private</span> <span style="color: #0000ff">set</span>;  }
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">}</pre></pre>

<p>… we can compare two objects using the following code:</p>

<pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">Person p1 = <span style="color: #0000ff">new</span> Person(&quot;<span style="color: #8b0000">John</span>&quot;);
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">p1.Children.Add(<span style="color: #0000ff">new</span> Person(&quot;<span style="color: #8b0000">Peter</span>&quot;));
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">p1.Children.Add(<span style="color: #0000ff">new</span> Person(&quot;<span style="color: #8b0000">Mary</span>&quot;));
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">Person p2 = <span style="color: #0000ff">new</span> Person(&quot;<span style="color: #8b0000">John</span>&quot;);
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">p2.Children.Add(<span style="color: #0000ff">new</span> Person(&quot;<span style="color: #8b0000">Peter</span>&quot;));
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #008000">// Perform the compare operation</span>
</pre><pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">ObjectGraphFactory factory = <span style="color: #0000ff">new</span> PublicPropertyObjectGraphFactory();
</pre><pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">ObjectComparer comparer = <span style="color: #0000ff">new</span> ObjectComparer(factory);
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">Console.WriteLine(
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    &quot;<span style="color: #8b0000">Objects p1 and p2 {0}</span>&quot;, 
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    comparer.Compare(p1, p2) ? &quot;<span style="color: #8b0000">match!</span>&quot; : &quot;<span style="color: #8b0000">do NOT match!</span>&quot;);</pre></pre>

<p>Execution of this code produces the following output:</p>

<pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">Objects p1 and p2 do NOT match!</pre></pre>

<h1>Example #2</h1>

<p>The following example demonstrates how to obtain the details of where the two objects do not match.</p>

<pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">Person p1 = <span style="color: #0000ff">new</span> Person(&quot;<span style="color: #8b0000">John</span>&quot;);
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">p1.Children.Add(<span style="color: #0000ff">new</span> Person(&quot;<span style="color: #8b0000">Peter</span>&quot;));
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">p1.Children.Add(<span style="color: #0000ff">new</span> Person(&quot;<span style="color: #8b0000">Mary</span>&quot;));
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">Person p2 = <span style="color: #0000ff">new</span> Person(&quot;<span style="color: #8b0000">John</span>&quot;);
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">p2.Children.Add(<span style="color: #0000ff">new</span> Person(&quot;<span style="color: #8b0000">Peter</span>&quot;));
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #008000">// Perform the compare operation</span>
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">ObjectGraphFactory factory = <span style="color: #0000ff">new</span> PublicPropertyObjectGraphFactory();
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">ObjectComparer comparer = <span style="color: #0000ff">new</span> ObjectComparer(factory);
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">IEnumerable&lt;ObjectComparisonMismatch&gt; m12 = <span style="color: #0000ff">new</span> List&lt;ObjectComparisonMismatch&gt;();
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">Console.WriteLine(
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    &quot;<span style="color: #8b0000">Objects p1 and p2 {0}</span>&quot;, 
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    comparer.Compare(p1, p2, <span style="color: #0000ff">out</span> m12) ? &quot;<span style="color: #8b0000">match!</span>&quot; : &quot;<span style="color: #8b0000">do NOT match!</span>&quot;);
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">foreach</span> (ObjectComparisonMismatch m <span style="color: #0000ff">in</span> m12)
</pre><pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">{
</pre><pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    Console.WriteLine(
</pre><pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        &quot;<span style="color: #8b0000">Nodes '{0}' and '{1}' do not match. Mismatch message: '{2}'</span>&quot;,
</pre><pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        m.LeftObjectNode != <span style="color: #0000ff">null</span> ? m.LeftObjectNode.Name : &quot;<span style="color: #8b0000">null</span>&quot;,
</pre><pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        m.RightObjectNode != <span style="color: #0000ff">null</span> ? m.LeftObjectNode.Name : &quot;<span style="color: #8b0000">null</span>&quot;,
</pre><pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        m.MismatchType); 
</pre><pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">}</pre></pre>

<p>Execution of this code produces the following output:</p>

<pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">Objects p1 and p2 do NOT match!
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">Nodes 'Children' and 'Children' do not match. Mismatch message: 'RightNodeHasFewerChildren'
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">Nodes 'IEnumerable1' and 'null' do not match. Mismatch message: 'MissingRightNode'
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">Nodes 'Children' and 'null' do not match. Mismatch message: 'MissingRightNode'
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">Nodes 'Count' and 'null' do not match. Mismatch message: 'MissingRightNode'
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">Nodes 'Name' and 'null' do not match. Mismatch message: 'MissingRightNode'
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">Nodes 'Count' and 'Count' do not match. Mismatch message: 'ObjectValuesDoNotMatch'</pre></pre>

<h1>Example #3</h1>

<p>The following example demonstrates how to create a custom object graph factory which determines which nodes in the object graph to compare. </p>

<p>For simplicity, we construct a factory that disregards any children.</p>

<pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"><pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">class</span> SimpleObjectGraphFactory : ObjectGraphFactory
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">{
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> GraphNode CreateObjectGraph(<span style="color: #0000ff">object</span> o)
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    {
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #008000">// Build the object graph with nodes that need to be compared.</span>
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #008000">// in this particular case, we only pick up the object itself</span>
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        GraphNode node = <span style="color: #0000ff">new</span> GraphNode();
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        node.Name = &quot;<span style="color: #8b0000">PersonObject</span>&quot;;
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        node.ObjectValue = (o <span style="color: #0000ff">as</span> Person).Name;
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">return</span> node;
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    }
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">}</pre></pre>

<p>Then, we utilize the factory to generate graph representations of the two object we want to compare.</p>

<pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">Person p1 = <span style="color: #0000ff">new</span> Person(&quot;<span style="color: #8b0000">John</span>&quot;);
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">p1.Children.Add(<span style="color: #0000ff">new</span> Person(&quot;<span style="color: #8b0000">Peter</span>&quot;));
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">p1.Children.Add(<span style="color: #0000ff">new</span> Person(&quot;<span style="color: #8b0000">Mary</span>&quot;));
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">Person p2 = <span style="color: #0000ff">new</span> Person(&quot;<span style="color: #8b0000">John</span>&quot;);
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">p2.Children.Add(<span style="color: #0000ff">new</span> Person(&quot;<span style="color: #8b0000">Peter</span>&quot;));
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">ObjectGraphFactory factory = <span style="color: #0000ff">new</span> SimpleObjectGraphFactory();
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">ObjectComparer comparer = <span style="color: #0000ff">new</span> ObjectComparer(factory);
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">Console.WriteLine(
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    &quot;<span style="color: #8b0000">Objects p1 and p2 {0}</span>&quot;,
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    comparer.Compare(p1, p2) ? &quot;<span style="color: #8b0000">match!</span>&quot; : &quot;<span style="color: #8b0000">do NOT match!</span>&quot;);</pre></pre>

<p>Execution of this code produces the following output…</p>

<pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">Objects p1 and p2 match!</pre></pre>

<p>… which is the expected result, given the fact that our simple factory completely disregards the Children of Person.</p>

<h1>Conclusion</h1>

<p>Comparing of objects is a common problem in automated test development and TestApi provides a simple generalized and extensible solution.</p>]]></content:encoded>
    </item>
  </channel>
</rss>