<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>.NET Ramblings - Brian Noyes' Blog</title>
    <link>http://www.softinsight.com/bnoyes/</link>
    <description>Occasional mutterings on .NET architecture and development</description>
    <language>en-us</language>
    <copyright>Brian Noyes</copyright>
    <lastBuildDate>Tue, 19 Jan 2010 15:13:05 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.0.7226.0</generator>
    <managingEditor>brian@softinsight.com</managingEditor>
    <webMaster>brian@softinsight.com</webMaster>
    <item>
      <trackback:ping>http://www.softinsight.com/bnoyes/Trackback.aspx?guid=0bb36661-ccbc-484b-b714-ff373d146662</trackback:ping>
      <pingback:server>http://www.softinsight.com/bnoyes/pingback.aspx</pingback:server>
      <pingback:target>http://www.softinsight.com/bnoyes/PermaLink,guid,0bb36661-ccbc-484b-b714-ff373d146662.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.softinsight.com/bnoyes/CommentView,guid,0bb36661-ccbc-484b-b714-ff373d146662.aspx</wfw:comment>
      <wfw:commentRss>http://www.softinsight.com/bnoyes/SyndicationService.asmx/GetEntryCommentsRss?guid=0bb36661-ccbc-484b-b714-ff373d146662</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
One of the things I’ll be working on for the first half of this year is a new book
project, co-authoring Learning WCF 2nd Edition with my colleague <a href="http://www.dasblonde.com" target="_blank">Michele
Leroux Bustamante</a>. Michele wrote <a href="http://oreilly.com/catalog/9780596101626" target="_blank">Learning
WCF</a> over 2 and a half years ago, and WCF has changed a lot since .NET 3.0. It
is still current and correct with respect to what was there in 3.0 and continues to
work fine, but we have gotten a lot of new capabilities and different ways to do things
in the last few years with WCF.
</p>
        <p>
Michele was nice enough to give me an opportunity to split the effort of rewriting
the book, which I gladly accepted. WCF is a big part of our core business at <a href="http://www.idesign.net" target="_blank">IDesign</a>,
and I have been teaching and consulting on WCF since the early betas and involved
even before that as a product team advisor, so it is a natural fit for me.
</p>
        <p>
Its been over 3 years since I finished my last book (<a href="http://www.amazon.com/Smart-Client-Deployment-ClickOnce-Applications/dp/0321197690" target="_blank">Smart
Client Deployment with ClickOnce</a>) and the LiveLesson DVD <a href="http://www.amazon.com/Developing-Applications-Workflow-Foundation-Training/dp/0321503139" target="_blank">Developing
Applications with Windows Workflow Foundation</a>, so I have been wanting to get started
on a new book project for a while now. 
</p>
        <p>
So it is back to the mode where every free minute is consumed with “I need to work
on the book”. :)
</p>
        <p>
We will be updating all the core chapters to include all the new features that came
in 3.5, 3.5 SP1, and coming in 4.0. We will also have a lot of new content on claims-based
and federated identity, REST-based WCF services, WCF and cloud (Azure) services, WF
4 Workflow Services, and more. We are gearing it so that those who read the first
edition of Learning WCF will still have a ton of new content and will be able to refresh
their skill set based on where we are at in WCF 4.0, and those who are picking it
up for the first time will have a great end-to-end coverage bringing them up to speed
on WCF 4 as well.
</p>
        <p>
Like the first edition, the chapters follow a tutorial-style format – some up front
conceptual material, and then lots of step-by-step hands-on lab style examples that
you can either just read or better yet, follow through and do yourself to cement the
concepts and coding practices.
</p>
        <p>
It should be out around TechEd timeframe this summer, possibly with parts on <a href="http://oreilly.com/roughcuts/" target="_blank">Rough
Cuts</a> before then.
</p>
        <img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=0bb36661-ccbc-484b-b714-ff373d146662" />
      </body>
      <title>New Book Project &amp;ndash; Learning WCF 2nd Edition</title>
      <guid isPermaLink="false">http://www.softinsight.com/bnoyes/PermaLink,guid,0bb36661-ccbc-484b-b714-ff373d146662.aspx</guid>
      <link>http://www.softinsight.com/bnoyes/2010/01/19/NewBookProjectNdashLearningWCF2ndEdition.aspx</link>
      <pubDate>Tue, 19 Jan 2010 15:13:05 GMT</pubDate>
      <description>&lt;p&gt;
One of the things I’ll be working on for the first half of this year is a new book
project, co-authoring Learning WCF 2nd Edition with my colleague &lt;a href="http://www.dasblonde.com" target="_blank"&gt;Michele
Leroux Bustamante&lt;/a&gt;. Michele wrote &lt;a href="http://oreilly.com/catalog/9780596101626" target="_blank"&gt;Learning
WCF&lt;/a&gt; over 2 and a half years ago, and WCF has changed a lot since .NET 3.0. It
is still current and correct with respect to what was there in 3.0 and continues to
work fine, but we have gotten a lot of new capabilities and different ways to do things
in the last few years with WCF.
&lt;/p&gt;
&lt;p&gt;
Michele was nice enough to give me an opportunity to split the effort of rewriting
the book, which I gladly accepted. WCF is a big part of our core business at &lt;a href="http://www.idesign.net" target="_blank"&gt;IDesign&lt;/a&gt;,
and I have been teaching and consulting on WCF since the early betas and involved
even before that as a product team advisor, so it is a natural fit for me.
&lt;/p&gt;
&lt;p&gt;
Its been over 3 years since I finished my last book (&lt;a href="http://www.amazon.com/Smart-Client-Deployment-ClickOnce-Applications/dp/0321197690" target="_blank"&gt;Smart
Client Deployment with ClickOnce&lt;/a&gt;) and the LiveLesson DVD &lt;a href="http://www.amazon.com/Developing-Applications-Workflow-Foundation-Training/dp/0321503139" target="_blank"&gt;Developing
Applications with Windows Workflow Foundation&lt;/a&gt;, so I have been wanting to get started
on a new book project for a while now. 
&lt;/p&gt;
&lt;p&gt;
So it is back to the mode where every free minute is consumed with “I need to work
on the book”. :)
&lt;/p&gt;
&lt;p&gt;
We will be updating all the core chapters to include all the new features that came
in 3.5, 3.5 SP1, and coming in 4.0. We will also have a lot of new content on claims-based
and federated identity, REST-based WCF services, WCF and cloud (Azure) services, WF
4 Workflow Services, and more. We are gearing it so that those who read the first
edition of Learning WCF will still have a ton of new content and will be able to refresh
their skill set based on where we are at in WCF 4.0, and those who are picking it
up for the first time will have a great end-to-end coverage bringing them up to speed
on WCF 4 as well.
&lt;/p&gt;
&lt;p&gt;
Like the first edition, the chapters follow a tutorial-style format – some up front
conceptual material, and then lots of step-by-step hands-on lab style examples that
you can either just read or better yet, follow through and do yourself to cement the
concepts and coding practices.
&lt;/p&gt;
&lt;p&gt;
It should be out around TechEd timeframe this summer, possibly with parts on &lt;a href="http://oreilly.com/roughcuts/" target="_blank"&gt;Rough
Cuts&lt;/a&gt; before then.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=0bb36661-ccbc-484b-b714-ff373d146662" /&gt;</description>
      <comments>http://www.softinsight.com/bnoyes/CommentView,guid,0bb36661-ccbc-484b-b714-ff373d146662.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.softinsight.com/bnoyes/Trackback.aspx?guid=68ece2bb-9dd7-4b1b-8dc4-c5d5f914031b</trackback:ping>
      <pingback:server>http://www.softinsight.com/bnoyes/pingback.aspx</pingback:server>
      <pingback:target>http://www.softinsight.com/bnoyes/PermaLink,guid,68ece2bb-9dd7-4b1b-8dc4-c5d5f914031b.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.softinsight.com/bnoyes/CommentView,guid,68ece2bb-9dd7-4b1b-8dc4-c5d5f914031b.aspx</wfw:comment>
      <wfw:commentRss>http://www.softinsight.com/bnoyes/SyndicationService.asmx/GetEntryCommentsRss?guid=68ece2bb-9dd7-4b1b-8dc4-c5d5f914031b</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Always a nice way to start the new year, with the email telling me I have been awarded <a href="https://mvp.support.microsoft.com/">Microsoft
MVP</a> for another year. This makes 7 years running, a good streak that I hope to
continue.
</p>
        <p>
Being an MVP means a lot of things to a lot of different people. Things I love about
the program are numerous:
</p>
        <ul>
          <li>
Direct access to product team members that really seem to listen and respond based
on the fact that you are an MVP</li>
          <li>
Opportunities to participate in early adopter events, SDRs, feedback sessions to help
shape where Microsoft takes its developer products</li>
          <li>
Opportunities to teach and evangelize those products to the community</li>
          <li>
Recognition of expertise from customers based on the title</li>
          <li>
MSDN and TechNet subscriptions</li>
        </ul>
        <p>
This year I’ll be continuing to have a split focus between both connected systems
(WCF and WF in particular) and client technologies (Silverlight and WPF). Lots of
conferences, classes, user groups, code camps and things like that already planned
or to be planned. Also a lot of writing this year (more on that in a subsequent post)
and plan to get more MSDN webcasts going this year as well.
</p>
        <p>
Its going to be an exciting year and an exciting decade. Bring on the technology!
</p>
        <img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=68ece2bb-9dd7-4b1b-8dc4-c5d5f914031b" />
      </body>
      <title>MVP &amp;ndash; Connected Systems for another year</title>
      <guid isPermaLink="false">http://www.softinsight.com/bnoyes/PermaLink,guid,68ece2bb-9dd7-4b1b-8dc4-c5d5f914031b.aspx</guid>
      <link>http://www.softinsight.com/bnoyes/2010/01/01/MVPNdashConnectedSystemsForAnotherYear.aspx</link>
      <pubDate>Fri, 01 Jan 2010 15:37:43 GMT</pubDate>
      <description>&lt;p&gt;
Always a nice way to start the new year, with the email telling me I have been awarded &lt;a href="https://mvp.support.microsoft.com/"&gt;Microsoft
MVP&lt;/a&gt; for another year. This makes 7 years running, a good streak that I hope to
continue.
&lt;/p&gt;
&lt;p&gt;
Being an MVP means a lot of things to a lot of different people. Things I love about
the program are numerous:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Direct access to product team members that really seem to listen and respond based
on the fact that you are an MVP&lt;/li&gt;
&lt;li&gt;
Opportunities to participate in early adopter events, SDRs, feedback sessions to help
shape where Microsoft takes its developer products&lt;/li&gt;
&lt;li&gt;
Opportunities to teach and evangelize those products to the community&lt;/li&gt;
&lt;li&gt;
Recognition of expertise from customers based on the title&lt;/li&gt;
&lt;li&gt;
MSDN and TechNet subscriptions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
This year I’ll be continuing to have a split focus between both connected systems
(WCF and WF in particular) and client technologies (Silverlight and WPF). Lots of
conferences, classes, user groups, code camps and things like that already planned
or to be planned. Also a lot of writing this year (more on that in a subsequent post)
and plan to get more MSDN webcasts going this year as well.
&lt;/p&gt;
&lt;p&gt;
Its going to be an exciting year and an exciting decade. Bring on the technology!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=68ece2bb-9dd7-4b1b-8dc4-c5d5f914031b" /&gt;</description>
      <comments>http://www.softinsight.com/bnoyes/CommentView,guid,68ece2bb-9dd7-4b1b-8dc4-c5d5f914031b.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.softinsight.com/bnoyes/Trackback.aspx?guid=01ee82c5-4146-48bb-bee1-17893ba7878d</trackback:ping>
      <pingback:server>http://www.softinsight.com/bnoyes/pingback.aspx</pingback:server>
      <pingback:target>http://www.softinsight.com/bnoyes/PermaLink,guid,01ee82c5-4146-48bb-bee1-17893ba7878d.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.softinsight.com/bnoyes/CommentView,guid,01ee82c5-4146-48bb-bee1-17893ba7878d.aspx</wfw:comment>
      <wfw:commentRss>http://www.softinsight.com/bnoyes/SyndicationService.asmx/GetEntryCommentsRss?guid=01ee82c5-4146-48bb-bee1-17893ba7878d</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I just finished reading <em><a href="http://oreilly.com/catalog/9780596802004">Confessions
of a Public Speaker</a></em> by <a href="http://www.scottberkun.com/">Scott Berkun</a>,
thanks to the recommendation from <a href="http://www.stephenforte.net/">Stephen Forte</a>.
I’d highly recommend this book for anyone who gives talks at user groups, conferences,
code camps or even just tech leads and developers who have to present to their team
from time to time. Doesn’t matter if you are a deeply experienced speaker or someone
just trying to expand your exposure and knowledge, this book is good for all who do
any speaking to groups.
</p>
        <p>
It is a quick and entertaining read, highly suitable for e-Book (I read the entire
book over a dozen or so workouts on the elliptical machine at the gym using <a href="http://www.amazon.com/gp/feature.html?ie=UTF8&amp;docId=1000301301">Kindle
for iPhone</a>), and offers great insights and enjoyable stories that will help anyone
who has to talk to crowds small to large. Scott does a great job of capturing the
experiences, challenges, and recommended techniques from a lot of public speaking. 
It will help you get over fears, figure out ways to improve your presentation techniques
and communication effectiveness, and generally just make preparing for and delivering
a talk a much better and easier thing.
</p>
        <img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=01ee82c5-4146-48bb-bee1-17893ba7878d" />
      </body>
      <title>Read and Recommended: Confessions of a Public Speaker</title>
      <guid isPermaLink="false">http://www.softinsight.com/bnoyes/PermaLink,guid,01ee82c5-4146-48bb-bee1-17893ba7878d.aspx</guid>
      <link>http://www.softinsight.com/bnoyes/2009/12/31/ReadAndRecommendedConfessionsOfAPublicSpeaker.aspx</link>
      <pubDate>Thu, 31 Dec 2009 14:31:42 GMT</pubDate>
      <description>&lt;p&gt;
I just finished reading &lt;em&gt;&lt;a href="http://oreilly.com/catalog/9780596802004"&gt;Confessions
of a Public Speaker&lt;/a&gt;&lt;/em&gt; by &lt;a href="http://www.scottberkun.com/"&gt;Scott Berkun&lt;/a&gt;,
thanks to the recommendation from &lt;a href="http://www.stephenforte.net/"&gt;Stephen Forte&lt;/a&gt;.
I’d highly recommend this book for anyone who gives talks at user groups, conferences,
code camps or even just tech leads and developers who have to present to their team
from time to time. Doesn’t matter if you are a deeply experienced speaker or someone
just trying to expand your exposure and knowledge, this book is good for all who do
any speaking to groups.
&lt;/p&gt;
&lt;p&gt;
It is a quick and entertaining read, highly suitable for e-Book (I read the entire
book over a dozen or so workouts on the elliptical machine at the gym using &lt;a href="http://www.amazon.com/gp/feature.html?ie=UTF8&amp;amp;docId=1000301301"&gt;Kindle
for iPhone&lt;/a&gt;), and offers great insights and enjoyable stories that will help anyone
who has to talk to crowds small to large. Scott does a great job of capturing the
experiences, challenges, and recommended techniques from a lot of public speaking.&amp;#160;
It will help you get over fears, figure out ways to improve your presentation techniques
and communication effectiveness, and generally just make preparing for and delivering
a talk a much better and easier thing.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=01ee82c5-4146-48bb-bee1-17893ba7878d" /&gt;</description>
      <comments>http://www.softinsight.com/bnoyes/CommentView,guid,01ee82c5-4146-48bb-bee1-17893ba7878d.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.softinsight.com/bnoyes/Trackback.aspx?guid=0e12d577-8246-4fc9-8928-24942c1c32c7</trackback:ping>
      <pingback:server>http://www.softinsight.com/bnoyes/pingback.aspx</pingback:server>
      <pingback:target>http://www.softinsight.com/bnoyes/PermaLink,guid,0e12d577-8246-4fc9-8928-24942c1c32c7.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.softinsight.com/bnoyes/CommentView,guid,0e12d577-8246-4fc9-8928-24942c1c32c7.aspx</wfw:comment>
      <wfw:commentRss>http://www.softinsight.com/bnoyes/SyndicationService.asmx/GetEntryCommentsRss?guid=0e12d577-8246-4fc9-8928-24942c1c32c7</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I was selected to speak this year at <a href="http://www.devteach.com/Session.aspx">DevTeach
Toronto</a> and will be giving two talks:
</p>
        <p>
Leverage WCF RIA Services for a Quick N-Tier Silverlight Solution
</p>
        <p>
Separate Your UI Concerns with MVVM &amp; Prism
</p>
        <p>
I’m really looking forward to it. DevTeach is a great little show densely packed with
awesome speakers, so I count myself lucky to be included among them. It has been a
couple of years since I have been able to speak there due to schedule conflicts with
all of their shows, so I am happy the timing worked out this year to be able to go.
</p>
        <img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=0e12d577-8246-4fc9-8928-24942c1c32c7" />
      </body>
      <title>Speaking at DevTeach Toronto March 8-12</title>
      <guid isPermaLink="false">http://www.softinsight.com/bnoyes/PermaLink,guid,0e12d577-8246-4fc9-8928-24942c1c32c7.aspx</guid>
      <link>http://www.softinsight.com/bnoyes/2009/12/18/SpeakingAtDevTeachTorontoMarch812.aspx</link>
      <pubDate>Fri, 18 Dec 2009 13:50:19 GMT</pubDate>
      <description>&lt;p&gt;
I was selected to speak this year at &lt;a href="http://www.devteach.com/Session.aspx"&gt;DevTeach
Toronto&lt;/a&gt; and will be giving two talks:
&lt;/p&gt;
&lt;p&gt;
Leverage WCF RIA Services for a Quick N-Tier Silverlight Solution
&lt;/p&gt;
&lt;p&gt;
Separate Your UI Concerns with MVVM &amp;amp; Prism
&lt;/p&gt;
&lt;p&gt;
I’m really looking forward to it. DevTeach is a great little show densely packed with
awesome speakers, so I count myself lucky to be included among them. It has been a
couple of years since I have been able to speak there due to schedule conflicts with
all of their shows, so I am happy the timing worked out this year to be able to go.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=0e12d577-8246-4fc9-8928-24942c1c32c7" /&gt;</description>
      <comments>http://www.softinsight.com/bnoyes/CommentView,guid,0e12d577-8246-4fc9-8928-24942c1c32c7.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.softinsight.com/bnoyes/Trackback.aspx?guid=91b3ba87-88be-47b2-9ffe-409b39791982</trackback:ping>
      <pingback:server>http://www.softinsight.com/bnoyes/pingback.aspx</pingback:server>
      <pingback:target>http://www.softinsight.com/bnoyes/PermaLink,guid,91b3ba87-88be-47b2-9ffe-409b39791982.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.softinsight.com/bnoyes/CommentView,guid,91b3ba87-88be-47b2-9ffe-409b39791982.aspx</wfw:comment>
      <wfw:commentRss>http://www.softinsight.com/bnoyes/SyndicationService.asmx/GetEntryCommentsRss?guid=91b3ba87-88be-47b2-9ffe-409b39791982</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A bit overdue, but a while back I wrote a post on handling graceful shutdown in a <a href="http://www.microsoft.com/compositewpf" target="_blank">Prism</a> application
through the use of commands <a href="http://www.softinsight.com/bnoyes/2009/09/05/SupportingGracefulShutdownAndSavingOnCloseFromAWPFPrismApp.aspx" target="_blank">here</a> and <a href="http://www.softinsight.com/bnoyes/2009/10/05/AvoidingMemoryLeaksWithCompositeCommands.aspx" target="_blank">here</a>.
In those posts, I also promised to talk about detecting active views.
</p>
        <p>
Baked into the Prism code since version 1 is an ability to detect when a view is active
automatically as long the view is hosted in a region. It is a bit under-documented
and hard to discover, but actually works quite nicely for a lot of scenarios. 
</p>
        <p>
Specifically in the example simple document editor I showed in the previous posts,
I needed to detect when a given document was active so that I could enable or disable
the global Save button in the toolbar based on the active document. That was based
on state associated with the view in its ViewModel, a dirty flag indicating whether
the document had been edited or not. In other contexts you might fire a pub-sub event
indicating an active item, or you could change a bunch of formatting on the fly based
on the active or inactive state of the view.
</p>
        <p>
It actually takes very little code to get this done.
</p>
        <p>
Part of the infrastructure code for Prism includes some things called region adapters.
You mostly don’t have to even know they are there, but they provide the bridge between
the abstract concept of a region and a specific type of container control in WPF or
Silverlight. If the region that a view ends up in supports selection (specifically
derives from Selector in WPF or Silverlight or is a custom container with its own
region adapter that indicates selection), then when the view is selected (i.e. TabItem
selected in a TabControl, ListBoxItem selected in a ListBox control, ListViewItem
selected in a ListView), a behavior in the region is invoked that checks the view
to see if it supports the IActiveAware interface.
</p>
        <h4>IActiveAware
</h4>
        <p>
IActiveAware is a simple interface you can implement on your views to indicate that
you want the view to be notified when it is made active or inactive. It looks like
this:
</p>
        <pre class="csharpcode">
          <span class="kwrd">public</span>
          <span class="kwrd">interface</span> IActiveAware
{ <span class="rem">/// &lt;summary&gt;</span><span class="rem">/// Gets or sets
a value indicating whether the object is active.</span><span class="rem">/// &lt;/summary&gt;</span><span class="rem">///
&lt;value&gt;&lt;see langword="true" /&gt; if the object is active; otherwise
&lt;see langword="false" /&gt;.&lt;/value&gt;</span><span class="kwrd">bool</span> IsActive
{ get; set; } <span class="rem">/// &lt;summary&gt;</span><span class="rem">/// Notifies
that the value for &lt;see cref="IsActive"/&gt; property has changed.</span><span class="rem">///
&lt;/summary&gt;</span><span class="kwrd">event</span> EventHandler IsActiveChanged;
}</pre>
        <p>
          <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
The IsActive flag lets you know if your view is active, and the IsActiveChanged event
will fire when that state changes.
</p>
        <p>
If you implement this on your view class (typically a user control), then you need
to ensure the event gets fired when the state is changed by the region behavior. Since
you shouldn’t put the actual logic code of what to do when that active state changes
in the view definition itself, you will also want to get that state change transmitted
into the view model. If you are following the typical pattern for ViewModel, your
ViewModel will be set as the DataContext for the view. You can also implement IActiveAware
on the ViewModel and have a nice decoupled way to dispatch the state change into the
ViewModel without coupling the view to the ViewModel.
</p>
        <p>
In the sample document editor, the view implementation of the interface looks like
the following:
</p>
        <pre class="csharpcode">
          <span class="kwrd">private</span>
          <span class="kwrd">bool</span> _IsActive; <span class="kwrd">public</span><span class="kwrd">bool</span> IsActive
{ get { <span class="kwrd">return</span> _IsActive; } set { _IsActive = <span class="kwrd">value</span>;
IActiveAware vmAware = DataContext <span class="kwrd">as</span> IActiveAware; <span class="kwrd">if</span> (vmAware
!= <span class="kwrd">null</span>) vmAware.IsActive = <span class="kwrd">value</span>;
} } <span class="kwrd">public</span><span class="kwrd">event</span> EventHandler
IsActiveChanged = <span class="kwrd">delegate</span> { };</pre>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
 
</p>
        <p>
The setter for the IsActive property will again be called by the region behavior,
and in that setter, we take care of both firing the event on the view (since it fully
implements IActiveAware) and also pass the setting call into the ViewModel if appropriate
by checking to see if the object set as the ViewModel implements IActiveAware as well.
If it does, we just set its IsActive property to the value being set on the view itself. 
</p>
        <p>
Notice the syntax for the IsActiveChanged event. We call this the “delegate trick”.
By declaring an empty anonymous delegate for the event, you are basically subscribing
for the life of the object a single, no-op subscriber to the list who cannot be removed.
That means that not only can you blindly fire the event without checking for null,
but it also solves a nasty little race condition if your null check gets called right
before a thread interrupt and the last subscriber is removed before your thread resumes.
The question always comes up of whether that will have a performance impact. The strict
answer is yes. A couple extra instructions on the stack when you fire your event.
A few nanoseconds lost on a modern machine. If that is truly the performance bottleneck
in your program, contact me – I want to hire you, because you are the best programmer
on the planet or I don’t want to hire you because you are not building anything real.
</p>
        <p>
The ViewModel implementation of the IActiveAware interface is where the real work
gets done, specifically setting the enabled state of the Save command.
</p>
        <pre class="csharpcode">
          <span class="kwrd">public</span>
          <span class="kwrd">bool</span> IsActive
{ get { <span class="kwrd">return</span> _IsActive; } set { _IsActive = <span class="kwrd">value</span>;
SaveCommand.IsActive = <span class="kwrd">value</span>; IsActiveChanged(<span class="kwrd">this</span>,
EventArgs.Empty); } } <span class="kwrd">public</span><span class="kwrd">event</span> EventHandler
IsActiveChanged = <span class="kwrd">delegate</span> { };</pre>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
 
</p>
        <p>
So that’s it. Simple, effective. Implement IActiveAware on your view. Dispatch the
setting of the IsActive property into your ViewModel by casting the DataContext to
IActiveAware and implementing IActiveAware on your ViewModel. In your ViewModel, do
whatever behavior is appropriate for your view.
</p>
        <p>
Any comments or questions welcome.
</p>
        <img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=91b3ba87-88be-47b2-9ffe-409b39791982" />
      </body>
      <title>Detecting the Active View in a Prism App</title>
      <guid isPermaLink="false">http://www.softinsight.com/bnoyes/PermaLink,guid,91b3ba87-88be-47b2-9ffe-409b39791982.aspx</guid>
      <link>http://www.softinsight.com/bnoyes/2009/12/08/DetectingTheActiveViewInAPrismApp.aspx</link>
      <pubDate>Tue, 08 Dec 2009 03:03:52 GMT</pubDate>
      <description>&lt;p&gt;
A bit overdue, but a while back I wrote a post on handling graceful shutdown in a &lt;a href="http://www.microsoft.com/compositewpf" target="_blank"&gt;Prism&lt;/a&gt; application
through the use of commands &lt;a href="http://www.softinsight.com/bnoyes/2009/09/05/SupportingGracefulShutdownAndSavingOnCloseFromAWPFPrismApp.aspx" target="_blank"&gt;here&lt;/a&gt; and &lt;a href="http://www.softinsight.com/bnoyes/2009/10/05/AvoidingMemoryLeaksWithCompositeCommands.aspx" target="_blank"&gt;here&lt;/a&gt;.
In those posts, I also promised to talk about detecting active views.
&lt;/p&gt;
&lt;p&gt;
Baked into the Prism code since version 1 is an ability to detect when a view is active
automatically as long the view is hosted in a region. It is a bit under-documented
and hard to discover, but actually works quite nicely for a lot of scenarios. 
&lt;/p&gt;
&lt;p&gt;
Specifically in the example simple document editor I showed in the previous posts,
I needed to detect when a given document was active so that I could enable or disable
the global Save button in the toolbar based on the active document. That was based
on state associated with the view in its ViewModel, a dirty flag indicating whether
the document had been edited or not. In other contexts you might fire a pub-sub event
indicating an active item, or you could change a bunch of formatting on the fly based
on the active or inactive state of the view.
&lt;/p&gt;
&lt;p&gt;
It actually takes very little code to get this done.
&lt;/p&gt;
&lt;p&gt;
Part of the infrastructure code for Prism includes some things called region adapters.
You mostly don’t have to even know they are there, but they provide the bridge between
the abstract concept of a region and a specific type of container control in WPF or
Silverlight. If the region that a view ends up in supports selection (specifically
derives from Selector in WPF or Silverlight or is a custom container with its own
region adapter that indicates selection), then when the view is selected (i.e. TabItem
selected in a TabControl, ListBoxItem selected in a ListBox control, ListViewItem
selected in a ListView), a behavior in the region is invoked that checks the view
to see if it supports the IActiveAware interface.
&lt;/p&gt;
&lt;h4&gt;IActiveAware
&lt;/h4&gt;
&lt;p&gt;
IActiveAware is a simple interface you can implement on your views to indicate that
you want the view to be notified when it is made active or inactive. It looks like
this:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; IActiveAware
{ &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt; &lt;span class="rem"&gt;/// Gets or sets
a value indicating whether the object is active.&lt;/span&gt; &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt; &lt;span class="rem"&gt;///
&amp;lt;value&amp;gt;&amp;lt;see langword=&amp;quot;true&amp;quot; /&amp;gt; if the object is active; otherwise
&amp;lt;see langword=&amp;quot;false&amp;quot; /&amp;gt;.&amp;lt;/value&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IsActive
{ get; set; } &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt; &lt;span class="rem"&gt;/// Notifies
that the value for &amp;lt;see cref=&amp;quot;IsActive&amp;quot;/&amp;gt; property has changed.&lt;/span&gt; &lt;span class="rem"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;event&lt;/span&gt; EventHandler IsActiveChanged;
}&lt;/pre&gt;
&lt;p&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
The IsActive flag lets you know if your view is active, and the IsActiveChanged event
will fire when that state changes.
&lt;/p&gt;
&lt;p&gt;
If you implement this on your view class (typically a user control), then you need
to ensure the event gets fired when the state is changed by the region behavior. Since
you shouldn’t put the actual logic code of what to do when that active state changes
in the view definition itself, you will also want to get that state change transmitted
into the view model. If you are following the typical pattern for ViewModel, your
ViewModel will be set as the DataContext for the view. You can also implement IActiveAware
on the ViewModel and have a nice decoupled way to dispatch the state change into the
ViewModel without coupling the view to the ViewModel.
&lt;/p&gt;
&lt;p&gt;
In the sample document editor, the view implementation of the interface looks like
the following:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; _IsActive; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IsActive
{ get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _IsActive; } set { _IsActive = &lt;span class="kwrd"&gt;value&lt;/span&gt;;
IActiveAware vmAware = DataContext &lt;span class="kwrd"&gt;as&lt;/span&gt; IActiveAware; &lt;span class="kwrd"&gt;if&lt;/span&gt; (vmAware
!= &lt;span class="kwrd"&gt;null&lt;/span&gt;) vmAware.IsActive = &lt;span class="kwrd"&gt;value&lt;/span&gt;;
} } &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;event&lt;/span&gt; EventHandler
IsActiveChanged = &lt;span class="kwrd"&gt;delegate&lt;/span&gt; { };&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
The setter for the IsActive property will again be called by the region behavior,
and in that setter, we take care of both firing the event on the view (since it fully
implements IActiveAware) and also pass the setting call into the ViewModel if appropriate
by checking to see if the object set as the ViewModel implements IActiveAware as well.
If it does, we just set its IsActive property to the value being set on the view itself. 
&lt;/p&gt;
&lt;p&gt;
Notice the syntax for the IsActiveChanged event. We call this the “delegate trick”.
By declaring an empty anonymous delegate for the event, you are basically subscribing
for the life of the object a single, no-op subscriber to the list who cannot be removed.
That means that not only can you blindly fire the event without checking for null,
but it also solves a nasty little race condition if your null check gets called right
before a thread interrupt and the last subscriber is removed before your thread resumes.
The question always comes up of whether that will have a performance impact. The strict
answer is yes. A couple extra instructions on the stack when you fire your event.
A few nanoseconds lost on a modern machine. If that is truly the performance bottleneck
in your program, contact me – I want to hire you, because you are the best programmer
on the planet or I don’t want to hire you because you are not building anything real.
&lt;/p&gt;
&lt;p&gt;
The ViewModel implementation of the IActiveAware interface is where the real work
gets done, specifically setting the enabled state of the Save command.
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IsActive
{ get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _IsActive; } set { _IsActive = &lt;span class="kwrd"&gt;value&lt;/span&gt;;
SaveCommand.IsActive = &lt;span class="kwrd"&gt;value&lt;/span&gt;; IsActiveChanged(&lt;span class="kwrd"&gt;this&lt;/span&gt;,
EventArgs.Empty); } } &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;event&lt;/span&gt; EventHandler
IsActiveChanged = &lt;span class="kwrd"&gt;delegate&lt;/span&gt; { };&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
So that’s it. Simple, effective. Implement IActiveAware on your view. Dispatch the
setting of the IsActive property into your ViewModel by casting the DataContext to
IActiveAware and implementing IActiveAware on your ViewModel. In your ViewModel, do
whatever behavior is appropriate for your view.
&lt;/p&gt;
&lt;p&gt;
Any comments or questions welcome.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=91b3ba87-88be-47b2-9ffe-409b39791982" /&gt;</description>
      <comments>http://www.softinsight.com/bnoyes/CommentView,guid,91b3ba87-88be-47b2-9ffe-409b39791982.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.softinsight.com/bnoyes/Trackback.aspx?guid=7c7997a8-bcd1-4304-93b7-f48f365ca225</trackback:ping>
      <pingback:server>http://www.softinsight.com/bnoyes/pingback.aspx</pingback:server>
      <pingback:target>http://www.softinsight.com/bnoyes/PermaLink,guid,7c7997a8-bcd1-4304-93b7-f48f365ca225.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.softinsight.com/bnoyes/CommentView,guid,7c7997a8-bcd1-4304-93b7-f48f365ca225.aspx</wfw:comment>
      <wfw:commentRss>http://www.softinsight.com/bnoyes/SyndicationService.asmx/GetEntryCommentsRss?guid=7c7997a8-bcd1-4304-93b7-f48f365ca225</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I gave 4 sessions and repeat recorded a 5th this week at Visual Studio and Architect
Connections in Las Vegas. The line up was as follows:
</p>
        <p>
          <strong>Build Workflow 4.0 Service Applications</strong> – covered the service messaging
capabilities of workflow 4.0. Covered the Receive activity (and coupled SendReply)
for exposing service operations from workflows, as well as Send/ReceiveReply (and
the code generated activities) for calling services. Also covered the three forms
of correlation: Request-Reply, Context (protocol), and Content correlation.
</p>
        <p>
          <a href="http://www.softinsight.com/downloads/Conferences/DevConnections/Noyes_VSC_VVS03_BuildingWF4ServiceApps.pdf" target="_blank">Slides</a>    <a href="http://www.softinsight.com/downloads/Conferences/DevConnections/Noyes_VSC_VVS03_WorkflowServicesDemos.zip" target="_blank">Demos</a></p>
        <p>
          <strong>Wrap Your Head Around Concurrency in WF 4.0</strong> – Covered all the many
forms of concurrency in workflows. Where threads are doing what, how to use the parallel
activities and the pseudo-concurrency that you get with that. Also showed how the
built-in InvokeMethod executes asychronously, as well as how to build a custom async
activity.
</p>
        <p>
          <a href="http://www.softinsight.com/downloads/Conferences/DevConnections/Noyes_VSC_VVS04_WorkflowConcurrency.pdf" target="_blank">Slides</a>   <a href="http://www.softinsight.com/downloads/Conferences/DevConnections/Noyes_VSC_VVS04_WorkflowConcurrencyDemos.zip" target="_blank">Demos</a></p>
        <p>
          <strong>Connecting Smart Clients Through the .NET Service Bus</strong> – Covered basic
use of .NET Service Bus to connect a client to back end services and the benefits
of doing so. Also spent a good deal of time on event driven scenarios -  being
able to push things to the client from back end services or for peer-to-peer communications
from other clients. Discussed current and future state of affairs for document/data
sharing and synchronization.
</p>
        <p>
          <a href="http://www.softinsight.com/downloads/Conferences/DevConnections/Noyes_VSC_VCC08_ConnectingSmartClientsThroughTheServiceBus.pdf" target="_blank">Slides</a>   <a href="http://www.softinsight.com/downloads/Conferences/DevConnections/Noyes_VSC_VCC08_ConnectingSmartClientsThroughTheServiceBusDemos.zip" target="_blank">Demos</a></p>
        <p>
          <strong>Build Testable Client and Service Applications</strong> – Covered practices
and patterns for making applications more testable. Discussed benefits and principals
of TDD, S.O.L.I.D., IoC, DI, Repository, Separated Presentation, and closed with a
number of testability tricks for unit testing.
</p>
        <p>
          <a href="http://www.softinsight.com/downloads/Conferences/DevConnections/Noyes_AC_VAC04_TestableClientAndServiceApplications.pdf" target="_blank">Slides</a>   <a href="http://www.softinsight.com/downloads/Conferences/DevConnections/Noyes_AC_VAC04_TestableClientAndServiceAppsDemos.zip" target="_blank">Demos</a></p>
        <img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=7c7997a8-bcd1-4304-93b7-f48f365ca225" />
      </body>
      <title>Slides and Demos from VS/Architect Connections This Week</title>
      <guid isPermaLink="false">http://www.softinsight.com/bnoyes/PermaLink,guid,7c7997a8-bcd1-4304-93b7-f48f365ca225.aspx</guid>
      <link>http://www.softinsight.com/bnoyes/2009/11/14/SlidesAndDemosFromVSArchitectConnectionsThisWeek.aspx</link>
      <pubDate>Sat, 14 Nov 2009 18:56:11 GMT</pubDate>
      <description>&lt;p&gt;
I gave 4 sessions and repeat recorded a 5th this week at Visual Studio and Architect
Connections in Las Vegas. The line up was as follows:
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Build Workflow 4.0 Service Applications&lt;/strong&gt; – covered the service messaging
capabilities of workflow 4.0. Covered the Receive activity (and coupled SendReply)
for exposing service operations from workflows, as well as Send/ReceiveReply (and
the code generated activities) for calling services. Also covered the three forms
of correlation: Request-Reply, Context (protocol), and Content correlation.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.softinsight.com/downloads/Conferences/DevConnections/Noyes_VSC_VVS03_BuildingWF4ServiceApps.pdf" target="_blank"&gt;Slides&lt;/a&gt;&amp;#160;&amp;#160;&amp;#160; &lt;a href="http://www.softinsight.com/downloads/Conferences/DevConnections/Noyes_VSC_VVS03_WorkflowServicesDemos.zip" target="_blank"&gt;Demos&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Wrap Your Head Around Concurrency in WF 4.0&lt;/strong&gt; – Covered all the many
forms of concurrency in workflows. Where threads are doing what, how to use the parallel
activities and the pseudo-concurrency that you get with that. Also showed how the
built-in InvokeMethod executes asychronously, as well as how to build a custom async
activity.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.softinsight.com/downloads/Conferences/DevConnections/Noyes_VSC_VVS04_WorkflowConcurrency.pdf" target="_blank"&gt;Slides&lt;/a&gt;&amp;#160;&amp;#160; &lt;a href="http://www.softinsight.com/downloads/Conferences/DevConnections/Noyes_VSC_VVS04_WorkflowConcurrencyDemos.zip" target="_blank"&gt;Demos&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Connecting Smart Clients Through the .NET Service Bus&lt;/strong&gt; – Covered basic
use of .NET Service Bus to connect a client to back end services and the benefits
of doing so. Also spent a good deal of time on event driven scenarios -&amp;#160; being
able to push things to the client from back end services or for peer-to-peer communications
from other clients. Discussed current and future state of affairs for document/data
sharing and synchronization.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.softinsight.com/downloads/Conferences/DevConnections/Noyes_VSC_VCC08_ConnectingSmartClientsThroughTheServiceBus.pdf" target="_blank"&gt;Slides&lt;/a&gt;&amp;#160;&amp;#160; &lt;a href="http://www.softinsight.com/downloads/Conferences/DevConnections/Noyes_VSC_VCC08_ConnectingSmartClientsThroughTheServiceBusDemos.zip" target="_blank"&gt;Demos&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Build Testable Client and Service Applications&lt;/strong&gt; – Covered practices
and patterns for making applications more testable. Discussed benefits and principals
of TDD, S.O.L.I.D., IoC, DI, Repository, Separated Presentation, and closed with a
number of testability tricks for unit testing.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.softinsight.com/downloads/Conferences/DevConnections/Noyes_AC_VAC04_TestableClientAndServiceApplications.pdf" target="_blank"&gt;Slides&lt;/a&gt;&amp;#160;&amp;#160; &lt;a href="http://www.softinsight.com/downloads/Conferences/DevConnections/Noyes_AC_VAC04_TestableClientAndServiceAppsDemos.zip" target="_blank"&gt;Demos&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=7c7997a8-bcd1-4304-93b7-f48f365ca225" /&gt;</description>
      <comments>http://www.softinsight.com/bnoyes/CommentView,guid,7c7997a8-bcd1-4304-93b7-f48f365ca225.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.softinsight.com/bnoyes/Trackback.aspx?guid=0e7fa2aa-fab3-4611-be84-0f20aff97a55</trackback:ping>
      <pingback:server>http://www.softinsight.com/bnoyes/pingback.aspx</pingback:server>
      <pingback:target>http://www.softinsight.com/bnoyes/PermaLink,guid,0e7fa2aa-fab3-4611-be84-0f20aff97a55.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.softinsight.com/bnoyes/CommentView,guid,0e7fa2aa-fab3-4611-be84-0f20aff97a55.aspx</wfw:comment>
      <wfw:commentRss>http://www.softinsight.com/bnoyes/SyndicationService.asmx/GetEntryCommentsRss?guid=0e7fa2aa-fab3-4611-be84-0f20aff97a55</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’m working on a project for a customer where we are trying to get a new version of
a product out the door. We need to add some features to an existing API, but don’t
want to break the existing API for existing customers. Common story, common place
to be.
</p>
        <p>
However, in adding these new features, we really need to be modifying an existing
API to add new options to existing methods. But we find ourselves in a place I’ve
seen a number of times: the API tried to be too granular about its arguments. It provided
flexibility for optional arguments with overloaded methods. Not a bad thing from an
OO perspective. The slippery slope is trying to anticipate how many arguments you
might actually need to that method over time and which of those arguments might be
optional.
</p>
        <h4>Defining a Clean, Version Tolerant API
</h4>
        <p>
Say you start with a simple API like this:
</p>
        <pre class="csharpcode">
          <span class="kwrd">public</span>
          <span class="kwrd">interface</span> ISomeInterface
{ <span class="kwrd">void</span> SomeMethod(<span class="kwrd">double</span> alwaysNeeded); <span class="kwrd">void</span> SomeMethod(<span class="kwrd">double</span> alwaysNeeded, <span class="kwrd">int</span> optionArg1); <span class="kwrd">void</span> SomeMethod(<span class="kwrd">double</span> alwaysNeeded, <span class="kwrd">string</span> optionArg2); <span class="kwrd">void</span> SomeMethod(<span class="kwrd">double</span> alwaysNeeded, <span class="kwrd">int</span> optionArg1, <span class="kwrd">string</span> optionArg2);
}</pre>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
There is one always needed argument, and a couple of optional args. Fine when there
are just two options. What about when the list grows to 3, 4, 5, 6? How many overloads
do you have to add to cover all the reasonable combinations of those arguments a user
might want? The size of your API goes exponential, and the usability of it goes downhill
quick.
</p>
        <p>
This is the situation we find ourselves in. And this is why I have long recommended
that unless an API is going to be static and always take the same set of arguments,
you are better off packaging up those arguments in a single complex argument – a data
structure single argument such as the following:
</p>
        <pre class="csharpcode">
          <span class="kwrd">public</span>
          <span class="kwrd">class</span> MyMethodArg
{ <span class="kwrd">public</span><span class="kwrd">double</span> AlwaysNeeded {
get; set; } <span class="kwrd">public</span><span class="kwrd">int</span> OptionalArg1
{ get; set; } <span class="kwrd">public</span><span class="kwrd">string</span> OptionalArg2
{ get; set; } }</pre>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
Then you can simplify the interface definition to just the following:
</p>
        <pre class="csharpcode">
          <span class="kwrd">public</span>
          <span class="kwrd">interface</span> ISomeInterface
{ <span class="kwrd">void</span> SomeMethod(MyMethodArg arg); }</pre>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
Now, over time, you can add additional required or optional arguments without affecting
the interface API at all. As long as you write graceful handling for when optional
parameters are not set explicitly on the data structure, you have much better ability
to change the underlying arguments over time without breaking existing clients. And
you have a much cleaner, easier to understand API.
</p>
        <h4>Extension Methods to the Rescue
</h4>
        <p>
So then the question becomes: If you find yourself with an API that looks like the
original version and you want to move to the cleaner version immediately above, do
you have to break all your existing clients to get there? Thanks to extension methods,
the answer is no.
</p>
        <p>
Say you have existing clients that have code that depends on the original API. A simple
one might look like the following console app:
</p>
        <pre class="csharpcode">
          <span class="kwrd">class</span> Program { <span class="kwrd">static</span><span class="kwrd">void</span> Main(<span class="kwrd">string</span>[]
args) { ISomeInterface itf = <span class="kwrd">new</span> SomeImplementation(); <span class="rem">//
V1 methods - obsolete</span> itf.SomeMethod(1.0); itf.SomeMethod(1.0,42); itf.SomeMethod(1.0,<span class="str">"foo"</span>);
itf.SomeMethod(1.0, 42,<span class="str">"foo"</span>); <span class="rem">//
V2 method</span> itf.SomeMethod(<span class="kwrd">new</span> MyMethodArg { OptionalArg1
= 42 }); Console.WriteLine(<span class="str">"Press Enter to Exit..."</span>);
Console.ReadLine(); } }</pre>
        <p>
          <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        </p>
        <p>
For sample purposes, say the original implementation looked like the following:
</p>
        <pre class="csharpcode">
          <span class="kwrd">public</span>
          <span class="kwrd">class</span> SomeImplementation
: ISomeInterface { <span class="kwrd">void</span> ISomeInterface.SomeMethod(<span class="kwrd">double</span> alwaysNeeded)
{ Debug.WriteLine(<span class="str">"SomeMethod no optional args"</span>);
} <span class="kwrd">void</span> ISomeInterface.SomeMethod(<span class="kwrd">double</span> alwaysNeeded, <span class="kwrd">int</span> arg)
{ Debug.WriteLine(<span class="str">"SomeMethod optional int arg"</span>);
} <span class="kwrd">void</span> ISomeInterface.SomeMethod(<span class="kwrd">double</span> alwaysNeeded, <span class="kwrd">string</span> arg)
{ Debug.WriteLine(<span class="str">"SomeMethod optional string arg"</span>);
} <span class="kwrd">void</span> ISomeInterface.SomeMethod(<span class="kwrd">double</span> alwaysNeeded, <span class="kwrd">int</span> arg1, <span class="kwrd">string</span> arg2)
{ Debug.WriteLine(<span class="str">"SomeMethod optional int and string args"</span>);
} }</pre>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
What you can do is use Extension methods to move the old API off the primary interface
you want to keep for the long term (assuming there are also other methods and properties
on that interface that you want to remain there instead of just defining a new interface
with the new API). You could add the following class to your existing project:
</p>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <pre class="csharpcode">
          <span class="kwrd">public</span>
          <span class="kwrd">static</span>
          <span class="kwrd">class</span> SomeInterfaceExtensions
{ [Obsolete] <span class="kwrd">public</span><span class="kwrd">static</span><span class="kwrd">void</span> SomeMethod(<span class="kwrd">this</span> ISomeInterface
itf, <span class="kwrd">double</span> alwaysNeeded) { itf.SomeMethod(<span class="kwrd">new</span> MyMethodArg
{ AlwaysNeeded = alwaysNeeded }); } [Obsolete] <span class="kwrd">public</span><span class="kwrd">static</span><span class="kwrd">void</span> SomeMethod(<span class="kwrd">this</span> ISomeInterface
itf, <span class="kwrd">double</span> alwaysNeeded, <span class="kwrd">int</span> arg)
{ itf.SomeMethod(<span class="kwrd">new</span> MyMethodArg { AlwaysNeeded = alwaysNeeded,
OptionalArg1 = arg }); } [Obsolete] <span class="kwrd">public</span><span class="kwrd">static</span><span class="kwrd">void</span> SomeMethod(<span class="kwrd">this</span> ISomeInterface
itf, <span class="kwrd">double</span> alwaysNeeded, <span class="kwrd">string</span> arg)
{ itf.SomeMethod(<span class="kwrd">new</span> MyMethodArg { AlwaysNeeded = alwaysNeeded,
OptionalArg2 = arg }); } [Obsolete] <span class="kwrd">public</span><span class="kwrd">static</span><span class="kwrd">void</span> SomeMethod(<span class="kwrd">this</span> ISomeInterface
itf, <span class="kwrd">double</span> alwaysNeeded, <span class="kwrd">int</span> arg1, <span class="kwrd">string</span> arg2)
{ itf.SomeMethod(<span class="kwrd">new</span> MyMethodArg { AlwaysNeeded = alwaysNeeded,
OptionalArg1 = arg1, OptionalArg2 = arg2 }); } }</pre>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
Then, the implementation class can be collapsed to the following:
</p>
        <pre class="csharpcode">
          <span class="kwrd">public</span>
          <span class="kwrd">class</span> SomeImplementation
: ISomeInterface { <span class="kwrd">void</span> ISomeInterface.SomeMethod(MyMethodArg
arg) { Debug.WriteLine(<span class="str">"SomeMethod complex arg"</span>);
} }</pre>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
The client can remained unchanged against the V1 API thanks to the extension methods,
but will now get compiler warnings that the API is obsolete thanks to the Obsolete
attributes. But they won’t break. New clients will not even see the old API unless
they go looking for it, and then they should be smart enough not to write new code
against things marked with the Obsolete attribute when there is a perfectly usable
method on the primary API itself.
</p>
        <p>
So this is the approach we are going to use to move forward the original lack-of-forethought
API and clean it up for the long term.
</p>
        <p>
Obviously this approach will only work if your clients (that you don’t want to break)
are on .NET 3.5. If you could afford to lock them down to just .NET 4.0 or later,
you would have another option with C# optional parameters or default values, but that
is unlikely for most apps at this point in time.
</p>
        <img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=0e7fa2aa-fab3-4611-be84-0f20aff97a55" />
      </body>
      <title>Use Extension Methods to Phase Out a Bad API</title>
      <guid isPermaLink="false">http://www.softinsight.com/bnoyes/PermaLink,guid,0e7fa2aa-fab3-4611-be84-0f20aff97a55.aspx</guid>
      <link>http://www.softinsight.com/bnoyes/2009/11/04/UseExtensionMethodsToPhaseOutABadAPI.aspx</link>
      <pubDate>Wed, 04 Nov 2009 20:51:30 GMT</pubDate>
      <description>&lt;p&gt;
I’m working on a project for a customer where we are trying to get a new version of
a product out the door. We need to add some features to an existing API, but don’t
want to break the existing API for existing customers. Common story, common place
to be.
&lt;/p&gt;
&lt;p&gt;
However, in adding these new features, we really need to be modifying an existing
API to add new options to existing methods. But we find ourselves in a place I’ve
seen a number of times: the API tried to be too granular about its arguments. It provided
flexibility for optional arguments with overloaded methods. Not a bad thing from an
OO perspective. The slippery slope is trying to anticipate how many arguments you
might actually need to that method over time and which of those arguments might be
optional.
&lt;/p&gt;
&lt;h4&gt;Defining a Clean, Version Tolerant API
&lt;/h4&gt;
&lt;p&gt;
Say you start with a simple API like this:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; ISomeInterface
{ &lt;span class="kwrd"&gt;void&lt;/span&gt; SomeMethod(&lt;span class="kwrd"&gt;double&lt;/span&gt; alwaysNeeded); &lt;span class="kwrd"&gt;void&lt;/span&gt; SomeMethod(&lt;span class="kwrd"&gt;double&lt;/span&gt; alwaysNeeded, &lt;span class="kwrd"&gt;int&lt;/span&gt; optionArg1); &lt;span class="kwrd"&gt;void&lt;/span&gt; SomeMethod(&lt;span class="kwrd"&gt;double&lt;/span&gt; alwaysNeeded, &lt;span class="kwrd"&gt;string&lt;/span&gt; optionArg2); &lt;span class="kwrd"&gt;void&lt;/span&gt; SomeMethod(&lt;span class="kwrd"&gt;double&lt;/span&gt; alwaysNeeded, &lt;span class="kwrd"&gt;int&lt;/span&gt; optionArg1, &lt;span class="kwrd"&gt;string&lt;/span&gt; optionArg2);
}&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
There is one always needed argument, and a couple of optional args. Fine when there
are just two options. What about when the list grows to 3, 4, 5, 6? How many overloads
do you have to add to cover all the reasonable combinations of those arguments a user
might want? The size of your API goes exponential, and the usability of it goes downhill
quick.
&lt;/p&gt;
&lt;p&gt;
This is the situation we find ourselves in. And this is why I have long recommended
that unless an API is going to be static and always take the same set of arguments,
you are better off packaging up those arguments in a single complex argument – a data
structure single argument such as the following:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MyMethodArg
{ &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; AlwaysNeeded {
get; set; } &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; OptionalArg1
{ get; set; } &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; OptionalArg2
{ get; set; } }&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
Then you can simplify the interface definition to just the following:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; ISomeInterface
{ &lt;span class="kwrd"&gt;void&lt;/span&gt; SomeMethod(MyMethodArg arg); }&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
Now, over time, you can add additional required or optional arguments without affecting
the interface API at all. As long as you write graceful handling for when optional
parameters are not set explicitly on the data structure, you have much better ability
to change the underlying arguments over time without breaking existing clients. And
you have a much cleaner, easier to understand API.
&lt;/p&gt;
&lt;h4&gt;Extension Methods to the Rescue
&lt;/h4&gt;
&lt;p&gt;
So then the question becomes: If you find yourself with an API that looks like the
original version and you want to move to the cleaner version immediately above, do
you have to break all your existing clients to get there? Thanks to extension methods,
the answer is no.
&lt;/p&gt;
&lt;p&gt;
Say you have existing clients that have code that depends on the original API. A simple
one might look like the following console app:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Program { &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[]
args) { ISomeInterface itf = &lt;span class="kwrd"&gt;new&lt;/span&gt; SomeImplementation(); &lt;span class="rem"&gt;//
V1 methods - obsolete&lt;/span&gt; itf.SomeMethod(1.0); itf.SomeMethod(1.0,42); itf.SomeMethod(1.0,&lt;span class="str"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;);
itf.SomeMethod(1.0, 42,&lt;span class="str"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;); &lt;span class="rem"&gt;//
V2 method&lt;/span&gt; itf.SomeMethod(&lt;span class="kwrd"&gt;new&lt;/span&gt; MyMethodArg { OptionalArg1
= 42 }); Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Press Enter to Exit...&amp;quot;&lt;/span&gt;);
Console.ReadLine(); } }&lt;/pre&gt;
&lt;p&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;/p&gt;
&lt;p&gt;
For sample purposes, say the original implementation looked like the following:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SomeImplementation
: ISomeInterface { &lt;span class="kwrd"&gt;void&lt;/span&gt; ISomeInterface.SomeMethod(&lt;span class="kwrd"&gt;double&lt;/span&gt; alwaysNeeded)
{ Debug.WriteLine(&lt;span class="str"&gt;&amp;quot;SomeMethod no optional args&amp;quot;&lt;/span&gt;);
} &lt;span class="kwrd"&gt;void&lt;/span&gt; ISomeInterface.SomeMethod(&lt;span class="kwrd"&gt;double&lt;/span&gt; alwaysNeeded, &lt;span class="kwrd"&gt;int&lt;/span&gt; arg)
{ Debug.WriteLine(&lt;span class="str"&gt;&amp;quot;SomeMethod optional int arg&amp;quot;&lt;/span&gt;);
} &lt;span class="kwrd"&gt;void&lt;/span&gt; ISomeInterface.SomeMethod(&lt;span class="kwrd"&gt;double&lt;/span&gt; alwaysNeeded, &lt;span class="kwrd"&gt;string&lt;/span&gt; arg)
{ Debug.WriteLine(&lt;span class="str"&gt;&amp;quot;SomeMethod optional string arg&amp;quot;&lt;/span&gt;);
} &lt;span class="kwrd"&gt;void&lt;/span&gt; ISomeInterface.SomeMethod(&lt;span class="kwrd"&gt;double&lt;/span&gt; alwaysNeeded, &lt;span class="kwrd"&gt;int&lt;/span&gt; arg1, &lt;span class="kwrd"&gt;string&lt;/span&gt; arg2)
{ Debug.WriteLine(&lt;span class="str"&gt;&amp;quot;SomeMethod optional int and string args&amp;quot;&lt;/span&gt;);
} }&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
What you can do is use Extension methods to move the old API off the primary interface
you want to keep for the long term (assuming there are also other methods and properties
on that interface that you want to remain there instead of just defining a new interface
with the new API). You could add the following class to your existing project:
&lt;/p&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SomeInterfaceExtensions
{ [Obsolete] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SomeMethod(&lt;span class="kwrd"&gt;this&lt;/span&gt; ISomeInterface
itf, &lt;span class="kwrd"&gt;double&lt;/span&gt; alwaysNeeded) { itf.SomeMethod(&lt;span class="kwrd"&gt;new&lt;/span&gt; MyMethodArg
{ AlwaysNeeded = alwaysNeeded }); } [Obsolete] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SomeMethod(&lt;span class="kwrd"&gt;this&lt;/span&gt; ISomeInterface
itf, &lt;span class="kwrd"&gt;double&lt;/span&gt; alwaysNeeded, &lt;span class="kwrd"&gt;int&lt;/span&gt; arg)
{ itf.SomeMethod(&lt;span class="kwrd"&gt;new&lt;/span&gt; MyMethodArg { AlwaysNeeded = alwaysNeeded,
OptionalArg1 = arg }); } [Obsolete] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SomeMethod(&lt;span class="kwrd"&gt;this&lt;/span&gt; ISomeInterface
itf, &lt;span class="kwrd"&gt;double&lt;/span&gt; alwaysNeeded, &lt;span class="kwrd"&gt;string&lt;/span&gt; arg)
{ itf.SomeMethod(&lt;span class="kwrd"&gt;new&lt;/span&gt; MyMethodArg { AlwaysNeeded = alwaysNeeded,
OptionalArg2 = arg }); } [Obsolete] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SomeMethod(&lt;span class="kwrd"&gt;this&lt;/span&gt; ISomeInterface
itf, &lt;span class="kwrd"&gt;double&lt;/span&gt; alwaysNeeded, &lt;span class="kwrd"&gt;int&lt;/span&gt; arg1, &lt;span class="kwrd"&gt;string&lt;/span&gt; arg2)
{ itf.SomeMethod(&lt;span class="kwrd"&gt;new&lt;/span&gt; MyMethodArg { AlwaysNeeded = alwaysNeeded,
OptionalArg1 = arg1, OptionalArg2 = arg2 }); } }&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
Then, the implementation class can be collapsed to the following:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SomeImplementation
: ISomeInterface { &lt;span class="kwrd"&gt;void&lt;/span&gt; ISomeInterface.SomeMethod(MyMethodArg
arg) { Debug.WriteLine(&lt;span class="str"&gt;&amp;quot;SomeMethod complex arg&amp;quot;&lt;/span&gt;);
} }&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
The client can remained unchanged against the V1 API thanks to the extension methods,
but will now get compiler warnings that the API is obsolete thanks to the Obsolete
attributes. But they won’t break. New clients will not even see the old API unless
they go looking for it, and then they should be smart enough not to write new code
against things marked with the Obsolete attribute when there is a perfectly usable
method on the primary API itself.
&lt;/p&gt;
&lt;p&gt;
So this is the approach we are going to use to move forward the original lack-of-forethought
API and clean it up for the long term.
&lt;/p&gt;
&lt;p&gt;
Obviously this approach will only work if your clients (that you don’t want to break)
are on .NET 3.5. If you could afford to lock them down to just .NET 4.0 or later,
you would have another option with C# optional parameters or default values, but that
is unlikely for most apps at this point in time.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=0e7fa2aa-fab3-4611-be84-0f20aff97a55" /&gt;</description>
      <comments>http://www.softinsight.com/bnoyes/CommentView,guid,0e7fa2aa-fab3-4611-be84-0f20aff97a55.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.softinsight.com/bnoyes/Trackback.aspx?guid=62e392e4-3164-47f7-9ed8-7b87befbb383</trackback:ping>
      <pingback:server>http://www.softinsight.com/bnoyes/pingback.aspx</pingback:server>
      <pingback:target>http://www.softinsight.com/bnoyes/PermaLink,guid,62e392e4-3164-47f7-9ed8-7b87befbb383.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.softinsight.com/bnoyes/CommentView,guid,62e392e4-3164-47f7-9ed8-7b87befbb383.aspx</wfw:comment>
      <wfw:commentRss>http://www.softinsight.com/bnoyes/SyndicationService.asmx/GetEntryCommentsRss?guid=62e392e4-3164-47f7-9ed8-7b87befbb383</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Last week I had the privilege of speaking at the Sydney .NET User’s Group while in
Sydney teaching a WCF Master Class. It was an outstanding group and I spoke on WF
4 and Prism (Composite Application Guidance for WPF and Sliverlight). Had some great
questions and discussion with the attendees, which is always what makes a group stand
out in my mind.
</p>
        <p>
If you want the slides and demos for the talks, you can find them here:
</p>
        <p>
First Look at WF 4:   <a href="http://www.softinsight.com/downloads/INETA/AFirstLookatWF4.pdf" target="_blank">Slides</a>  
(no pre-built demo code, all on the fly demos in VS 2010 Beta 2)
</p>
        <p>
Building Composite WPF and Silverlight Applications:   <a href="http://www.softinsight.com/downloads/INETA/CompositeAppGuidanceforWPF.pdf" target="_blank">Slides</a>    <a href="http://www.softinsight.com/downloads/INETA/CompositeWPFDemosApr2009.zip" target="_blank">Demos</a></p>
        <p>
The other thing that made this group stand out for me (besides the above and the fact
that it is run by friend and fellow RD Adam Cogan from <a href="http://www.ssw.com.au/ssw/">SSW
Software</a>) was that instead of going out for beers or something else unhealthy
afterwards, a small group of us went for a short power walk for some exercise afterwards
around the area of the user group meeting. You can see the route we walked here:
</p>
        <p>
          <a href="http://www.mapmyride.com/route/australia/earlwood/465125612609191527">http://www.mapmyride.com/route/australia/earlwood/465125612609191527</a>
        </p>
        <p>
Nice variation for someone who is trying to lose weight and good chance to keep the
technology discussion going with some of the attendees afterwards. Thanks to Adam
for organizing!
</p>
        <img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=62e392e4-3164-47f7-9ed8-7b87befbb383" />
      </body>
      <title>Sydney .NET User Group Fit Walk</title>
      <guid isPermaLink="false">http://www.softinsight.com/bnoyes/PermaLink,guid,62e392e4-3164-47f7-9ed8-7b87befbb383.aspx</guid>
      <link>http://www.softinsight.com/bnoyes/2009/10/28/SydneyNETUserGroupFitWalk.aspx</link>
      <pubDate>Wed, 28 Oct 2009 16:41:32 GMT</pubDate>
      <description>&lt;p&gt;
Last week I had the privilege of speaking at the Sydney .NET User’s Group while in
Sydney teaching a WCF Master Class. It was an outstanding group and I spoke on WF
4 and Prism (Composite Application Guidance for WPF and Sliverlight). Had some great
questions and discussion with the attendees, which is always what makes a group stand
out in my mind.
&lt;/p&gt;
&lt;p&gt;
If you want the slides and demos for the talks, you can find them here:
&lt;/p&gt;
&lt;p&gt;
First Look at WF 4:&amp;#160;&amp;#160; &lt;a href="http://www.softinsight.com/downloads/INETA/AFirstLookatWF4.pdf" target="_blank"&gt;Slides&lt;/a&gt;&amp;#160;&amp;#160;
(no pre-built demo code, all on the fly demos in VS 2010 Beta 2)
&lt;/p&gt;
&lt;p&gt;
Building Composite WPF and Silverlight Applications:&amp;#160;&amp;#160; &lt;a href="http://www.softinsight.com/downloads/INETA/CompositeAppGuidanceforWPF.pdf" target="_blank"&gt;Slides&lt;/a&gt;&amp;#160;&amp;#160;&amp;#160; &lt;a href="http://www.softinsight.com/downloads/INETA/CompositeWPFDemosApr2009.zip" target="_blank"&gt;Demos&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
The other thing that made this group stand out for me (besides the above and the fact
that it is run by friend and fellow RD Adam Cogan from &lt;a href="http://www.ssw.com.au/ssw/"&gt;SSW
Software&lt;/a&gt;) was that instead of going out for beers or something else unhealthy
afterwards, a small group of us went for a short power walk for some exercise afterwards
around the area of the user group meeting. You can see the route we walked here:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.mapmyride.com/route/australia/earlwood/465125612609191527"&gt;http://www.mapmyride.com/route/australia/earlwood/465125612609191527&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Nice variation for someone who is trying to lose weight and good chance to keep the
technology discussion going with some of the attendees afterwards. Thanks to Adam
for organizing!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=62e392e4-3164-47f7-9ed8-7b87befbb383" /&gt;</description>
      <comments>http://www.softinsight.com/bnoyes/CommentView,guid,62e392e4-3164-47f7-9ed8-7b87befbb383.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.softinsight.com/bnoyes/Trackback.aspx?guid=501f1345-e8f2-42bd-a4d7-08e59e38bcc1</trackback:ping>
      <pingback:server>http://www.softinsight.com/bnoyes/pingback.aspx</pingback:server>
      <pingback:target>http://www.softinsight.com/bnoyes/PermaLink,guid,501f1345-e8f2-42bd-a4d7-08e59e38bcc1.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.softinsight.com/bnoyes/CommentView,guid,501f1345-e8f2-42bd-a4d7-08e59e38bcc1.aspx</wfw:comment>
      <wfw:commentRss>http://www.softinsight.com/bnoyes/SyndicationService.asmx/GetEntryCommentsRss?guid=501f1345-e8f2-42bd-a4d7-08e59e38bcc1</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’m spending the next two weeks in Australia to teach some classes and speak at some
user groups. This week, 12-16 Oct, I am teaching our <a href="http://www.idesign.net/idesign/DesktopDefault.aspx?tabindex=0&amp;tabid=23" target="_blank">Architect
Master Class</a> through our training partner <a href="http://readify.net/" target="_blank">Readify</a> in
Melbourne. Next week I’ll be teaching our <a href="http://www.idesign.net/idesign/DesktopDefault.aspx?tabindex=0&amp;tabid=20" target="_blank">WCF
Master Class</a> in Sydney 19-23 Oct, also through Readify.
</p>
        <p>
The timing worked out perfectly that I also get to be the guest speaker at a user
group in each city as well. On 13 October, I’ll be presenting a talk on <a href="http://www.microsoft.com/prism" target="_blank">Prism</a> at
the <a href="http://www.victoriadotnet.com.au/vic_index.aspx" target="_blank">Victoria
.NET User Group</a>. On Wed 21 October, I’ll be giving two sessions at the <a href="http://www.ssw.com.au/ssw/NETUG/Sydney.aspx" target="_blank">Sydney
.NET User’s Group</a> on <a href="http://www.microsoft.com/prism" target="_blank">Prism</a> and
WF 4.
</p>
        <p>
It’s always fun to give talks to user groups, but it is extra special fun to get to
give user group talks in other countries. Really looking forward to both, as well
as the classes. And spending two weeks in Australia doesn’t suck one bit either. :)
</p>
        <img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=501f1345-e8f2-42bd-a4d7-08e59e38bcc1" />
      </body>
      <title>Australia Tour</title>
      <guid isPermaLink="false">http://www.softinsight.com/bnoyes/PermaLink,guid,501f1345-e8f2-42bd-a4d7-08e59e38bcc1.aspx</guid>
      <link>http://www.softinsight.com/bnoyes/2009/10/11/AustraliaTour.aspx</link>
      <pubDate>Sun, 11 Oct 2009 05:02:10 GMT</pubDate>
      <description>&lt;p&gt;
I’m spending the next two weeks in Australia to teach some classes and speak at some
user groups. This week, 12-16 Oct, I am teaching our &lt;a href="http://www.idesign.net/idesign/DesktopDefault.aspx?tabindex=0&amp;amp;tabid=23" target="_blank"&gt;Architect
Master Class&lt;/a&gt; through our training partner &lt;a href="http://readify.net/" target="_blank"&gt;Readify&lt;/a&gt; in
Melbourne. Next week I’ll be teaching our &lt;a href="http://www.idesign.net/idesign/DesktopDefault.aspx?tabindex=0&amp;amp;tabid=20" target="_blank"&gt;WCF
Master Class&lt;/a&gt; in Sydney 19-23 Oct, also through Readify.
&lt;/p&gt;
&lt;p&gt;
The timing worked out perfectly that I also get to be the guest speaker at a user
group in each city as well. On 13 October, I’ll be presenting a talk on &lt;a href="http://www.microsoft.com/prism" target="_blank"&gt;Prism&lt;/a&gt; at
the &lt;a href="http://www.victoriadotnet.com.au/vic_index.aspx" target="_blank"&gt;Victoria
.NET User Group&lt;/a&gt;. On Wed 21 October, I’ll be giving two sessions at the &lt;a href="http://www.ssw.com.au/ssw/NETUG/Sydney.aspx" target="_blank"&gt;Sydney
.NET User’s Group&lt;/a&gt; on &lt;a href="http://www.microsoft.com/prism" target="_blank"&gt;Prism&lt;/a&gt; and
WF 4.
&lt;/p&gt;
&lt;p&gt;
It’s always fun to give talks to user groups, but it is extra special fun to get to
give user group talks in other countries. Really looking forward to both, as well
as the classes. And spending two weeks in Australia doesn’t suck one bit either. :)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=501f1345-e8f2-42bd-a4d7-08e59e38bcc1" /&gt;</description>
      <comments>http://www.softinsight.com/bnoyes/CommentView,guid,501f1345-e8f2-42bd-a4d7-08e59e38bcc1.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.softinsight.com/bnoyes/Trackback.aspx?guid=0fbf4727-24a5-4e43-bd9c-3e48c8c1278e</trackback:ping>
      <pingback:server>http://www.softinsight.com/bnoyes/pingback.aspx</pingback:server>
      <pingback:target>http://www.softinsight.com/bnoyes/PermaLink,guid,0fbf4727-24a5-4e43-bd9c-3e48c8c1278e.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.softinsight.com/bnoyes/CommentView,guid,0fbf4727-24a5-4e43-bd9c-3e48c8c1278e.aspx</wfw:comment>
      <wfw:commentRss>http://www.softinsight.com/bnoyes/SyndicationService.asmx/GetEntryCommentsRss?guid=0fbf4727-24a5-4e43-bd9c-3e48c8c1278e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I had some good follow on discussions from my <a href="http://www.softinsight.com/bnoyes/2009/09/05/SupportingGracefulShutdownAndSavingOnCloseFromAWPFPrismApp.aspx">recent
post on Graceful Shutdown</a> with <a href="http://neverindoubtnet.blogspot.com/">Ward
Bell</a> and <a href="http://codebetter.com/blogs/jeremy.miller/">Jeremy Miller</a> about
how “graceful” my shutdown example really was. They argued a point that I agreed was
a big weakness with the approach: sending information back to the shell about whether
to shutdown through a command parameter is not a very clean path of communication.
Also, my arguments about using a command vs a pub-sub event were difficult to defend.
Either one would work fine, but both suffer this same problem of obscure communication
paths.
</p>
        <p>
Jeremy also pointed out that the use of Prism CompositeCommands is always a little
dirty and hazardous for two reasons. First, they are typically used as globals – a
static singleton instance of the CompositeCommand that any control can source and
any other part of the app can hook up to through the CompositeCommand.RegisterCommand
method. And we all know that globals are evil. 
</p>
        <p>
The other problem with CompositeCommands is that it is too easy to have some chunk
of code register a child command with the RegisterCommand method and then forget that
now the CompositeCommand holds a reference chain back to the child command, the object
on which the child command is a member, and the object on which the child command
handler method exists. 
</p>
        <p>
In my simple example, there was the smell of a potential memory leak – an app that
lets you open multiple documents, each document gets its own view and view model,
and the view models are the command handlers for composite commands. Since those views
are being dynamically created (in this case in response to another composite command
for “New”), the registration is being done on the fly as their view models are initialized.
So this begs the question of when do they get unregistered so that you don’t leak
memory (in the form of residual command references into view models that are no longer
being used). Prism commands do not currently use weak references like the Prism events
do, although you could modify them to do so without too much difficulty.
</p>
        <p>
You can get the <a href="http://www.softinsight.com/downloads/Blog/GracefulShutdownSamplev2.zip">updated
code for this post here</a>.
</p>
        <p>
With the original sample code from my last post, it turned out this was not really
a problem because the sample provided no way to close a view once opened. But it was
just a sample focusing on the communication path for the Closing event after all.
But say it was a real app and you were going to allow the user to close a document.
I’ve modified the sample to allow closing a document through an X button on the tabs
that the documents get opened in.
</p>
        <p>
          <a href="http://www.softinsight.com/bnoyes/content/binary/WindowsLiveWriter/AvoidingMemoryLeakswithCompositeCommands_A8D5/10-5-2009%208-40-21%20AM_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="10-5-2009 8-40-21 AM" border="0" alt="10-5-2009 8-40-21 AM" src="http://www.softinsight.com/bnoyes/content/binary/WindowsLiveWriter/AvoidingMemoryLeakswithCompositeCommands_A8D5/10-5-2009%208-40-21%20AM_thumb.png" width="337" height="254" />
          </a>
        </p>
        <p>
I didn’t take the time to beautifully style it, so forgive me my artistic ineptitude.
But now that there is a mechanism to close the views, presumably the references to
the views and view models are released when their document is closed, but if we don’t
make sure we call UnregisterCommand in that process, we will have an effective memory
leak – the CompositeCommands for Shutdown and Save will be holding references to the
view models keeping them from being garbage collected. Each new document we open gets
a new view and ViewModel instance, registers it, and over time we would see the memory
of this app grow and grow.
</p>
        <p>
So the direct solution is to ensure through whatever means practical to call UnregisterCommand
before all refs to the ViewModel go away. Lets take a quick look at the code for this
sample to get that done.
</p>
        <p>
I added a data template to the shell where the TabControl is defined to add the X
buttons into the tab headers:
</p>
        <pre class="csharpcode">
          <span class="kwrd">&lt;</span>
          <span class="html">DataTemplate</span>
          <span class="attr">x:Key</span>
          <span class="kwrd">="ButtonTabItem"</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">DockPanel</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">Button</span>
          <span class="attr">DockPanel</span>.<span class="attr">Dock</span><span class="kwrd">="Right"</span><span class="attr">Command</span><span class="kwrd">="{Binding
Path=Content.DataContext.CloseCommand, RelativeSource={RelativeSource AncestorType=TabItem}}"</span><span class="kwrd">&gt;</span>X <span class="kwrd">&lt;/</span><span class="html">Button</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;</span><span class="html">TextBlock</span><span class="attr">Text</span><span class="kwrd">="{Binding
Path=Content.DataContext.DocumentTitle, RelativeSource={RelativeSource AncestorType=TabItem}}"</span><span class="attr">VerticalAlignment</span><span class="kwrd">="Center"</span><span class="kwrd">/&gt;</span><span class="kwrd">&lt;/</span><span class="html">DockPanel</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;/</span><span class="html">DataTemplate</span><span class="kwrd">&gt;</span></pre>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
        </p>
        <p>
 
</p>
        <p>
You can see the binding code is expecting a CloseCommand to be exposed from the ViewModel
which is the DataContext of the view, and the view is the Content of the TabItem.
The DocumentEditorView did not have to be modified at all, but the CloseCommand was
added to the ViewModel as a DelegateCommand, as well as a Closed event to notify the
controller:
</p>
        <pre class="csharpcode">
          <span class="kwrd">public</span> DocumentEditorViewModel()
{ SaveCommand = <span class="kwrd">new</span> DelegateCommand&lt;<span class="kwrd">object</span>&gt;(OnSave,
OnCanSave); SaveCommand.IsActive = <span class="kwrd">true</span>; Commands.SaveCommand.RegisterCommand(SaveCommand);
ShutdownCommand = <span class="kwrd">new</span> DelegateCommand&lt;CancelEventArgs&gt;(OnShutdown);
Commands.ShutdownCommand.RegisterCommand(ShutdownCommand); ... CloseCommand = <span class="kwrd">new</span> DelegateCommand&lt;<span class="kwrd">object</span>&gt;(OnClose);
} <span class="kwrd">public</span> DelegateCommand&lt;<span class="kwrd">object</span>&gt;
CloseCommand { get; set; } <span class="kwrd">public</span><span class="kwrd">event</span> Action&lt;DocumentEditorViewModel&gt;
Closed = <span class="kwrd">delegate</span> { }; <span class="kwrd">private</span><span class="kwrd">void</span> OnClose(<span class="kwrd">object</span> obj)
{ <span class="rem">// Prompt to save, save document, etc.</span> Commands.ShutdownCommand.UnregisterCommand(ShutdownCommand);
Commands.ShutdownCommand.UnregisterCommand(SaveCommand); Closed(<span class="kwrd">this</span>); <span class="rem">//
Notify controller through an event, could also use a Prism event if others might care...</span> }</pre>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
 
</p>
        <p>
In this case, since the command handling for closing can be collocated with the code
that did the registration, it is easy to make sure that we UnregisterCommand as part
of the closing process. The controller is the one that takes care of presenting the
views in this case, so the event is fired so the controller can choose to do what
is appropriate, which in this case is to just remove the view from the region. That
takes a bit of convoluted code to locate the view that corresponds to the ViewModel
since the two are loosely coupled.
</p>
        <pre class="csharpcode">
          <span class="kwrd">private</span>
          <span class="kwrd">void</span> OnViewClosed(DocumentEditorViewModel
vm) { vm.Closed -= OnViewClosed; IRegion region = m_RegionManager.Regions[Constants.DOCUMENTREGION];
DocumentEditorView viewToRemove = <span class="kwrd">null</span>; <span class="kwrd">foreach</span> (var
view <span class="kwrd">in</span> region.Views) { DocumentEditorView docView = view <span class="kwrd">as</span> DocumentEditorView; <span class="kwrd">if</span> (docView
== <span class="kwrd">null</span>) <span class="kwrd">continue</span>; <span class="kwrd">if</span> (docView.DataContext
== vm) { viewToRemove = docView; <span class="kwrd">break</span>; } } <span class="kwrd">if</span> (viewToRemove
!= <span class="kwrd">null</span>) region.Remove(viewToRemove); }</pre>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
 
</p>
        <p>
So for this simple example, it was not too terribly hard to make sure a memory leak
did not happen with the use of the CompositeCommand once I added the functionality
to close a view. However, what you can see emerging here is that the complexity is
growing disproportionate to the work that this little sample is really doing. With
a large app with many views/ViewModels, lots of commands and cross module communications,
etc. this could get out of control pretty quick, and it would be easy to miss a place
where you are not unregistering correctly.
</p>
        <p>
The net result of all this is that the use of CompositeCommand works, but is not completely
satisfying here, and especially not in a large complex  app. Modifying CompositeCommand
to use weak references would be one choice, or switching to Prism events for the communications
would be another choice. 
</p>
        <p>
Coupled with this challenge of potential memory leaks is the scenario of the previous
post – graceful shutdown communications – is a another responsibility relative to
view management that really cries out for some centralized management. Then you have
the view activation/deactivation that I will talk about in my next post that also
requires some common handling, and it turns out that what you really need is a pattern/abstraction
that Prism does not yet really provide – you need a screen conductor / director of
some sort that keeps track of what views are being presented, when they are activated/deactivated,
whether they can close, etc.
</p>
        <p>
Jeremy is <a href="http://codebetter.com/blogs/jeremy.miller/archive/2009/09/07/screen-activator-pattern.aspx">working
on a chapter for his upcoming book</a>  that will cover an approach to this problem.
I and others are trying to wrap our heads around the best way to tackle this problem.
Ward Bell has suggested a “Close Service” that is responsible for coordinating the
shutdown and he spiked an implementation of this that definitely felt cleaner than
doing the back-channel communications through command or event arguments. I’ll be
sure to blog more about this as my thoughts gel on it and if I can get a decent implementation
put together, or will link to whoever beats me to it publicly first.
</p>
        <p>
But before I get there, I do want to explain the IActiveAware mechanism of Prism,
since it was important in getting the application to work correctly as well and is
severely under-documented in the Prism docs. So that will be my next post, stay tuned…
</p>
        <p>
You can get the <a href="http://www.softinsight.com/downloads/Blog/GracefulShutdownSamplev2.zip">updated
code for this post here</a>.
</p>
        <img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=0fbf4727-24a5-4e43-bd9c-3e48c8c1278e" />
      </body>
      <title>Avoiding Memory Leaks with CompositeCommands</title>
      <guid isPermaLink="false">http://www.softinsight.com/bnoyes/PermaLink,guid,0fbf4727-24a5-4e43-bd9c-3e48c8c1278e.aspx</guid>
      <link>http://www.softinsight.com/bnoyes/2009/10/05/AvoidingMemoryLeaksWithCompositeCommands.aspx</link>
      <pubDate>Mon, 05 Oct 2009 13:22:17 GMT</pubDate>
      <description>&lt;p&gt;
I had some good follow on discussions from my &lt;a href="http://www.softinsight.com/bnoyes/2009/09/05/SupportingGracefulShutdownAndSavingOnCloseFromAWPFPrismApp.aspx"&gt;recent
post on Graceful Shutdown&lt;/a&gt; with &lt;a href="http://neverindoubtnet.blogspot.com/"&gt;Ward
Bell&lt;/a&gt; and &lt;a href="http://codebetter.com/blogs/jeremy.miller/"&gt;Jeremy Miller&lt;/a&gt; about
how “graceful” my shutdown example really was. They argued a point that I agreed was
a big weakness with the approach: sending information back to the shell about whether
to shutdown through a command parameter is not a very clean path of communication.
Also, my arguments about using a command vs a pub-sub event were difficult to defend.
Either one would work fine, but both suffer this same problem of obscure communication
paths.
&lt;/p&gt;
&lt;p&gt;
Jeremy also pointed out that the use of Prism CompositeCommands is always a little
dirty and hazardous for two reasons. First, they are typically used as globals – a
static singleton instance of the CompositeCommand that any control can source and
any other part of the app can hook up to through the CompositeCommand.RegisterCommand
method. And we all know that globals are evil. 
&lt;/p&gt;
&lt;p&gt;
The other problem with CompositeCommands is that it is too easy to have some chunk
of code register a child command with the RegisterCommand method and then forget that
now the CompositeCommand holds a reference chain back to the child command, the object
on which the child command is a member, and the object on which the child command
handler method exists. 
&lt;/p&gt;
&lt;p&gt;
In my simple example, there was the smell of a potential memory leak – an app that
lets you open multiple documents, each document gets its own view and view model,
and the view models are the command handlers for composite commands. Since those views
are being dynamically created (in this case in response to another composite command
for “New”), the registration is being done on the fly as their view models are initialized.
So this begs the question of when do they get unregistered so that you don’t leak
memory (in the form of residual command references into view models that are no longer
being used). Prism commands do not currently use weak references like the Prism events
do, although you could modify them to do so without too much difficulty.
&lt;/p&gt;
&lt;p&gt;
You can get the &lt;a href="http://www.softinsight.com/downloads/Blog/GracefulShutdownSamplev2.zip"&gt;updated
code for this post here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
With the original sample code from my last post, it turned out this was not really
a problem because the sample provided no way to close a view once opened. But it was
just a sample focusing on the communication path for the Closing event after all.
But say it was a real app and you were going to allow the user to close a document.
I’ve modified the sample to allow closing a document through an X button on the tabs
that the documents get opened in.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.softinsight.com/bnoyes/content/binary/WindowsLiveWriter/AvoidingMemoryLeakswithCompositeCommands_A8D5/10-5-2009%208-40-21%20AM_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="10-5-2009 8-40-21 AM" border="0" alt="10-5-2009 8-40-21 AM" src="http://www.softinsight.com/bnoyes/content/binary/WindowsLiveWriter/AvoidingMemoryLeakswithCompositeCommands_A8D5/10-5-2009%208-40-21%20AM_thumb.png" width="337" height="254" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
I didn’t take the time to beautifully style it, so forgive me my artistic ineptitude.
But now that there is a mechanism to close the views, presumably the references to
the views and view models are released when their document is closed, but if we don’t
make sure we call UnregisterCommand in that process, we will have an effective memory
leak – the CompositeCommands for Shutdown and Save will be holding references to the
view models keeping them from being garbage collected. Each new document we open gets
a new view and ViewModel instance, registers it, and over time we would see the memory
of this app grow and grow.
&lt;/p&gt;
&lt;p&gt;
So the direct solution is to ensure through whatever means practical to call UnregisterCommand
before all refs to the ViewModel go away. Lets take a quick look at the code for this
sample to get that done.
&lt;/p&gt;
&lt;p&gt;
I added a data template to the shell where the TabControl is defined to add the X
buttons into the tab headers:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DataTemplate&lt;/span&gt; &lt;span class="attr"&gt;x:Key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;ButtonTabItem&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DockPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Button&lt;/span&gt; &lt;span class="attr"&gt;DockPanel&lt;/span&gt;.&lt;span class="attr"&gt;Dock&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Right&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Command&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{Binding
Path=Content.DataContext.CloseCommand, RelativeSource={RelativeSource AncestorType=TabItem}}&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;X &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Button&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TextBlock&lt;/span&gt; &lt;span class="attr"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{Binding
Path=Content.DataContext.DocumentTitle, RelativeSource={RelativeSource AncestorType=TabItem}}&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;VerticalAlignment&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Center&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;DockPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;DataTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
You can see the binding code is expecting a CloseCommand to be exposed from the ViewModel
which is the DataContext of the view, and the view is the Content of the TabItem.
The DocumentEditorView did not have to be modified at all, but the CloseCommand was
added to the ViewModel as a DelegateCommand, as well as a Closed event to notify the
controller:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; DocumentEditorViewModel()
{ SaveCommand = &lt;span class="kwrd"&gt;new&lt;/span&gt; DelegateCommand&amp;lt;&lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt;(OnSave,
OnCanSave); SaveCommand.IsActive = &lt;span class="kwrd"&gt;true&lt;/span&gt;; Commands.SaveCommand.RegisterCommand(SaveCommand);
ShutdownCommand = &lt;span class="kwrd"&gt;new&lt;/span&gt; DelegateCommand&amp;lt;CancelEventArgs&amp;gt;(OnShutdown);
Commands.ShutdownCommand.RegisterCommand(ShutdownCommand); ... CloseCommand = &lt;span class="kwrd"&gt;new&lt;/span&gt; DelegateCommand&amp;lt;&lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt;(OnClose);
} &lt;span class="kwrd"&gt;public&lt;/span&gt; DelegateCommand&amp;lt;&lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt;
CloseCommand { get; set; } &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;event&lt;/span&gt; Action&amp;lt;DocumentEditorViewModel&amp;gt;
Closed = &lt;span class="kwrd"&gt;delegate&lt;/span&gt; { }; &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnClose(&lt;span class="kwrd"&gt;object&lt;/span&gt; obj)
{ &lt;span class="rem"&gt;// Prompt to save, save document, etc.&lt;/span&gt; Commands.ShutdownCommand.UnregisterCommand(ShutdownCommand);
Commands.ShutdownCommand.UnregisterCommand(SaveCommand); Closed(&lt;span class="kwrd"&gt;this&lt;/span&gt;); &lt;span class="rem"&gt;//
Notify controller through an event, could also use a Prism event if others might care...&lt;/span&gt; }&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
In this case, since the command handling for closing can be collocated with the code
that did the registration, it is easy to make sure that we UnregisterCommand as part
of the closing process. The controller is the one that takes care of presenting the
views in this case, so the event is fired so the controller can choose to do what
is appropriate, which in this case is to just remove the view from the region. That
takes a bit of convoluted code to locate the view that corresponds to the ViewModel
since the two are loosely coupled.
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnViewClosed(DocumentEditorViewModel
vm) { vm.Closed -= OnViewClosed; IRegion region = m_RegionManager.Regions[Constants.DOCUMENTREGION];
DocumentEditorView viewToRemove = &lt;span class="kwrd"&gt;null&lt;/span&gt;; &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var
view &lt;span class="kwrd"&gt;in&lt;/span&gt; region.Views) { DocumentEditorView docView = view &lt;span class="kwrd"&gt;as&lt;/span&gt; DocumentEditorView; &lt;span class="kwrd"&gt;if&lt;/span&gt; (docView
== &lt;span class="kwrd"&gt;null&lt;/span&gt;) &lt;span class="kwrd"&gt;continue&lt;/span&gt;; &lt;span class="kwrd"&gt;if&lt;/span&gt; (docView.DataContext
== vm) { viewToRemove = docView; &lt;span class="kwrd"&gt;break&lt;/span&gt;; } } &lt;span class="kwrd"&gt;if&lt;/span&gt; (viewToRemove
!= &lt;span class="kwrd"&gt;null&lt;/span&gt;) region.Remove(viewToRemove); }&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
So for this simple example, it was not too terribly hard to make sure a memory leak
did not happen with the use of the CompositeCommand once I added the functionality
to close a view. However, what you can see emerging here is that the complexity is
growing disproportionate to the work that this little sample is really doing. With
a large app with many views/ViewModels, lots of commands and cross module communications,
etc. this could get out of control pretty quick, and it would be easy to miss a place
where you are not unregistering correctly.
&lt;/p&gt;
&lt;p&gt;
The net result of all this is that the use of CompositeCommand works, but is not completely
satisfying here, and especially not in a large complex&amp;#160; app. Modifying CompositeCommand
to use weak references would be one choice, or switching to Prism events for the communications
would be another choice. 
&lt;/p&gt;
&lt;p&gt;
Coupled with this challenge of potential memory leaks is the scenario of the previous
post – graceful shutdown communications – is a another responsibility relative to
view management that really cries out for some centralized management. Then you have
the view activation/deactivation that I will talk about in my next post that also
requires some common handling, and it turns out that what you really need is a pattern/abstraction
that Prism does not yet really provide – you need a screen conductor / director of
some sort that keeps track of what views are being presented, when they are activated/deactivated,
whether they can close, etc.
&lt;/p&gt;
&lt;p&gt;
Jeremy is &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2009/09/07/screen-activator-pattern.aspx"&gt;working
on a chapter for his upcoming book&lt;/a&gt;&amp;#160; that will cover an approach to this problem.
I and others are trying to wrap our heads around the best way to tackle this problem.
Ward Bell has suggested a “Close Service” that is responsible for coordinating the
shutdown and he spiked an implementation of this that definitely felt cleaner than
doing the back-channel communications through command or event arguments. I’ll be
sure to blog more about this as my thoughts gel on it and if I can get a decent implementation
put together, or will link to whoever beats me to it publicly first.
&lt;/p&gt;
&lt;p&gt;
But before I get there, I do want to explain the IActiveAware mechanism of Prism,
since it was important in getting the application to work correctly as well and is
severely under-documented in the Prism docs. So that will be my next post, stay tuned…
&lt;/p&gt;
&lt;p&gt;
You can get the &lt;a href="http://www.softinsight.com/downloads/Blog/GracefulShutdownSamplev2.zip"&gt;updated
code for this post here&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.softinsight.com/bnoyes/aggbug.ashx?id=0fbf4727-24a5-4e43-bd9c-3e48c8c1278e" /&gt;</description>
      <comments>http://www.softinsight.com/bnoyes/CommentView,guid,0fbf4727-24a5-4e43-bd9c-3e48c8c1278e.aspx</comments>
    </item>
  </channel>
</rss>