<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><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>Jonas Follesø's World of Software</title>
    <link>http://jonas.follesoe.no/</link>
    <description>Jonas Follesø's World of Software</description>
    <image>
      <url>http://jonas.follesoe.no/content/binary/roskilde.jpg</url>
      <title>Jonas Follesø's World of Software</title>
      <link>http://jonas.follesoe.no/</link>
    </image>
    <language>en-us</language>
    <copyright>Jonas Follesø</copyright>
    <lastBuildDate>Sat, 06 Mar 2010 23:22:54 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>jonas@follesoe.no</managingEditor>
    <webMaster>jonas@follesoe.no</webMaster>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/follesoe" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="follesoe" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
      <trackback:ping>http://jonas.follesoe.no/Trackback.aspx?guid=c5494709-8c5f-4aba-abd6-53aa86ab56ba</trackback:ping>
      <pingback:server>http://jonas.follesoe.no/pingback.aspx</pingback:server>
      <pingback:target>http://jonas.follesoe.no/PermaLink,guid,c5494709-8c5f-4aba-abd6-53aa86ab56ba.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://jonas.follesoe.no/CommentView,guid,c5494709-8c5f-4aba-abd6-53aa86ab56ba.aspx</wfw:comment>
      <wfw:commentRss>http://jonas.follesoe.no/SyndicationService.asmx/GetEntryCommentsRss?guid=c5494709-8c5f-4aba-abd6-53aa86ab56ba</wfw:commentRss>
      <slash:comments>1</slash:comments>
      
      <title>MVVM presentation from NDC2009 on Vimeo</title>
      <guid isPermaLink="false">http://jonas.follesoe.no/PermaLink,guid,c5494709-8c5f-4aba-abd6-53aa86ab56ba.aspx</guid>
      <link>http://jonas.follesoe.no/MVVMPresentationFromNDC2009OnVimeo.aspx</link>
      <pubDate>Sat, 06 Mar 2010 23:22:54 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
Last year I gave a presentation on the MVVM design pattern at the Norwegian Developer&#xD;
Conference. Most of the presentations from NDC2009 was recorded and made available&#xD;
online, including mine. However, the user experience of the &lt;a href="http://arkiv.ndc2009.no/agenda.aspx?cat=1071&amp;amp;id=1813"&gt;video&#xD;
content on the NDC site&lt;/a&gt; isn’t the best. Playing a video requires multiple clicks,&#xD;
and the videos are only available in WMV format. &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The feedback I’ve gotten on the presentation is so good that I decided to make it&#xD;
a bit more discoverable by &lt;a href="http://vimeo.com/9765330"&gt;uploading it to Vimeo&lt;/a&gt;.&#xD;
In addition to the MVVM presentation I have also uploaded &lt;a href="http://vimeo.com/9964528"&gt;my&#xD;
lightning talk from Smidig 2009&lt;/a&gt; (in Norwegian) as well as my &lt;a href="http://vimeo.com/9967222"&gt;Silverlight&#xD;
talk from TechEd New Zealand 2008&lt;/a&gt;. &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
If you want to watch all the content from NDC2009 you can download it &lt;a href="http://blogs.msdn.com/grothaug/pages/downloadable-ndc2009-videos.aspx"&gt;nicely&#xD;
packaged as one big torrent file&lt;/a&gt;. Oh, and I haven’t made an announcement on the&#xD;
blog yet, but I will be &lt;a href="http://www.ndc2010.no/index.aspx"&gt;speaking at this&#xD;
year’s NDC&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;object width="670" height="536"&gt;&#xD;
          &lt;param name="allowfullscreen" value="true"&gt;&lt;/param&gt;&#xD;
          &lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&#xD;
          &lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=9765330&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=ff0179&amp;amp;fullscreen=1"&gt;&lt;/param&gt;&#xD;
          &lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=9765330&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=ff0179&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="670" height="536"&gt;&#xD;
          &lt;/embed&gt;&#xD;
        &lt;/object&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://vimeo.com/9765330"&gt;MVVM Design Pattern NDC2009&lt;/a&gt; from &lt;a href="http://vimeo.com/follesoe"&gt;Jonas&#xD;
Follesø&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;div style="width: 425px" id="__ss_1664018"&gt;&#xD;
          &lt;strong style="margin: 12px 0px 4px; display: block"&gt;&#xD;
            &lt;a title="MVVM Design Pattern NDC2009" href="http://www.slideshare.net/follesoe/mvvm-design-pattern-ndc2009"&gt;MVVM&#xD;
Design Pattern NDC2009&lt;/a&gt;&#xD;
          &lt;/strong&gt;&#xD;
          &lt;object width="425" height="355"&gt;&#xD;
            &lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=mvvmpresentationndc2009-090630160910-phpapp02&amp;amp;stripped_title=mvvm-design-pattern-ndc2009"&gt;&lt;/param&gt;&#xD;
            &lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&#xD;
            &lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt;&#xD;
            &lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=mvvmpresentationndc2009-090630160910-phpapp02&amp;amp;stripped_title=mvvm-design-pattern-ndc2009" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&#xD;
            &lt;/embed&gt;&#xD;
          &lt;/object&gt;&#xD;
          &lt;div style="padding-bottom: 12px; padding-left: 0px; padding-right: 0px; padding-top: 5px"&gt;View&#xD;
more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/follesoe"&gt;follesoe&lt;/a&gt;.&#xD;
&lt;/div&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;img width="0" height="0" src="http://jonas.follesoe.no/aggbug.ashx?id=c5494709-8c5f-4aba-abd6-53aa86ab56ba"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=a4dmsmGVydc:tuIhVu1E9fk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=a4dmsmGVydc:tuIhVu1E9fk:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=a4dmsmGVydc:tuIhVu1E9fk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?i=a4dmsmGVydc:tuIhVu1E9fk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=a4dmsmGVydc:tuIhVu1E9fk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/follesoe/~4/a4dmsmGVydc" height="1" width="1"/&gt;</description>
      <comments>http://jonas.follesoe.no/CommentView,guid,c5494709-8c5f-4aba-abd6-53aa86ab56ba.aspx</comments>
      <category>Conferences</category>
      <category>MVVM</category>
      <category>Presentation</category>
      <category>Silverlight</category>
    </item>
    <item>
      <trackback:ping>http://jonas.follesoe.no/Trackback.aspx?guid=eb7ef405-542f-471e-acd3-bb305b0f67c7</trackback:ping>
      <pingback:server>http://jonas.follesoe.no/pingback.aspx</pingback:server>
      <pingback:target>http://jonas.follesoe.no/PermaLink,guid,eb7ef405-542f-471e-acd3-bb305b0f67c7.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://jonas.follesoe.no/CommentView,guid,eb7ef405-542f-471e-acd3-bb305b0f67c7.aspx</wfw:comment>
      <wfw:commentRss>http://jonas.follesoe.no/SyndicationService.asmx/GetEntryCommentsRss?guid=eb7ef405-542f-471e-acd3-bb305b0f67c7</wfw:commentRss>
      <slash:comments>6</slash:comments>
      
      <title>Automatic INPC using dynamic proxy and Ninject</title>
      <guid isPermaLink="false">http://jonas.follesoe.no/PermaLink,guid,eb7ef405-542f-471e-acd3-bb305b0f67c7.aspx</guid>
      <link>http://jonas.follesoe.no/AutomaticINPCUsingDynamicProxyAndNinject.aspx</link>
      <pubDate>Sun, 17 Jan 2010 21:43:42 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
There has been lots of talk in the Silverlight community about what is the best way&#xD;
to implement the INotifyPropertyChanged interface. During Christmas I blogged about &lt;a href="http://jonas.follesoe.no/AutomaticINotifyPropertyChangedUsingDynamicProxy.aspx"&gt;how&#xD;
you can use dynamic proxies to get INPC implemented automatically&lt;/a&gt;. Since then&#xD;
both &lt;a href="http://www.ingebrigtsen.info/post/2010/01/10/INotifyPropertyChanged-Automagically-implemented.aspx"&gt;Einar&#xD;
Ingebrigtsen&lt;/a&gt; and &lt;a href="http://justinangel.net/"&gt;Justin Angel&lt;/a&gt; have blogged&#xD;
about an interesting approach to INPC using MSIL weaving. I really recommend checking&#xD;
out Justin’s post, as he covers some of the pros and cons of different INPC implementations,&#xD;
as well as purposing &lt;a href="http://justinangel.net/#BlogPost=AutomagicallyImplementingINotifyPropertyChanged"&gt;an&#xD;
elegant solution using post-build MSIL weaving&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
One of the things Justin mentions as a drawback of the dynamic proxy approach is that&#xD;
you cannot simply new up your ViewModel directly and get change notification automatically.&#xD;
You have to explicitly create the ViewModel instance through a proxy creator. Einar&#xD;
also mentioned that he had a hard time finding a way to integrate the proxy creator&#xD;
with an IoC container.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
When I write code I’m always careful about where I instantiate my objects, and lately&#xD;
all projects I’ve worked on have used some sort of IoC container. Having an IoC container&#xD;
gives you a single place in your code base to create- and register objects. If the&#xD;
dynamic proxy implementation of automatic INPC is going to be useful it has to be&#xD;
as simple requesting a ViewModel instance from the IoC container. In this blog post&#xD;
I’m going to show how you can combine automatic INPC using dynamic proxy with the&#xD;
Ninject IoC container.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
If you have read my blog you may have noticed &lt;a href="http://jonas.follesoe.no/YouCardRevisitedImplementingDependencyInjectionInSilverlight.aspx"&gt;I&#xD;
got a soft spot for Ninject&lt;/a&gt;. I mean, who cannot love a framework whose name, graphic&#xD;
profile and code examples are all about Ninjas? When I first set out to integrate&#xD;
my automatic INPC interceptor with &lt;a href="http://ninject.org/"&gt;Ninject&lt;/a&gt; I wasn’t&#xD;
quite sure where to start. Ninject 1.0 had AOP concepts built in, but in 2.0 (which&#xD;
are under development) this has been moved out of the core and into a separate interception&#xD;
extension module. This is part of the new modular design of Ninject 2.0. Features&#xD;
you may not need all the time are moved out to separate extensions, leaving the core&#xD;
really small and simple (~90kb).&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ninject-ninja" border="0" alt="ninject-ninja" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/AutomaticINPCusingdynamicproxyandNinject_13E0B/ninject-ninja_3.jpg" width="612" height="346"&gt;&lt;/img&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
My first plan was to use the Ninject interception extension. The extension uses the&#xD;
LinFu framework for dynamic proxies, and I wasn’t sure how to get my Castle Dynamic&#xD;
Proxy based implementation to work directly. I later got contacted by &lt;a href="http://www.twitter.com/innovatian"&gt;Ian&#xD;
Davis&lt;/a&gt;, the owner of the interception-extension project. He asked if I needed some&#xD;
help getting automatic INPC working with Ninject. After some back-and-forth on Twitter&#xD;
Ian had an implementation of automatic INPC added to the &lt;a href="http://github.com/idavis/ninject.extensions.interception"&gt;Ninject.Extension.Interception&#xD;
project&lt;/a&gt;. The code is &lt;a href="http://github.com/idavis/ninject.extensions.interception/commit/b991f89ca687fe0265d9e34d2ba6f626b06b6a5d"&gt;commited&#xD;
to the trunk&lt;/a&gt;, and is available on &lt;a href="http://github.com/idavis/ninject.extensions.interception"&gt;github&lt;/a&gt; if&#xD;
you want to check it out. Ian’s implementation is probably worth a blog post on its&#xD;
own.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
A comment from &lt;a href="http://miguelmadero.blogspot.com/"&gt;Miguel Madero&lt;/a&gt; pointed&#xD;
me in the right direction to get my interceptor working with Ninject. Miguel had integrated&#xD;
it himself by implementing the interceptor as a Ninject Provider. Ninject lets you&#xD;
register types against providers which let you write code that creates the instance&#xD;
when the type is requested from the container. The interface is really simple, having&#xD;
one Create-method. In this method you have to create the instance being requested.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The implementation for the automatic INPC provider is fairly simply. It finds the&#xD;
largest constructor of the ViewModel being requested, creates instances of all constructor&#xD;
parameters, before calling the dynamic proxy creator I implemented in my &lt;a href="http://jonas.follesoe.no/AutomaticChangeNotificationForDependentProperties.aspx"&gt;previous&#xD;
two&lt;/a&gt;&lt;a href="http://jonas.follesoe.no/AutomaticINotifyPropertyChangedUsingDynamicProxy.aspx"&gt;blog&#xD;
posts&lt;/a&gt;. &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ProviderCode" border="0" alt="ProviderCode" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/AutomaticINPCusingdynamicproxyandNinject_13E0B/ProviderCode_3.png" width="670" height="555"&gt;&lt;/img&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
In Ninject all configuration is done through code using an internal DSL. You configure&#xD;
the container by creating module classes specifying the bindings of the different&#xD;
types you want to be able to create. In this example I have a simple logging service&#xD;
(to demonstrate constructor injection combined with automatic INPC) as well as a simple&#xD;
ViewModel. The ViewModel is bound to the provider, which will call the proxy creator&#xD;
when the ViewModel is requested.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ConfigurationExample" border="0" alt="ConfigurationExample" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/AutomaticINPCusingdynamicproxyandNinject_13E0B/ConfigurationExample_3.png" width="670" height="240"&gt;&lt;/img&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
This unit tests shows how to request an instance of the ViewModel from the container.&#xD;
When the Name-property is set the ViewModel will log the action to the fake logger&#xD;
which was injected into the ViewModel constructor.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ExampleUnitTestOfViewModelFromKernel" border="0" alt="ExampleUnitTestOfViewModelFromKernel" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/AutomaticINPCusingdynamicproxyandNinject_13E0B/ExampleUnitTestOfViewModelFromKernel_3.png" width="670" height="193"&gt;&lt;/img&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Having to register every single ViewModel against the provider is tedious and repetitive.&#xD;
Miguel Madero also suggested that you can override the GetBinding method of the Ninject&#xD;
StandardKernel and use convention over configuration. By overriding the GetBinding&#xD;
method we can check if the type being requested is a ViewModel, and if it is we can&#xD;
create a binding on the fly tying the ViewModel type against the automatic INPC provider.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The implementation of the AutoNotifyKernel is really simple. It checks if the name&#xD;
of the type being requested contains “ViewModel” and implements the IAutoNotifyPropertyChanged&#xD;
interface. If it does we create a binding for the type.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="AutoNotifyKernel" border="0" alt="AutoNotifyKernel" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/AutomaticINPCusingdynamicproxyandNinject_13E0B/AutoNotifyKernel_3.png" width="670" height="398"&gt;&lt;/img&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Having a convention based approach in place we do not have to manually register every&#xD;
single ViewModel.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Some of this code might seem complicated, but I really wanted to cover the details&#xD;
of how to integrate it with Ninject, as similar approaches probably work for other&#xD;
containers. Once you got a framework for automatic INPC in place the usage becomes&#xD;
really simple. In the example application for automatic INPC the code needed to implement&#xD;
the ViewModel, configure the container and tie the ViewModel to the View looks something&#xD;
like this:&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="FullExample" border="0" alt="FullExample" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/AutomaticINPCusingdynamicproxyandNinject_13E0B/FullExample_3.png" width="670" height="844"&gt;&lt;/img&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
It’s funny how such a simple interface can trigger so many different implementations.&#xD;
I hope you found my blog post on combining a dynamic proxy approach with an IoC container&#xD;
useful. It will be interesting to see which approach emerges as the most used, and&#xD;
which frameworks that will provide implementations of the different techniques.&#xD;
&lt;/p&gt;&#xD;
        &lt;iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 98px; padding-right: 0px; height: 115px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-1a08c11c407c0d8e.skydrive.live.com/embedicon.aspx/Code%20samples/AutoINPC.zip" frameborder="0" marginwidth="0" scrolling="no"&gt;&#xD;
        &lt;/iframe&gt;&#xD;
        &lt;img width="0" height="0" src="http://jonas.follesoe.no/aggbug.ashx?id=eb7ef405-542f-471e-acd3-bb305b0f67c7"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=1cfUKPhejL4:66MO6irJ56s:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=1cfUKPhejL4:66MO6irJ56s:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=1cfUKPhejL4:66MO6irJ56s:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?i=1cfUKPhejL4:66MO6irJ56s:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=1cfUKPhejL4:66MO6irJ56s:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/follesoe/~4/1cfUKPhejL4" height="1" width="1"/&gt;</description>
      <comments>http://jonas.follesoe.no/CommentView,guid,eb7ef405-542f-471e-acd3-bb305b0f67c7.aspx</comments>
      <category>Design</category>
      <category>MVVM</category>
      <category>Patterns</category>
      <category>Silverlight</category>
    </item>
    <item>
      <trackback:ping>http://jonas.follesoe.no/Trackback.aspx?guid=a2c1f336-dfc8-4376-9dfe-522804385c1c</trackback:ping>
      <pingback:server>http://jonas.follesoe.no/pingback.aspx</pingback:server>
      <pingback:target>http://jonas.follesoe.no/PermaLink,guid,a2c1f336-dfc8-4376-9dfe-522804385c1c.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://jonas.follesoe.no/CommentView,guid,a2c1f336-dfc8-4376-9dfe-522804385c1c.aspx</wfw:comment>
      <wfw:commentRss>http://jonas.follesoe.no/SyndicationService.asmx/GetEntryCommentsRss?guid=a2c1f336-dfc8-4376-9dfe-522804385c1c</wfw:commentRss>
      <slash:comments>9</slash:comments>
      
      <title>Automatic change notification for dependent properties</title>
      <guid isPermaLink="false">http://jonas.follesoe.no/PermaLink,guid,a2c1f336-dfc8-4376-9dfe-522804385c1c.aspx</guid>
      <link>http://jonas.follesoe.no/AutomaticChangeNotificationForDependentProperties.aspx</link>
      <pubDate>Thu, 24 Dec 2009 03:12:03 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
Yesterday I published a post showing &lt;a href="http://jonas.follesoe.no/AutomaticINotifyPropertyChangedUsingDynamicProxy.aspx"&gt;how&#xD;
we can use AOP and Castle Dynamic Proxy to get automatic change notification for ViewModels&lt;/a&gt; by&#xD;
intercepting property setters. One of the comments I got was from &lt;a href="http://kozmic.pl/Default.aspx"&gt;Krzysztof&#xD;
Koźmic&lt;/a&gt; who suggested that I should &lt;a href="http://kozmic.pl/archive/0001/01/01/castle-dynamic-proxy-tutorial-part-iii-selecting-which-methods-to.aspx"&gt;use&#xD;
ProxyGenerationHook to narrow down the scope of the proxy&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
By implementing the IProxyGenerationHook we get to choose which methods to intercept.&#xD;
In my original implementation this logic was handled by the interceptor itself. The&#xD;
interceptor would check that the method being intercepted was indeed a property setter,&#xD;
that it was not of type ICommand, and that it was not marked for exclusion. By implementing&#xD;
a ProxyGenerationHook I could move all this code into a separate class, making my&#xD;
interceptor much cleaner. The ShouldInterceptMethod implementation of the ProxyGenerationHook&#xD;
now looks like this:&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ProxyGenerationHookCode" border="0" alt="ProxyGenerationHookCode" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/Automaticchangenotificationfordependentp_3A8A/ProxyGenerationHookCode_3.png" width="670" height="281"&gt;&lt;/img&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
I also got a good question from &lt;a href="http://twitter.com/aknutsen"&gt;Anders Knutsen&lt;/a&gt; asking&#xD;
how to handle change notification for properties depending on another property. A&#xD;
typical scenario for a ViewModel might be to have a ZipCode-property with both setter&#xD;
and getter, and City and State properties with only getters. When you set the ZipCode&#xD;
you raise change notification for ZipCode, City and State. In the City- and State-getter&#xD;
you look up the values based on the ZipCode. This means that you must be able to raise&#xD;
multiple change notifications in a single setter.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
I solved this by adding a new NotifyChangesFor-attribute that you can decorate properties&#xD;
with to trigger change notification for additional dependent properties.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="NotifyChangeForAttributeCode" border="0" alt="NotifyChangeForAttributeCode" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/Automaticchangenotificationfordependentp_3A8A/NotifyChangeForAttributeCode_3.png" width="670" height="121"&gt;&lt;/img&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
I have also updated the tests to document this behavior.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="NotifiyChangesForTestCode" border="0" alt="NotifiyChangesForTestCode" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/Automaticchangenotificationfordependentp_3A8A/NotifiyChangesForTestCode_3.png" width="670" height="237"&gt;&lt;/img&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The sample code has been updated with the new ProxyGenerationHook and the new NotifyChangesFor-attribute.&#xD;
&lt;/p&gt;&#xD;
        &lt;iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 98px; padding-right: 0px; height: 115px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-1a08c11c407c0d8e.skydrive.live.com/embedicon.aspx/Code%20samples/AutoINPC.zip" frameborder="0" marginwidth="0" scrolling="no"&gt;&#xD;
        &lt;/iframe&gt;&#xD;
        &lt;img width="0" height="0" src="http://jonas.follesoe.no/aggbug.ashx?id=a2c1f336-dfc8-4376-9dfe-522804385c1c"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=KQlwW2hGwsk:M49abYFlxRU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=KQlwW2hGwsk:M49abYFlxRU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=KQlwW2hGwsk:M49abYFlxRU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?i=KQlwW2hGwsk:M49abYFlxRU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=KQlwW2hGwsk:M49abYFlxRU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/follesoe/~4/KQlwW2hGwsk" height="1" width="1"/&gt;</description>
      <comments>http://jonas.follesoe.no/CommentView,guid,a2c1f336-dfc8-4376-9dfe-522804385c1c.aspx</comments>
      <category>MVVM</category>
      <category>Patterns</category>
      <category>Silverlight</category>
    </item>
    <item>
      <trackback:ping>http://jonas.follesoe.no/Trackback.aspx?guid=b82d81db-a34d-4644-850e-811f369d5489</trackback:ping>
      <pingback:server>http://jonas.follesoe.no/pingback.aspx</pingback:server>
      <pingback:target>http://jonas.follesoe.no/PermaLink,guid,b82d81db-a34d-4644-850e-811f369d5489.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://jonas.follesoe.no/CommentView,guid,b82d81db-a34d-4644-850e-811f369d5489.aspx</wfw:comment>
      <wfw:commentRss>http://jonas.follesoe.no/SyndicationService.asmx/GetEntryCommentsRss?guid=b82d81db-a34d-4644-850e-811f369d5489</wfw:commentRss>
      <slash:comments>11</slash:comments>
      
      <title>Automatic INotifyPropertyChanged using Dynamic Proxy</title>
      <guid isPermaLink="false">http://jonas.follesoe.no/PermaLink,guid,b82d81db-a34d-4644-850e-811f369d5489.aspx</guid>
      <link>http://jonas.follesoe.no/AutomaticINotifyPropertyChangedUsingDynamicProxy.aspx</link>
      <pubDate>Wed, 23 Dec 2009 02:14:46 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
As a WPF or Silverlight developer chances are you have implemented the INotifyPropertyChanged-interface&#xD;
more than once. The interface is simple enough, consisting of a single PropertyChanged-event.&#xD;
The data binding infrastructure in WPF and Silverlight will look for this interface&#xD;
and subscribe to the PropertyChanged-event. As a developer you have to write code&#xD;
in your property setters to raise the event whenever some property is changed. This&#xD;
is boring and repetitive code to write, that often contains magic strings (property&#xD;
names) and can really clutter your ViewModels. Finding an elegant implementation of&#xD;
the INotifyPropertyChanged-interface has become one of the holy-grails of WPF and&#xD;
Silverlight developers.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
An idea I had some time back where to use &lt;a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming"&gt;AOP&lt;/a&gt;-techniques&#xD;
and &lt;a href="http://www.castleproject.org/dynamicproxy/index.html"&gt;dynamic proxies&lt;/a&gt; to&#xD;
get INotifyPropertyChanged implemented automatically. With the r&lt;a href="http://kozmic.pl/archive/2009/12/04/castle-dynamic-proxy-2.2-beta-in-the-wild.aspx"&gt;ecent&#xD;
beta release of Castle Dynamic Proxy 2.2 with official support for Silverlight&lt;/a&gt;,&#xD;
combined with Christmas holiday, I figured this would be a good time to take a stab&#xD;
at this problem.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
After doing some research I found a couple implementations of INPC using AOP. In August&#xD;
2008 &lt;a href="https://mvp.support.microsoft.com/profile/ricci"&gt;Gian Mari Ricci&lt;/a&gt; published&#xD;
two blog posts about automatic implementation of INPC. The &lt;a href="http://www.codewrecks.com/blog/index.php/2008/08/04/implement-inotifypropertychanged-with-dynamic-code-generation/"&gt;first&#xD;
one he used Reflection.Emit and dynamic code generation&lt;/a&gt;, the second was a much &lt;a href="http://www.codewrecks.com/blog/index.php/2008/08/04/implement-inotifypropertychanged-with-castledynamicproxy/"&gt;simpler&#xD;
implementation using Castle Dynamic Proxy&lt;/a&gt;. &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
In June &lt;a href="http://www.lostechies.com/blogs/rhouston/default.aspx"&gt;Ray Houston&lt;/a&gt; published&#xD;
an &lt;a href="http://www.lostechies.com/blogs/rhouston/archive/2009/06/02/fluent-silverlight-auto-wiring-inotifypropertychanged.aspx"&gt;interesting&#xD;
post on how they had implemented auto wiring of INPC&lt;/a&gt; as part of the &lt;a href="http://code.google.com/p/fluent-silverlight/"&gt;Fluent&#xD;
Silverlight framework&lt;/a&gt;. Fluent Silverlight is an open source framework by Ray Houston&#xD;
and &lt;a href="http://www.lostechies.com/blogs/gabrielschenker/default.aspx"&gt;Gabriel&#xD;
Schenker&lt;/a&gt; that provides a fluent interface for configuring data binding in a strongly&#xD;
typed manner using C#. Their implementation of automatic wiring of INPC is based on&#xD;
Castle Dynamic Proxy, and is really simple and elegant. Instead of trying to reinvent&#xD;
the wheel I decided to re-implement the automatic INPC parts from Fluent Silverlight,&#xD;
and walk you through the code in this blog post. I do not want to take credit for&#xD;
Ray and Gabriel’s work, and must emphasize that this should be considered a walkthrough&#xD;
of their implementation.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The first part of the implementation is a new IAutoNotifyPropertyChanged interface&#xD;
that extends the INotifyPropertyChanged interface with one new method. This interface&#xD;
will be implemented for any ViewModel where we want automatic change notification.&#xD;
The interface serves as both a marker interface for the interceptor, as well as providing&#xD;
a method that the interceptor can call to raise the PropertyChanged-event.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="IAutoNotifyPropertyChanged Code Example (code download attached)" border="0" alt="IAutoNotifyPropertyChanged Code Example (code download attached)" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/AutomaticINotifyPropertyChangedusingDyna_2906/IAutoNotifyPropertyChangedCode_3.png" width="670" height="134"&gt;&lt;/img&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
To create a new ViewModel we simply implement the interface, and make any property&#xD;
we want change notification for as virtual. The properties need to be virtual so that&#xD;
the generated proxy class can override the property setter method and call the interceptor.&#xD;
The implementation of the interface can off course be moved down to a base class,&#xD;
but I have included it in this sample to make it clear what is required by the ViewModel&#xD;
for automatic change notification.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="PersonViewModelCode" border="0" alt="PersonViewModelCode" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/AutomaticINotifyPropertyChangedusingDyna_2906/PersonViewModelCode_3.png" width="670" height="309"&gt;&lt;/img&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
With a ViewModel implementing the IAutoNotifyPropertyChanged-interface in place we&#xD;
can now write an interceptor that will add change notification for the properties&#xD;
on the ViewModel. Interceptors are a concept from AOP that enables us to intercept&#xD;
method calls and add new behavior dynamically. This is helpful as we can move cross-cutting&#xD;
concerns out of the business logic. Typical use cases for AOP often include authentication,&#xD;
logging, exception handling and other technical concerns. By having these concerns&#xD;
implemented outside our class we can keep our business logic nice and clean. In our&#xD;
case we are going to apply some of these techniques to keep the ViewModel free from&#xD;
change notification code cluttering the class.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The interceptor is defined as a generic class that intercepts classes implementing&#xD;
the IAutoNotifyPropertyChanged-interface. The interceptor implements IInterceptor-interface&#xD;
which defines a method that will be called for every method invocation, providing&#xD;
us a hook to add addition behavior to the method call. Our interceptor will start&#xD;
by letting the original method call (the property setter) run before checking if we&#xD;
should raise change notification. If the property being set isn’t marked for exclusion&#xD;
we call the OnPropertyChanged method on the IAutoNotifyPropertyChanged-interface,&#xD;
passing in the property name as the parameter.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="InterceptorCode" border="0" alt="InterceptorCode" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/AutomaticINotifyPropertyChangedusingDyna_2906/InterceptorCode_3.png" width="670" height="365"&gt;&lt;/img&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The code to determine if we should raise change notification starts by checking if&#xD;
the method being invoked is in fact a property setter. This is done by checking the&#xD;
IsSpecialName-property on the &lt;a href="http://msdn.microsoft.com/en-us/library/system.reflection.methodinfo.aspx"&gt;MethodInfo&lt;/a&gt; object,&#xD;
as well as checking that the name of the method starts with “set_“. The second step&#xD;
is to check if the property is marked with a DoNotNotifyChanges-attribute. This is&#xD;
a marker attribute that can be applied on properties to prevent automatic change notification.&#xD;
The third step is to check if the property being set is of type ICommand. A common&#xD;
pattern when creating ViewModels is to expose operations as Commands hanging of the&#xD;
ViewModel as properties. You do not need change notification for commands, so they&#xD;
are ignored by the interceptor.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ShouldSurpressCode" border="0" alt="ShouldSurpressCode" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/AutomaticINotifyPropertyChangedusingDyna_2906/ShouldSurpressCode_3.png" width="670" height="216"&gt;&lt;/img&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Now that we have our change notification interceptor the only thing missing is a way&#xD;
to create the proxy object. To do this we create a new proxy creator. The proxy creator&#xD;
has a generic method that creates proxied instances of any class implementing the&#xD;
IAutoNotifyPropertyChanged-interface.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ProxyCreatorCode" border="0" alt="ProxyCreatorCode" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/AutomaticINotifyPropertyChangedusingDyna_2906/ProxyCreatorCode_3.png" width="670" height="233"&gt;&lt;/img&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
This diagram illustrates how the View calls the property setter on the proxied ViewModel.&#xD;
The property setter gets intercepted, and the interceptor lets the original setter&#xD;
execute before raising the PropertyChanged-event.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/AutomaticINotifyPropertyChangedusingDyna_2906/AutoINPCDiagram_2.png"&gt;&#xD;
            &lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="AutoINPCDiagram" border="0" alt="AutoINPCDiagram" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/AutomaticINotifyPropertyChangedusingDyna_2906/AutoINPCDiagram_thumb.png" width="670" height="490"&gt;&lt;/img&gt;&#xD;
          &lt;/a&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Now that we got the proxy creator it is really straight forward to create an instance&#xD;
of our ViewModel that will have automatic change-notification. I have included the&#xD;
tests documenting the behavior of the automatic change notification interceptor. The&#xD;
tests documents change notification for simple properties, as well as exclusion of&#xD;
commands and properties marked with the DoNotNotifyChanges-attribute. &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="AutoINPCTestsCode" border="0" alt="AutoINPCTestsCode" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/AutomaticINotifyPropertyChangedusingDyna_2906/AutoINPCTestsCode_3.png" width="670" height="875"&gt;&lt;/img&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;h4&gt;Summary&#xD;
&lt;/h4&gt;&#xD;
        &lt;p&gt;&#xD;
Using dynamic proxies for automatic change notification is a good way to keep your&#xD;
ViewModels nice and tidy as well as not having to hand-write tedious, repetitive change&#xD;
notification code. In my next blog post I will explore how we can integrate the change-notification&#xD;
interceptor with the Ninject IoC-container. By integrating the interceptor with an&#xD;
IoC-container we can have any ViewModel retrieved from the container support automatic&#xD;
change notification.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
For more information about Castle Dynamic Proxy I would recommend &lt;a href="http://kozmic.pl/Default.aspx"&gt;Krzysztof&#xD;
Koźmic&lt;/a&gt;&lt;a href="http://kozmic.pl/archive/2009/04/27/castle-dynamic-proxy-tutorial.aspx"&gt;excellent&#xD;
15-part tutorial&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The example code for this blog post requires Silverlight 3, and includes the latest&#xD;
beta of Castle Dynamic Proxy 2.2. The code is experimental, and not intended for production&#xD;
use.&#xD;
&lt;/p&gt;&#xD;
        &lt;iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 98px; padding-right: 0px; height: 115px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-1a08c11c407c0d8e.skydrive.live.com/embedicon.aspx/Code%20samples/AutoINPC.zip" frameborder="0" marginwidth="0" scrolling="no"&gt;&#xD;
        &lt;/iframe&gt;&#xD;
        &lt;img width="0" height="0" src="http://jonas.follesoe.no/aggbug.ashx?id=b82d81db-a34d-4644-850e-811f369d5489"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=_raLxPLuvH8:8bIgqToJ2cs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=_raLxPLuvH8:8bIgqToJ2cs:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=_raLxPLuvH8:8bIgqToJ2cs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?i=_raLxPLuvH8:8bIgqToJ2cs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=_raLxPLuvH8:8bIgqToJ2cs:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/follesoe/~4/_raLxPLuvH8" height="1" width="1"/&gt;</description>
      <comments>http://jonas.follesoe.no/CommentView,guid,b82d81db-a34d-4644-850e-811f369d5489.aspx</comments>
      <category>MVVM</category>
      <category>Patterns</category>
      <category>Silverlight</category>
    </item>
    <item>
      <trackback:ping>http://jonas.follesoe.no/Trackback.aspx?guid=55e182ea-652b-49cd-97e0-3bf37eebe96e</trackback:ping>
      <pingback:server>http://jonas.follesoe.no/pingback.aspx</pingback:server>
      <pingback:target>http://jonas.follesoe.no/PermaLink,guid,55e182ea-652b-49cd-97e0-3bf37eebe96e.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://jonas.follesoe.no/CommentView,guid,55e182ea-652b-49cd-97e0-3bf37eebe96e.aspx</wfw:comment>
      <wfw:commentRss>http://jonas.follesoe.no/SyndicationService.asmx/GetEntryCommentsRss?guid=55e182ea-652b-49cd-97e0-3bf37eebe96e</wfw:commentRss>
      <slash:comments>4</slash:comments>
      
      <title>Some food for thought on a Saturday morning</title>
      <guid isPermaLink="false">http://jonas.follesoe.no/PermaLink,guid,55e182ea-652b-49cd-97e0-3bf37eebe96e.aspx</guid>
      <link>http://jonas.follesoe.no/SomeFoodForThoughtOnASaturdayMorning.aspx</link>
      <pubDate>Sat, 28 Nov 2009 11:23:11 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
This blog post is not about software development. Or maybe it is. I will leave that&#xD;
up for you to decide. &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
On the flight home from Frankfurt last night I was reading &lt;a href="http://www.dn.no/d2/"&gt;D2&lt;/a&gt;,&#xD;
a magazine that comes out every Friday as part of the Norwegian newspaper Dagens Næringsliv.&#xD;
I haven’t read D2 before, but I was surprised by the quality of design and print as&#xD;
well as the great feature stories. Some of the quotes in the stories caught my attention&#xD;
and I want to share them with you.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The first feature story was about the perfume industry, and the increasing popularity&#xD;
of smaller, more exclusive and personalized niche perfumes. I’m not at all interested&#xD;
in perfume and cosmetics, but it was still fascinating to read about the movers and&#xD;
shakers of that industry. I want to share a quote from &lt;a href="http://www.franciskurkdjian.com/"&gt;Francis&#xD;
Kurkdjian&lt;/a&gt;, one of the most famous perfumers in the world:&#xD;
&lt;/p&gt;&#xD;
        &lt;blockquote class="pink"&gt;&#xD;
          &lt;p&gt;&#xD;
            &lt;em&gt;The problem with this industry is that there are too many people involved in the&#xD;
process. There are too much thinking and rationalizing, and too little passion. &lt;/em&gt;&#xD;
          &lt;/p&gt;&#xD;
          &lt;p align="right"&gt;&#xD;
            &lt;em&gt;- Francis Kurkdjian, famous perfumers.&lt;/em&gt;&#xD;
          &lt;/p&gt;&#xD;
        &lt;/blockquote&gt;&#xD;
        &lt;p&gt;&#xD;
The next quote is by &lt;a href="http://ecologicalurbanism.gsd.harvard.edu/2009/03/12/sissel-tolaas/"&gt;Sissel&#xD;
Tolaas&lt;/a&gt;, taken from the same story:&#xD;
&lt;/p&gt;&#xD;
        &lt;blockquote class="pink"&gt;&#xD;
          &lt;p&gt;&#xD;
            &lt;em&gt;Excellent perfumers have been forced to make a commercial soup. It came a point&#xD;
where they said; “this is boring, we can do better”. &lt;/em&gt;&#xD;
          &lt;/p&gt;&#xD;
          &lt;p align="right"&gt;&#xD;
            &lt;em&gt;- Sissel Tolaas, artist and perfumer&lt;/em&gt;&#xD;
          &lt;/p&gt;&#xD;
        &lt;/blockquote&gt;&#xD;
        &lt;p&gt;&#xD;
The next story was about &lt;a href="http://en.wikipedia.org/wiki/Mario_Batali"&gt;Mario&#xD;
Batali&lt;/a&gt;; perhaps USA’s most famous chef. Mario owns 15 restaurants, and is in charge&#xD;
of 1800 employees. He has also written several books and appeared on multiple TV shows.&#xD;
Mario is a fascinating guy, with a great passion for his craft. The following quote&#xD;
is taken from his answer about whether his colleague education and specialization&#xD;
in Spanish classical theater is of any relevance to his profession:&#xD;
&lt;/p&gt;&#xD;
        &lt;blockquote class="pink"&gt;&#xD;
          &lt;p&gt;&#xD;
            &lt;em&gt;All knowledge about the world around you makes you better suited to complete the&#xD;
task at hand. I could teach a fucking chimpanzee the manual work involved. But I cannot&#xD;
teach him to love it, day after day, thousand days in a row. &lt;/em&gt;&#xD;
          &lt;/p&gt;&#xD;
          &lt;p align="right"&gt;&#xD;
            &lt;em&gt;- Mario Baltali, most famous chef in the USA&lt;/em&gt;&#xD;
          &lt;/p&gt;&#xD;
        &lt;/blockquote&gt;&#xD;
        &lt;p&gt;&#xD;
The &lt;a href="http://www.dn.no/d2/arkitektur/article1789680.ece"&gt;third story&lt;/a&gt; was&#xD;
about the Norwegian architects &lt;a href="http://www.bkark.no/"&gt;Geir Brendeland and&#xD;
Olav Kristoffersen&lt;/a&gt;, who became famous for creating the &lt;a href="http://www.bkark.no/projects/svartlamoen-housing/"&gt;tallest&#xD;
building in Norway built using solid wood&lt;/a&gt;. They now run their own architecture&#xD;
office where wood as a building material is one of their specializations. &#xD;
&lt;/p&gt;&#xD;
        &lt;blockquote class="pink"&gt;&#xD;
          &lt;p&gt;&#xD;
            &lt;em&gt;We are extremely interested in the field of architecture. Our goal was not to&#xD;
build up a large office; the goal was to learn the craft and create projects. To build. &lt;/em&gt;&#xD;
          &lt;/p&gt;&#xD;
          &lt;p align="right"&gt;&#xD;
            &lt;em&gt;- Geir Brendeland, architect&lt;/em&gt;&#xD;
          &lt;/p&gt;&#xD;
        &lt;/blockquote&gt;&#xD;
        &lt;blockquote class="pink"&gt;&#xD;
          &lt;p&gt;&#xD;
            &lt;em&gt;The distance between architects and craftsmen has gotten way too big. &lt;/em&gt;&#xD;
          &lt;/p&gt;&#xD;
          &lt;p align="right"&gt;&#xD;
            &lt;em&gt;- Olav Kristoffersen, architect&lt;/em&gt;&#xD;
          &lt;/p&gt;&#xD;
        &lt;/blockquote&gt;&#xD;
        &lt;img width="0" height="0" src="http://jonas.follesoe.no/aggbug.ashx?id=55e182ea-652b-49cd-97e0-3bf37eebe96e"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=nsxM8v84VYc:IrYVufmjAqc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=nsxM8v84VYc:IrYVufmjAqc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=nsxM8v84VYc:IrYVufmjAqc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?i=nsxM8v84VYc:IrYVufmjAqc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=nsxM8v84VYc:IrYVufmjAqc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/follesoe/~4/nsxM8v84VYc" height="1" width="1"/&gt;</description>
      <comments>http://jonas.follesoe.no/CommentView,guid,55e182ea-652b-49cd-97e0-3bf37eebe96e.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://jonas.follesoe.no/Trackback.aspx?guid=2becbdf8-9883-423b-bffd-306bd3a7e8ca</trackback:ping>
      <pingback:server>http://jonas.follesoe.no/pingback.aspx</pingback:server>
      <pingback:target>http://jonas.follesoe.no/PermaLink,guid,2becbdf8-9883-423b-bffd-306bd3a7e8ca.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://jonas.follesoe.no/CommentView,guid,2becbdf8-9883-423b-bffd-306bd3a7e8ca.aspx</wfw:comment>
      <wfw:commentRss>http://jonas.follesoe.no/SyndicationService.asmx/GetEntryCommentsRss?guid=2becbdf8-9883-423b-bffd-306bd3a7e8ca</wfw:commentRss>
      
      <title>My UX prototyping presentation from Smidig2009</title>
      <guid isPermaLink="false">http://jonas.follesoe.no/PermaLink,guid,2becbdf8-9883-423b-bffd-306bd3a7e8ca.aspx</guid>
      <link>http://jonas.follesoe.no/MyUXPrototypingPresentationFromSmidig2009.aspx</link>
      <pubDate>Fri, 20 Nov 2009 23:33:07 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
Last month I was lucky enough to attend and speak at the &lt;a href="http://smidig2009.no/"&gt;Smidig2009&lt;/a&gt; (Agile&#xD;
2009) conference in Oslo. This was my first time attending the conference, and I’m&#xD;
really impressed with the content, speakers, organizers and attendees. The format&#xD;
of the conference was four lightning talks per hour in three simultaneous tracks before&#xD;
lunch, and open spaces after lunch. The formatted worked out really well – and I got&#xD;
to see several inspiring and educational talks, as well as taking part in some interesting&#xD;
discussions in open spaces.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
My talk was about UX prototyping as a natural part of an agile software project. This&#xD;
is something I have written about both &lt;a href="http://jonas.follesoe.no/AgileUXDevelopmentUsingLowfidelityPrototypes.aspx"&gt;on&#xD;
this blog&lt;/a&gt;, as well as the &lt;a href="http://www.no.capgemini.com/teknologiblogg/2009/10/skjermbildeprototyping_en_nytt.php"&gt;Capgemini&#xD;
technology blog&lt;/a&gt;. The talk covered UX prototyping as a technique and the benefits&#xD;
it gives you in an agile project, as well as showing two short demos of mockups in&#xD;
Balsamiq, and interactive prototypes in SketchFlow.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Thanks to Tandberg video &lt;a href="http://tcs.java.no/tcs/"&gt;recordings of the entire&#xD;
conference&lt;/a&gt; was made available almost instantly. The image blow takes you &lt;a href="http://tcs.java.no/tcs/?id=EB63B27D-2453-42B5-9740-B53A0F19F84D"&gt;directly&#xD;
to my presentation&lt;/a&gt;. I have also uploaded the slide deck to Slide Share and embedded&#xD;
it into this post.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;div style="text-align: left; width: 425px" id="__ss_2450595"&gt;&#xD;
          &lt;object style="margin:0px" width="425" height="355"&gt;&#xD;
            &lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=smidiguxlyntalesmidig2009utenvideo-091108093705-phpapp01&amp;amp;stripped_title=smidig-brukeropplevelse-med-skjermbildeprototyper-smidig2009"&gt;&lt;/param&gt;&#xD;
            &lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&#xD;
            &lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt;&#xD;
            &lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=smidiguxlyntalesmidig2009utenvideo-091108093705-phpapp01&amp;amp;stripped_title=smidig-brukeropplevelse-med-skjermbildeprototyper-smidig2009" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&#xD;
            &lt;/embed&gt;&#xD;
          &lt;/object&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://tcs.java.no/tcs/?id=EB63B27D-2453-42B5-9740-B53A0F19F84D"&gt;&#xD;
            &lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Smidig2009UXPresentasjon" border="0" alt="Smidig2009UXPresentasjon" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/MyUXprototypingpresentationfromSmidig200_7B0/Smidig2009UXPresentasjon_3.png" width="670" height="343"&gt;&lt;/img&gt;&#xD;
          &lt;/a&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;img width="0" height="0" src="http://jonas.follesoe.no/aggbug.ashx?id=2becbdf8-9883-423b-bffd-306bd3a7e8ca"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=2zepx6Zt-_M:nX-SJ2_ygsY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=2zepx6Zt-_M:nX-SJ2_ygsY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=2zepx6Zt-_M:nX-SJ2_ygsY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?i=2zepx6Zt-_M:nX-SJ2_ygsY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=2zepx6Zt-_M:nX-SJ2_ygsY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/follesoe/~4/2zepx6Zt-_M" height="1" width="1"/&gt;</description>
      <comments>http://jonas.follesoe.no/CommentView,guid,2becbdf8-9883-423b-bffd-306bd3a7e8ca.aspx</comments>
      <category>Agile</category>
      <category>Presentation</category>
      <category>UX</category>
    </item>
    <item>
      <trackback:ping>http://jonas.follesoe.no/Trackback.aspx?guid=a81e0deb-423c-4d1a-8c62-c05356992a80</trackback:ping>
      <pingback:server>http://jonas.follesoe.no/pingback.aspx</pingback:server>
      <pingback:target>http://jonas.follesoe.no/PermaLink,guid,a81e0deb-423c-4d1a-8c62-c05356992a80.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://jonas.follesoe.no/CommentView,guid,a81e0deb-423c-4d1a-8c62-c05356992a80.aspx</wfw:comment>
      <wfw:commentRss>http://jonas.follesoe.no/SyndicationService.asmx/GetEntryCommentsRss?guid=a81e0deb-423c-4d1a-8c62-c05356992a80</wfw:commentRss>
      <slash:comments>1</slash:comments>
      
      <title>Speaking at NNUG Kristiansand and Smidig 2009 next week</title>
      <guid isPermaLink="false">http://jonas.follesoe.no/PermaLink,guid,a81e0deb-423c-4d1a-8c62-c05356992a80.aspx</guid>
      <link>http://jonas.follesoe.no/SpeakingAtNNUGKristiansandAndSmidig2009NextWeek.aspx</link>
      <pubDate>Sat, 17 Oct 2009 08:45:55 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
On Wednesday 21 October I will be visiting the Kristiansand chapter of &lt;a href="http://nnug.no"&gt;NNUG&lt;/a&gt; to&#xD;
give two Silverlight presentations. The first will be about the MVVM design pattern,&#xD;
and the second on building business focused applications using .NET RIA Services.&#xD;
After the NNUG meeting there will be a geekbeer get-together at Patrick’s. &lt;a href="http://nnug.no/Avdelinger/Kristiansand/Moter2/NNUG-Kristiansand--Oktober-2009/"&gt;Details&#xD;
and registration for the meeting is up on the NNUG site&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
On Thursday and Friday (22-23 October) I will be attending the &lt;a href="http://smidig2009.no"&gt;Smidig&#xD;
2009&lt;/a&gt; (Agile 2009) conference in Oslo. This will be my first time attending the&#xD;
Smidig conference, and I’m really looking forward to it. The format of the conference&#xD;
is 4 lightning talks pr hour before lunch, and open spaces after lunch. Judging by&#xD;
the number of submitted talks I think it is going to be a really interesting conference,&#xD;
and I hope to learn allot about how to run successful agile software projects. I’m&#xD;
also a big fan of open spaces and the interaction between conference attendees it&#xD;
enables.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Since I was planning to attend the conference I made a last minute decision to submit &lt;a href="http://smidig2009.no/talks/111"&gt;a&#xD;
talk on UX prototyping in agile projects&lt;/a&gt; using &lt;a href="http://balsamiq.com"&gt;Balsamiq&lt;/a&gt; and &lt;a href="http://www.microsoft.com/expression/products/SketchFlow_OverView.aspx"&gt;SketchFlow&lt;/a&gt;.&#xD;
The talk got accepted, which means I will not only be attending – I will also be speaking&#xD;
at the conference!&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
I’m looking forward to doing some presentations again, and I hope to see you in Kristiansand&#xD;
or Oslo next week!&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;em&gt;(Time-lapse video taken by &lt;a href="http://twitter.com/petesamuel"&gt;@petesamuel&lt;/a&gt; from&#xD;
a presentation I gave earlier this year)&lt;/em&gt; &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;object width="425" height="344"&gt;&#xD;
            &lt;param name="movie" value="http://www.youtube.com/v/Xa5FTHhFHGs&amp;amp;hl=en&amp;amp;fs=1&amp;amp;"&gt;&lt;/param&gt;&#xD;
            &lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&#xD;
            &lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&#xD;
            &lt;embed src="http://www.youtube.com/v/Xa5FTHhFHGs&amp;amp;hl=en&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&#xD;
            &lt;/embed&gt;&#xD;
          &lt;/object&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;img width="0" height="0" src="http://jonas.follesoe.no/aggbug.ashx?id=a81e0deb-423c-4d1a-8c62-c05356992a80"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=0lI6316GaJ4:uo4KaCVVbAE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=0lI6316GaJ4:uo4KaCVVbAE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=0lI6316GaJ4:uo4KaCVVbAE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?i=0lI6316GaJ4:uo4KaCVVbAE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=0lI6316GaJ4:uo4KaCVVbAE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/follesoe/~4/0lI6316GaJ4" height="1" width="1"/&gt;</description>
      <comments>http://jonas.follesoe.no/CommentView,guid,a81e0deb-423c-4d1a-8c62-c05356992a80.aspx</comments>
      <category>Agile</category>
      <category>Conferences</category>
      <category>NNUG</category>
      <category>Presentation</category>
      <category>UX</category>
    </item>
    <item>
      <trackback:ping>http://jonas.follesoe.no/Trackback.aspx?guid=87563e28-a46e-4daa-9f6f-de546186560e</trackback:ping>
      <pingback:server>http://jonas.follesoe.no/pingback.aspx</pingback:server>
      <pingback:target>http://jonas.follesoe.no/PermaLink,guid,87563e28-a46e-4daa-9f6f-de546186560e.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://jonas.follesoe.no/CommentView,guid,87563e28-a46e-4daa-9f6f-de546186560e.aspx</wfw:comment>
      <wfw:commentRss>http://jonas.follesoe.no/SyndicationService.asmx/GetEntryCommentsRss?guid=87563e28-a46e-4daa-9f6f-de546186560e</wfw:commentRss>
      <slash:comments>1</slash:comments>
      
      <title>Agile UX development using low-fidelity prototypes</title>
      <guid isPermaLink="false">http://jonas.follesoe.no/PermaLink,guid,87563e28-a46e-4daa-9f6f-de546186560e.aspx</guid>
      <link>http://jonas.follesoe.no/AgileUXDevelopmentUsingLowfidelityPrototypes.aspx</link>
      <pubDate>Sat, 26 Sep 2009 18:15:47 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
For me agile software projects is all about maximizing the customers’ value of the&#xD;
software being built by encouraging and incorporating feedback, new features and change&#xD;
requests as quickly and cheaply as possible. To achieve agility we adopt agile project&#xD;
process like &lt;a href="http://en.wikipedia.org/wiki/Scrum_%28development%29"&gt;Scrum&lt;/a&gt;,&#xD;
which helps us manage and prioritize the features of the software we are building&#xD;
into short iterations. To build a flexible code base that enables us to quickly add,&#xD;
remove or change features throughout the project we adopt agile development practices&#xD;
like &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;Test Driven Development&lt;/a&gt;.&#xD;
We try to follow good design principles like &lt;a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod"&gt;SOLID&lt;/a&gt;,&#xD;
and we build and integrate our code frequently using &lt;a href="http://en.wikipedia.org/wiki/Continuous_integration"&gt;Continuous&#xD;
Integration&lt;/a&gt;. But what can we do to become more agile in the way we build the &lt;a href="http://en.wikipedia.org/wiki/User_experience_design"&gt;User&#xD;
Experience&lt;/a&gt; (screen layout, navigation structure, colors and graphic design, imagery,&#xD;
error messages, texts and labels) of our application?&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
On most of the software projects I have worked on the User Experience have been left&#xD;
up to the developers to decide. Towards the end of the iteration we bring in the customer&#xD;
for a demonstration of what we have built, implemented as running HTML, Windows Forms&#xD;
or perhaps XAML code. In many cases the customer immediately starts focuses on the&#xD;
tiny (perhaps unimportant) details of the UX. Like, “the title should be bigger and&#xD;
bluer”, or “the save button should be 4 pixels to the left”. One of the reasons for&#xD;
this reaction might be that by demonstrating a complete implementation of the UX straight&#xD;
away the application looks too complete, and the customer might feel that it is too&#xD;
late in the project to make substantial changes to the UX of the software. However,&#xD;
if this does not happen and we do get good feedback, suggesting that we need to rethink&#xD;
the UX of the application, the reaction from the development team might be hesitation.&#xD;
If you have put lots of effort into building the UX of the application you don’t want&#xD;
to throw it away. And in contrast the business logic of the application we do not&#xD;
have the same refactoring and testing support for the UX of our application as we&#xD;
do for the other parts of the system, making it harder to make big changes with little&#xD;
effort.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
One way to work efficiently with UX in an agile software team is to create low-fidelity&#xD;
prototypes. These prototypes can be created using &lt;a href="http://www.alistapart.com/articles/paperprototyping"&gt;pen&#xD;
and paper&lt;/a&gt;, or tools like Visio, &lt;a href="http://www.istartedsomething.com/20071018/powerpoint-prototype-toolkit-01/"&gt;PowerPoint&lt;/a&gt;, &lt;a href="http://balsamiq.com/"&gt;Balsamiq&lt;/a&gt; or &lt;a href="http://www.microsoft.com/expression/products/SketchFlow_OverView.aspx"&gt;SketchFlow&lt;/a&gt;. &lt;a href="http://www.alistapart.com/articles/paperprototyping"&gt;Low-fidelity&#xD;
prototypes&lt;/a&gt; feel less finished, but are at the same time concrete enough for the&#xD;
customer to really “get” the concepts being prototyped. Using low-fidelity prototypes&#xD;
the customer is more likely to give constructive feedback about the important aspects&#xD;
of the UX, like how the screen layout and navigation should work, which fields are&#xD;
needed, or how we are going to display error messages, than if they were presented&#xD;
with a high-fidelity prototype or near complete version of the software.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="paperprototype" border="0" alt="paperprototype" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/AgileUXdevelopmentusinglowfidelityprotot_11CDC/paperprototype_3.jpg" width="282" height="254"&gt;&lt;/img&gt;&#xD;
          &lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Oppsett" border="0" alt="Oppsett" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/AgileUXdevelopmentusinglowfidelityprotot_11CDC/Oppsett_3.png" width="340" height="254"&gt;&lt;/img&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The developers are going to be less attached to a low-fidelity prototype, as the amount&#xD;
of effort put into it is far less compared to a real implementation done in code.&#xD;
Using prototyping the development team and the customer can do multiple iterations&#xD;
trying out different ideas and concepts for the UX, hopefully coming up with a great&#xD;
solution in the end. After all, good design is all about exploring multiple ideas,&#xD;
before narrowing it down to the right design for the problem. Good design is not about&#xD;
picking the first solution that pops into a developers mind.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
I think UX prototyping fits perfectly with agile software development, and should&#xD;
be a natural tool for any agile team building software that interacts directly with&#xD;
end-users. My next blog post is going to be more concrete, giving an introduction&#xD;
to two great prototyping tools: Balsamiq and Microsoft SketchFlow.&#xD;
&lt;/p&gt;&#xD;
        &lt;img width="0" height="0" src="http://jonas.follesoe.no/aggbug.ashx?id=87563e28-a46e-4daa-9f6f-de546186560e"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=rX-6yScbYMg:bH4lKeUdupQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=rX-6yScbYMg:bH4lKeUdupQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=rX-6yScbYMg:bH4lKeUdupQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?i=rX-6yScbYMg:bH4lKeUdupQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=rX-6yScbYMg:bH4lKeUdupQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/follesoe/~4/rX-6yScbYMg" height="1" width="1"/&gt;</description>
      <comments>http://jonas.follesoe.no/CommentView,guid,87563e28-a46e-4daa-9f6f-de546186560e.aspx</comments>
      <category>Agile</category>
      <category>Silverlight</category>
      <category>SketchFlow</category>
      <category>UX</category>
    </item>
    <item>
      <trackback:ping>http://jonas.follesoe.no/Trackback.aspx?guid=2db1100f-018d-4cc0-8fd1-261eec4796e6</trackback:ping>
      <pingback:server>http://jonas.follesoe.no/pingback.aspx</pingback:server>
      <pingback:target>http://jonas.follesoe.no/PermaLink,guid,2db1100f-018d-4cc0-8fd1-261eec4796e6.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://jonas.follesoe.no/CommentView,guid,2db1100f-018d-4cc0-8fd1-261eec4796e6.aspx</wfw:comment>
      <wfw:commentRss>http://jonas.follesoe.no/SyndicationService.asmx/GetEntryCommentsRss?guid=2db1100f-018d-4cc0-8fd1-261eec4796e6</wfw:commentRss>
      <slash:comments>8</slash:comments>
      
      <title>Recording of my MVVM talk at NDC2009 is now online</title>
      <guid isPermaLink="false">http://jonas.follesoe.no/PermaLink,guid,2db1100f-018d-4cc0-8fd1-261eec4796e6.aspx</guid>
      <link>http://jonas.follesoe.no/RecordingOfMyMVVMTalkAtNDC2009IsNowOnline.aspx</link>
      <pubDate>Sat, 04 Jul 2009 23:28:39 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
The videos from NDC2009 are now published on &lt;a href="http://ndc2009.no/agenda.aspx?cat=1071&amp;amp;id=1813"&gt;the&#xD;
conference agenda site&lt;/a&gt;. The site isn’t the easiest to navigate, so &lt;a href="http://blog.fohjin.com/"&gt;Mark&#xD;
Nijhof&lt;/a&gt; went through the effort of creating a &lt;a href="http://blog.fohjin.com/blog/2009/7/1/NDC_videos_are_published"&gt;simple&#xD;
list of all the videos grouped by speaker&lt;/a&gt;. There is tons of great content available&#xD;
and the videos should be a great way to do some (relaxed) learning in the summer heat. &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
There is a problem with some of the links, and the link to the video of my second&#xD;
talk on .NET RIA Services is broken. I’ll make a new post when that video becomes&#xD;
available.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://media01.smartcom.no/Microsite/start.aspx?eventid=4459"&gt;&#xD;
            &lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="JoansGivingMVVMTalk" border="0" alt="JoansGivingMVVMTalk" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/RecordingofmyMVVMtalkatNDC2009isnowonlin_14C1/JoansGivingMVVMTalk_3.png" width="670" height="342"&gt;&lt;/img&gt;&#xD;
          &lt;/a&gt;  &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://media01.smartcom.no/Microsite/start.aspx?eventid=4459"&gt;Click to view&#xD;
my Model-View-ViewModel presentation from NDC2009.&lt;/a&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;img width="0" height="0" src="http://jonas.follesoe.no/aggbug.ashx?id=2db1100f-018d-4cc0-8fd1-261eec4796e6"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=u1vX_BXyyDI:qs7kXmUW638:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=u1vX_BXyyDI:qs7kXmUW638:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=u1vX_BXyyDI:qs7kXmUW638:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?i=u1vX_BXyyDI:qs7kXmUW638:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=u1vX_BXyyDI:qs7kXmUW638:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/follesoe/~4/u1vX_BXyyDI" height="1" width="1"/&gt;</description>
      <comments>http://jonas.follesoe.no/CommentView,guid,2db1100f-018d-4cc0-8fd1-261eec4796e6.aspx</comments>
      <category>Conferences</category>
      <category>Presentation</category>
      <category>Silverlight</category>
      <category>WPF</category>
    </item>
    <item>
      <trackback:ping>http://jonas.follesoe.no/Trackback.aspx?guid=44b5816d-67a6-4b66-ad05-1402d67086e6</trackback:ping>
      <pingback:server>http://jonas.follesoe.no/pingback.aspx</pingback:server>
      <pingback:target>http://jonas.follesoe.no/PermaLink,guid,44b5816d-67a6-4b66-ad05-1402d67086e6.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://jonas.follesoe.no/CommentView,guid,44b5816d-67a6-4b66-ad05-1402d67086e6.aspx</wfw:comment>
      <wfw:commentRss>http://jonas.follesoe.no/SyndicationService.asmx/GetEntryCommentsRss?guid=44b5816d-67a6-4b66-ad05-1402d67086e6</wfw:commentRss>
      <slash:comments>12</slash:comments>
      
      <title>Awarded Silverlight MVP 2009!</title>
      <guid isPermaLink="false">http://jonas.follesoe.no/PermaLink,guid,44b5816d-67a6-4b66-ad05-1402d67086e6.aspx</guid>
      <link>http://jonas.follesoe.no/AwardedSilverlightMVP2009.aspx</link>
      <pubDate>Thu, 02 Jul 2009 21:26:36 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;img style="border-right-width: 0px; margin: 0px 15px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="MicrosoftMVP" border="0" alt="MicrosoftMVP" align="left" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/AwardedSilverlightMVP2009_1499D/MicrosoftMVP_3.png" width="85" height="132"&gt;&lt;/img&gt; Yesterday&#xD;
I was awarded &lt;a href="https://mvp.support.microsoft.com/"&gt;Microsoft Most Valuable&#xD;
Professional&lt;/a&gt; in Silverlight. The nomination came based on my involvement with&#xD;
the Silverlight community during my year in Australia. I’m truly grateful for such&#xD;
recognition, and am looking forward to continue to work closely with the Silverlight&#xD;
development community to share knowledge and learn together.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
About the MVP program (from Microsoft): &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;em&gt;Microsoft is pleased to recognize and award its Most Valuable Professionals (MVPs).&#xD;
We present the MVP Award to thank individuals for their exceptional contributions&#xD;
to technical communities worldwide. When a community participant sees an MVP in a&#xD;
technical community, whether in a newsgroup, as a user group host, a conference speaker,&#xD;
or a respondent in forums, that community participant can be confident that the information&#xD;
shared by the MVP will be of the highest caliber and will help every user make the&#xD;
most of the technology.&lt;/em&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://twitter.com/teamsilverlight/statuses/2415785003"&gt;&#xD;
            &lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="SilverlightMVPTweet" border="0" alt="SilverlightMVPTweet" src="http://jonas.follesoe.no/content/binary/WindowsLiveWriter/AwardedSilverlightMVP2009_1499D/SilverlightMVPTweet_3.png" width="670" height="272"&gt;&lt;/img&gt;&#xD;
          &lt;/a&gt;&#xD;
          &lt;br&gt;&#xD;
          &lt;em&gt;As with all important news: It breaks first on Twitter.&lt;/em&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;em&gt;&#xD;
            &lt;strong&gt;Update&lt;/strong&gt;: &lt;a href="https://mvp.support.microsoft.com/profile=C85D0CA7-9EE2-4236-AED3-5009DFABCACA"&gt;My&#xD;
MVP profile is now available online&lt;/a&gt;.&lt;/em&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;img width="0" height="0" src="http://jonas.follesoe.no/aggbug.ashx?id=44b5816d-67a6-4b66-ad05-1402d67086e6"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=oXQ6sGwavIw:GyrdJ3aXb1E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=oXQ6sGwavIw:GyrdJ3aXb1E:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=oXQ6sGwavIw:GyrdJ3aXb1E:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?i=oXQ6sGwavIw:GyrdJ3aXb1E:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/follesoe?a=oXQ6sGwavIw:GyrdJ3aXb1E:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/follesoe?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/follesoe/~4/oXQ6sGwavIw" height="1" width="1"/&gt;</description>
      <comments>http://jonas.follesoe.no/CommentView,guid,44b5816d-67a6-4b66-ad05-1402d67086e6.aspx</comments>
    </item>
  </channel>
</rss>
