<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Dude, where is my Kaizen?</title>
	<atom:link href="http://www.bjoernrochel.de/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.bjoernrochel.de</link>
	<description>Björn Rochel&#039;s weblog</description>
	<lastBuildDate>Mon, 21 Jun 2010 07:26:00 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>prio. conference 2010</title>
		<link>http://www.bjoernrochel.de/2010/06/21/prio-conference-2010/</link>
		<comments>http://www.bjoernrochel.de/2010/06/21/prio-conference-2010/#comments</comments>
		<pubDate>Mon, 21 Jun 2010 07:26:00 +0000</pubDate>
		<dc:creator>BjRo</dc:creator>
				<category><![CDATA[Conference]]></category>
		<category><![CDATA[#prio]]></category>

		<guid isPermaLink="false">http://www.bjoernrochel.de/2010/06/21/prio-conference-2010/</guid>
		<description><![CDATA[In case you haven’t heard it yet, I’m going to give 2 talks at this years prio. conference.     
 
I’m very exited to be part of this years speaker line up (though the quality of the line up is a bit intimidating  ) Both talks will be on the 20th [...]]]></description>
			<content:encoded><![CDATA[<p>In case you haven’t heard it yet, I’m going to give 2 talks at this years <a href="http://www.prioconference.de/" target="_blank">prio. conference</a>.     </p>
<p><a href="http://www.bjoernrochel.de/wp-content/uploads/2010/06/prioSpreaker_Banner_234x60_1.gif"><img style="border-bottom: 0px;border-left: 0px;border-top: 0px;border-right: 0px" border="0" alt="prio-Spreaker_Banner_234x60_1" src="http://www.bjoernrochel.de/wp-content/uploads/2010/06/prioSpreaker_Banner_234x60_1_thumb.gif" width="234" height="60" /></a> </p>
<p>I’m very exited to be part of <a href="http://www.prioconference.de/Speaker/Speaker-prio.conference-2010" target="_blank">this years speaker line up</a> (though the quality of the line up is a bit intimidating <img src='http://www.bjoernrochel.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> ) Both talks will be on the <a href="http://www.prioconference.de/Programm/Programm-prio.conference-20.-Oktober-2010/prio.conference-Track-32" target="_blank">20th of October in Track 4</a>.</p>
<p>10.05 – 11.05h    </p>
<p><strong>Introduction to Rhino.ServiceBus</strong></p>
<p>15.20h – 16.20h</p>
<p><strong>(ServiceBus) Patters for always responsive clients</strong></p>
<p>Looking forward to see you there . . . </p>
]]></content:encoded>
			<wfw:commentRss>http://www.bjoernrochel.de/2010/06/21/prio-conference-2010/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>.NET Open Space S&#252;d Retrospective</title>
		<link>http://www.bjoernrochel.de/2010/06/21/net-open-space-sd-retrospective/</link>
		<comments>http://www.bjoernrochel.de/2010/06/21/net-open-space-sd-retrospective/#comments</comments>
		<pubDate>Mon, 21 Jun 2010 06:46:59 +0000</pubDate>
		<dc:creator>BjRo</dc:creator>
				<category><![CDATA[Conference]]></category>
		<category><![CDATA[NOS_SUED]]></category>

		<guid isPermaLink="false">http://www.bjoernrochel.de/2010/06/21/net-open-space-sd-retrospective/</guid>
		<description><![CDATA[I haven&#8217;t blogged in a while, mostly because time has become such a limited resource in the last weeks or to be honest actually months. Blogging, my current project, workshops, the F# Bookclub, preparation of the next conference appearances and of course xUnit.BDDExtensions all want a piece of that cake. Finding the right balance between [...]]]></description>
			<content:encoded><![CDATA[<p>I haven&#8217;t blogged in a while, mostly because time has become such a limited resource in the last weeks or to be honest actually months. Blogging, my current project, workshops, the F# Bookclub, preparation of the next conference appearances and of course xUnit.BDDExtensions all want a piece of that cake. Finding the right balance between those tasks is often not as easy as I would like it to be. More often as I like skipping blogging seems to be the easiest way to regain some time. I’m really sorry for that, but you know I try to do my best. On the other hand this is a new blog post,&#160; so things can’t be that bad, can’t they? Although I haven’t slept much the last 3 days, something inside me urges to write this post.</p>
<p>Most of the time of the past weekend I spend in Karlsruhe at the .NET Open Space Süd. To sum it up in 5 words: <u>The event was a blast</u>. I had an unbelievable amount of fun coding,&#160; chatting &amp; learning with some of smartest people in the German .NET Community.     </p>
<p>This was the 4th Open Space event I attended during the last 2 years and I think this one was the best so far. Why?     </p>
<ol>
<li>The content of the sessions I attended / participated in was really high quality. I learned something new in every fracking session. Every session was dense, focused and we had at least one participant who actually had extensive field experience in the related topic area. No CQRS session disaster this time <img src='http://www.bjoernrochel.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />      </li>
<li>Overly generic topics ala “I want to talk about TDD” or “Let’s talk about (D)DDD” were the minority.     </li>
</ol>
<p>Besides that, one personal note: It was a blast to meet some of the guys I got to know throughout the last 2 years again and see the personal progression each of them has made. Guys, your awesome. Keep up your pace!   </p>
<p>So, just to give you an idea about the sessions I attended here’s a quick sum-up of my weekend @NOS_SUED.    </p>
<h3>WTF is a Monad? (C# Edition)</h3>
<p>The first day started with one of the hardest topics you might imagine, Monads. @sforkmann did a great job explaining the various basic monadic types and their implementation in C#. Helped me a lot to form a better picture of this abstract concept in my mind. Was nice to see the Maybe Monad implemented using query comprehension syntax (though we found out that the related msdn sample doesn’t compile aka sucks). Sadly we didn’t have time enough to take a look at Monads in F#. Homework, I guess.   </p>
<p>Funny side note: The word “Monad” was present throughout the complete weekend. I guess the revelation that most of us have been using a&#160; Monad&#160; for quite a while now (in LINQ), though not knowing it, shocked quite a bunch of participants.</p>
<h3>Git tips &amp; tricks </h3>
<p>Next up was @agross with Git. I never forgot that Alex was the person that told me about this “Git thing” two years ago, long before the topic suddenly started to get the attentions of the .NET OS community. Main focus of this session was the various approaches around conflict resolution and a detailed look at the difference between merging and rebasing.    </p>
<p>Especially interesting was to hear a bit more about this experience with Git in the context of a popular .NET OS project (Alex is one of the core maintainers of MSpec).</p>
<h3>Convention over Configuration</h3>
<p>Halfway through Saturday I talked a bit about my experience with “Convention over Configuration”. My current project uses conventions a lot (but only for binding, thx @ilkerde for the clarification) and I’m really happy with the outcome so far. On retrospective I think @ilkerde, @agross and myself did a really good job in categorizing the various ways CoC can be applied from sourcecode, to builds to deployment. </p>
<h3>BDD&#160; vs. ATDD</h3>
<p>The biggest session I participated in was the (dunno what was the exact name of the session) “Behavior Driven Development vs. classic Acceptance Test Driven Development” session. Was cool to have @agross (MSpec maintainer), @ssishkin ( my personal Fitnesse guru), @sforkmann (creator of NaturalSpec), @DerAlbert and several others who’ve been doing BDD, something BDD-like or ATTD in a room and hearing their various war stories and views on the topic.</p>
<h3>Introduction to Reactive Extensions </h3>
<p>If you start a day with Monads to be consequent you need to end it with Monads, too.&#160; @sshishkin and @sforkmann gave an interesting talk about the ideas behind IObserver, IObservable and IQbservable. BTW, how cool is this IQbservable idea?</p>
<h3>Specification By Example Do’s &amp; Dont’ s </h3>
<p>In this session we took a look at the various proven practices in BDD specification design and the other side of the coin, the different flavors of specification smells. We discussed the ObjectMother pattern, TestData Builder Pattern, modularization strategies for specs and especially the idea of having the specifications side-by-side with the actual production code in a single assembly.&#160; Very good to see other proponents of this idea. </p>
<p>I was literally blown away by finally seeing the <a href="http://mokosh.co.uk/wp-content/uploads/2010/04/image10.png" target="_blank">grouping functionality for Visual Studio</a>, I always wanted to have, <a href="http://mokosh.co.uk/wp-content/uploads/2010/04/image23.png" target="_blank">alive</a>. <a href="http://mokosh.co.uk/vscommands/" target="_blank">VsCommands</a>, I’m going to install you today! </p>
<p>&#160;</p>
<h3>Behavior Driven Development BDD Framework &#8211; Shootout (MSpec vs. NaturalSpec vs. xUnit.BDDExtensions) </h3>
<p>The (un)conference ended for me with a side-by-side comparison of different BDD frameworks. Several guys asked for this. I guess it makes sense when you’ve got the authors of 3 different frameworks for a particular topic together.&#160; Although I didn’t like the idea at first sight (I don’t like framework wars that much, besides&#160; in the end the idea of BDD matters, and not the tools) the session turned out to be a win for all of us. We started demo-ed&#160; the typical bank transfer sample in each of the frameworks (MSpec, xUnit.BDDExtensions, NaturalSpec). Afterwards every framework owner demo-ed additional features more or less unique to the particular framework. I guess, each of us got ideas for “new” features <img src='http://www.bjoernrochel.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<h3>Closing thoughts</h3>
<p>I really enjoyed being in Karsruhe. Big thx to the organization team for making this event possible. I hope to see some of you again at the Open Space in Leipzig later this year or same place next year.   </p>
<p>Special thx to @agross, @sforkmann, @ilkerde, @roeb and @sshiskin for the intense and inside-full discussions. You rock guys!!! </p>
<p>One last advice: Don’t forget <u><strong>Jean Clojure’s basal monad</strong></u></p>
]]></content:encoded>
			<wfw:commentRss>http://www.bjoernrochel.de/2010/06/21/net-open-space-sd-retrospective/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Kata StringCalculator in F#</title>
		<link>http://www.bjoernrochel.de/2010/05/12/kata-stringcalculator-in-f/</link>
		<comments>http://www.bjoernrochel.de/2010/05/12/kata-stringcalculator-in-f/#comments</comments>
		<pubDate>Wed, 12 May 2010 18:36:38 +0000</pubDate>
		<dc:creator>BjRo</dc:creator>
				<category><![CDATA[F#]]></category>
		<category><![CDATA[Code Kata]]></category>
		<category><![CDATA[StringCalculator]]></category>

		<guid isPermaLink="false">http://www.bjoernrochel.de/?p=803</guid>
		<description><![CDATA[
Yesterday&#8217;s F# bookclub meeting in Munich was awesome as usual. It’s very interesting to see our overall understanding of functional programming progressing. Slowly, but steady. Main topics we discussed on the last meeting were Currying and Tail Recursion. Finally &#8220;got that&#8221; (at least I think so  )


Two meetings ago we decided to do some [...]]]></description>
			<content:encoded><![CDATA[<p>
Yesterday&#8217;s F# bookclub meeting in Munich was awesome as usual. It’s very interesting to see our overall understanding of functional programming progressing. Slowly, but steady. Main topics we discussed on the last meeting were Currying and Tail Recursion. Finally &#8220;got that&#8221; (at least I think so <img src='http://www.bjoernrochel.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> )
</p>
<p>
Two meetings ago we decided to do some coding on every meeting. The previous meeting we solved Kata FizzBuzz and on yesterday’s meeting we tried to dance with <a href="http://osherove.com/tdd-kata-1/">Roy Osheroves Kata StringCalculator</a>. We didn&#8217;t make it completely to the end, but I think we solved most of the Kata. You can find yesterdays code at the end of this post. I&#8217;m sure in parts it smells a bit imperative and it definitely uses too much Regex &#8211; KungFu, but overall I&#8217;m pleased with the result.
</p>
<p>
We&#8217;ve tried to incorporate the feedback we got on the Kata FizzBuzz code. I would love to get feedback on this one as well. What could be done better, cleaner or simply differently?
</p>
<pre class="brush: csharp">
open System
open System.Text.RegularExpressions
open Xunit

let shouldBeEqualTo a b = Assert.Equal(a,b)

let parse value =
    if String.IsNullOrEmpty(value) then 0 else
    match Int32.TryParse value with
    | (false,_) -&gt; failwithf &quot;Did not parse value %s&quot; value
    | (true, n) when n &lt; 0 -&gt; failwithf &quot;Negatives not allowed %s&quot; value
    | (true, n) when n &gt;= 1000 -&gt;0
    | (true, n) -&gt; n

let splitIntoDelimitersAndRest (calculationString:String) =
    let defaultDelmiters = [&quot;,&quot;;&quot;\n&quot;]
    let regex = new Regex(&quot;^//(?&lt;defaultDelimiter&gt;.*?)\\n(?&lt;rest&gt;.*)$&quot;, RegexOptions.Singleline)
    match regex.Match calculationString with
    | m when m.Success -&gt;
        let delimiters = List.Cons(m.Groups.[&quot;defaultDelimiter&quot;].Value, defaultDelmiters)
        (delimiters, m.Groups.[&quot;rest&quot;].Value)
    | _ -&gt; (defaultDelmiters, calculationString)

let add (calculationString:String) =
   let splitResult = splitIntoDelimitersAndRest calculationString
   let delimiters = fst splitResult |&gt; List.toArray
   let rest = snd splitResult
   rest.Split(delimiters, StringSplitOptions.RemoveEmptyEntries)
   |&gt; List.ofSeq
   |&gt; List.map parse
   |&gt; List.sum

[&lt;Fact&gt;]
let ``When an empty string is supplied it should return 0``() =
    String.Empty
    |&gt; add
    |&gt; (shouldBeEqualTo 0)

[&lt;Fact&gt;]
let ``When a single digit is supplied it should return the digits value``() =
    [&quot;1&quot;; &quot;2&quot;; &quot;3&quot;]
    |&gt; List.map add
    |&gt; List.iter2 shouldBeEqualTo [1;2;3]

[&lt;Fact&gt;]
let ``When two digits are supplied separated by a comma it should be able to some them up``() =
    [&quot;1,2&quot;; &quot;3,4&quot;; &quot;4,5&quot;]
    |&gt; List.map add
    |&gt; List.iter2 shouldBeEqualTo [3;7;9]

[&lt;Fact&gt;]
let ``When more than two digits are supplied separated by a comma it should be able to sum them up``() =
    [&quot;1,2,4,5&quot;; &quot;3,4,5&quot;; &quot;4,5,6,7,8&quot;]
    |&gt; List.map add
    |&gt; List.iter2 shouldBeEqualTo [12;12;30]

[&lt;Fact&gt;]
let ``When more than two digits are supplied separated by new line character be able to to sum them up``() =
    [&quot;1\n2\n4\n5&quot;; &quot;3\n4\n5&quot;; &quot;4\n5\n6\n7\n8&quot;]
    |&gt; List.map add
    |&gt; List.iter2 shouldBeEqualTo [12;12;30]

[&lt;Fact&gt;]
let ``When more than two digits are supplied separated by new line character or comma it should be able to some them up``() =
    [&quot;1,2\n4,5&quot;; &quot;3,4\n5&quot;; &quot;4,5\n6\n7\n8&quot;]
    |&gt; List.map add
    |&gt; List.iter2 shouldBeEqualTo [12;12;30]

[&lt;Fact&gt;]
let ``When more than two digits are supplied separated by a user supplied default delimiter it should be able to sum them up``() =
    [&quot;//*\n1*2*4*5&quot;; &quot;//$\n3$4$5&quot;; &quot;//%\n4%5%6%7%8&quot;]
    |&gt; List.map add
    |&gt; List.iter2 shouldBeEqualTo [12;12;30] 

[&lt;Fact&gt;]
let ``When more than two digits are supplied separated by a user supplied default delimiter or one of the standard delimiters it should be able to sum them up``() =
    [&quot;//*\n1*2*4*5&quot;; &quot;//$\n3$4$5&quot;; &quot;//%\n4\n5%6%7%8&quot;]
    |&gt; List.map add
    |&gt; List.iter2 shouldBeEqualTo [12;12;30]

[&lt;Fact&gt;]
let ``When digits greater than 1000 are supplied it should ignore them``() =
    [&quot;//*\n1*2000*4*5&quot;; &quot;//$\n3$4$1000&quot;]
    |&gt; List.map add
    |&gt; List.iter2 shouldBeEqualTo [10;7]

[&lt;Fact&gt;]
let ``When using more than two digits with with a custom separator of multiple characters ít should be able to sum them up``() =
    [&quot;//asdf\n1asdf4asdf5&quot;; &quot;//as\n3as4as&quot;]
    |&gt; List.map add
    |&gt; List.iter2 shouldBeEqualTo [10;7]
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.bjoernrochel.de/2010/05/12/kata-stringcalculator-in-f/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Kata FizzBuzz in F#</title>
		<link>http://www.bjoernrochel.de/2010/04/29/kata-fizzbuzz-in-f/</link>
		<comments>http://www.bjoernrochel.de/2010/04/29/kata-fizzbuzz-in-f/#comments</comments>
		<pubDate>Thu, 29 Apr 2010 18:00:00 +0000</pubDate>
		<dc:creator>BjRo</dc:creator>
				<category><![CDATA[F#]]></category>
		<category><![CDATA[F#; Code Kata ; FizzBuzz]]></category>

		<guid isPermaLink="false">http://www.bjoernrochel.de/?p=797</guid>
		<description><![CDATA[Last F# book club meeting in Munich was awesome (as usual). 2 weeks ago we decided to do a Code Kata on each subsequent meeting. This week was our first, with Kata FizzBuzz.
This is what we came up with. (BTW: Partial function application and pipelining rocks !!!)


open Xunit  

let fizzBuzz number =
   [...]]]></description>
			<content:encoded><![CDATA[<p>Last F# book club meeting in Munich was awesome (as usual). 2 weeks ago we decided to do a Code Kata on each subsequent meeting. This week was our first, with Kata FizzBuzz.</p>
<p>This is what we came up with. (BTW: Partial function application and pipelining rocks !!!)</p>
<pre class="brush: csharp">

open Xunit  

let fizzBuzz number =
     match number with
     | n when n%15=0 -&gt; &quot;FizzBuzz&quot;
     | n when n%3=0 -&gt; &quot;Fizz&quot;
     | n when n%5=0 -&gt; &quot;Buzz&quot;
     | _ -&gt; number.ToString()  

let areEqual expected actual =
     Assert.Equal(expected, actual)  

[&lt;Fact&gt;]
let Should_return_the_digit_for_numbers_which_are_not_dividable_by_3_or_5()  =
    [1;2;11;13;16]
    |&gt; List.map fizzBuzz
    |&gt; List.iter2 areEqual [&quot;1&quot;;&quot;2&quot;;&quot;11&quot;;&quot;13&quot;;&quot;16&quot;]  

[&lt;Fact&gt;]
let Should_return_Fizz_for_digits_dividable_by_3() =
    [3;6;9;12]
    |&gt; List.map fizzBuzz
    |&gt; List.iter (areEqual &quot;Fizz&quot;)

[&lt;Fact&gt;]
let Should_return_Buzz_for_digits_dividable_by_5() =
    [5;10;20;25]
    |&gt; List.map fizzBuzz
    |&gt; List.iter (areEqual &quot;Buzz&quot;)  

[&lt;Fact&gt;]
let Should_return_FizzBuzz_for_digits_dividable_by_3_and_5() =
    [15;30;45;60]
    |&gt; List.map fizzBuzz
    |&gt; List.iter (areEqual &quot;FizzBuzz&quot;)  
</pre>
<p>If anyone of you hardcore functional guys out there notices something utterly wrong or something that could radically simplified, please let me know. We’re eager to learn more.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bjoernrochel.de/2010/04/29/kata-fizzbuzz-in-f/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Testing F# code with xUnit.net (on .NET 4.0)</title>
		<link>http://www.bjoernrochel.de/2010/04/19/testing-f-code-with-xunit-net-on-net-4-0/</link>
		<comments>http://www.bjoernrochel.de/2010/04/19/testing-f-code-with-xunit-net-on-net-4-0/#comments</comments>
		<pubDate>Mon, 19 Apr 2010 07:48:46 +0000</pubDate>
		<dc:creator>BjRo</dc:creator>
				<category><![CDATA[Testing]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[xUnit]]></category>

		<guid isPermaLink="false">http://www.bjoernrochel.de/?p=784</guid>
		<description><![CDATA[A lot of my free time currently goes into learning F#. While I had a great time playing around with the F# REPL FSI, I came to the conclusion that using FSI is not my preferred way of a) learning the F# language and b) to develop code. Writing unit tests simply for the purpose [...]]]></description>
			<content:encoded><![CDATA[<p>A lot of my free time currently goes into learning F#. While I had a great time playing around with the F# REPL FSI, I came to the conclusion that using FSI is not my preferred way of a) learning the F# language and b) to develop code. Writing unit tests simply for the purpose of learning and understanding of a language/component/system (aka &quot;Learning tests&quot;) seems to be a better fit, at least for me. So, I sat down in order to see how I can use my beloved xUnit.net for this. As it turns out it&#8217;s not that difficult, but it&#8217;s got some hurdles. </p>
<p><strong>Possible runtime differences</strong> </p>
<p>xUnit.net 1.5 is compiled against the .Net Framework 3.5. If you&#8217;re using F# in combination with the VS2010 RC or RTM (like I do) you&#8217;ve got at least to options to make them work together. </p>
<ol>
<li>Use multi-targeting&#160; and configure the F# projects to compile for the .NET 3.5 runtime (Properties/Application/Target Framework). </li>
<li>Update the app.config files of xunit.console.exe and xunit.gui.exe with a startup section and specify the .NET framework 4.0 version as supported.
<pre class="brush: xml">

     &lt;startup&gt;
    	&lt;supportedRuntime version=&quot;v4.0.30128&quot; safemode=&quot;true&quot;/&gt; &lt;!-- VS2010 RC --&gt;
    	&lt;supportedRuntime version=&quot;v4.0.30319&quot; safemode=&quot;true&quot;/&gt; &lt;!-- VS2010 RTM --&gt;
     &lt;/startup&gt;
</pre>
</li>
</ol>
<p><strong>Pay attention to your parentheses</strong> </p>
<p>My choice was to update the xUnit.net configurations. After the update of the configuration files my assembly was loaded, however the test runner failed to detect my unit tests. As it turns out the open parentheses after a test function play an important role.</p>
<p><pre class="brush: csharp">
     [&lt;Fact&gt;]
     let After_converting_a_valid_data_row_the_title_should_have_been_extracted = //This compiles, but the test doesn&#039;t show up in the test runner.
        let row = convertDataRow &quot;Test, 1234&quot;
        Assert.Equal(fst(row), &quot;Test&quot;)

     [&lt;Fact&gt;]
     let After_converting_a_valid_data_row_the_title_should_have_been_extracted() = //This will work fine
        let row = convertDataRow &quot;Test, 1234&quot;
        Assert.Equal(fst(row), &quot;Test&quot;)
  </pre>
</p>
<p>My first reaction was: WTF? But after reading some more chapters of &quot;Real world functional programming&quot; and a discussion at our local F# book club the behavior makes sense to me. My current understanding is that omitting the parentheses results in a different method signature. You can easily spot this in FSI. The first one is <em>val After_converting_a_valid_data_row_the_title_should_have_been_extracted : unit</em> while the second one results in a <em>val After_converting_a_valid_data_row_the_title_should_have_been_extracted : unit -&gt; unit</em>. What you can see here is that the first function signature doesn&#8217;t have a parameter while the second has a parameter of the type unit. One interesting difference between F# and C# is that the F# equivalent to C#&#8217;s void is an actual type called unit. The fun part is that () is it&#8217;s only value. Parentheses play a completely different role here <img src='http://www.bjoernrochel.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  The xUnit test runner looks for methods with one unit parameter and a return type of unit. That&#8217;s why you need the parentheses. </p>
<p><strong>Testing exceptions with xUnit.Net</strong> </p>
<p>One little subtlety I came across when testing exceptions is that you have to explicitly &quot;ignore&quot; the return value when you&#8217;re using Assert.Throws and pass in a method which doesn&#8217;t return unit. Feels a bit strange at first, but explainable. Again a signature mismatch. Assert.Throws expects a method with a unit -&gt; unit signature. You have to do this in order to please the compiler. (If there&#8217;s a better way for this, please let me know) </p>
<p><pre class="brush: csharp">
    [&lt;Fact&gt;]
    let Trying_to_convert_an_invalid_format_throws() =
        Assert.Throws(fun () -&gt; convertDataRow &quot;FuBar&quot; |&gt; ignore)
  </pre>
</p>
<p>The ignore function simply throws away any value it receives, returns a unit and makes the F# compiler happy.</p>
<p><strong>Conclusion</strong> </p>
<p>I hope you saw in this post that testing F# with xUnit.net is actually pretty easy. It&#8217;s also a wonderful case for language interop on top of the CLR. Go see it for yourself <img src='http://www.bjoernrochel.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.bjoernrochel.de/2010/04/19/testing-f-code-with-xunit-net-on-net-4-0/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cutting the fluff from Service registration with StructureMap revisited</title>
		<link>http://www.bjoernrochel.de/2010/03/15/cutting-the-fluff-from-service-registration-with-structuremap-revisited/</link>
		<comments>http://www.bjoernrochel.de/2010/03/15/cutting-the-fluff-from-service-registration-with-structuremap-revisited/#comments</comments>
		<pubDate>Mon, 15 Mar 2010 20:28:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[StructureMap]]></category>

		<guid isPermaLink="false">http://www.bjoernrochel.de/?p=781</guid>
		<description><![CDATA[This is just a quick update of an older post of mine. Since StructureMap&#8217;s convention API has changed quite a bit, here is the updated version of the code used in the post using the new APIs introduced in StructureMap 2.5.4.
The new code is actually easier. It should look something like this . . . [...]]]></description>
			<content:encoded><![CDATA[<p>This is just a quick update of an <a href="http://www.bjoernrochel.de/2009/07/24/cutting-the-fluff-from-service-registration-or-how-to-do-funky-stuff-with-coc-castledynamicproxy-structuremap/">older post of mine</a>. Since StructureMap&#8217;s convention API has <a href="http://www.bjoernrochel.de/2010/01/05/changes-in-structuremap-254/ ">changed quite a bit</a>, here is the updated version of the code used in the post using the new APIs introduced in StructureMap 2.5.4.</p>
<p>The new code is actually easier. It should look something like this . . . . </p>
<pre class="brush: csharp">

    public class ServicesAreSingletonsAndProxies : IRegistrationConvention
    {
        #region IRegistrationConvention Members

        public void Process(Type type, Registry registry)
        {
            if (!type.IsConcrete() || !IsService(type) || !Constructor.HasConstructors(type))
            {
                return;
            }

            Type pluginType = FindPluginType(type);

            if (pluginType == null)
            {
                return;
            }

            registry
                .For(pluginType)
                .Singleton()
                .Use(new ConfiguredInstance(type)
                     {
                         Interceptor = new DynamicProxyInterceptor(pluginType)
                     });
        }

        #endregion

        private static bool IsService(Type type)
        {
            return type.Name.EndsWith(&quot;Service&quot;);
        }

        private static Type FindPluginType(Type concreteType)
        {
            string interfaceName = &quot;I&quot; + concreteType.Name;

            return concreteType
                .GetInterfaces()
                .Where(t =&gt; string.Equals(t.Name, interfaceName, StringComparison.Ordinal))
                .FirstOrDefault();
        }
    }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.bjoernrochel.de/2010/03/15/cutting-the-fluff-from-service-registration-with-structuremap-revisited/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Plain Old CLR / C# Object</title>
		<link>http://www.bjoernrochel.de/2010/02/25/plain-old-clr-c-object/</link>
		<comments>http://www.bjoernrochel.de/2010/02/25/plain-old-clr-c-object/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 19:51:37 +0000</pubDate>
		<dc:creator>BjRo</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[POCO]]></category>

		<guid isPermaLink="false">http://www.bjoernrochel.de/2010/02/25/plain-old-clr-c-object/</guid>
		<description><![CDATA[Crap, time can go by so fast. On Monday a tweet by Ralf Westphal caught my attention and I felt the need to comment. It started as a series of Twitter replies, but to be honest Twitter isn’t suited or made for those kind of discussions. So I started to write this post in order [...]]]></description>
			<content:encoded><![CDATA[<p>Crap, time can go by so fast. On Monday a <a href="http://twitter.com/ralfw/status/9446904971">tweet</a> by <strong>Ralf Westphal</strong> caught my attention and I felt the need to comment. It started as a series of Twitter replies, but to be honest Twitter isn’t suited or made for those kind of discussions. So I started to write this post in order to explain why I disagree with Ralf (or at least don’t get the intended message of his tweet). Yeah a short look into the calendar indicates that I’m a little late, but I thought better late than ditch the post and forget about it. </p>
<p><strong>What got me baffled</strong></p>
<p>In his tweet he basically states (my translation from German to English) that    </p>
<p><em>“If a domain model consists only of POCOs it should be called data model”</em></p>
<p>My first thought was a) does he mean anemic domain models and b) what has POCO to do with that? As I found out he didn’t mean <a href="http://twitter.com/ralfw/status/9493173442">anemic domain models</a>. So let’s take a look at the POCO aspect.</p>
<p><strong>POCO / POJO / PONO / POwhateverO</strong></p>
<p>The term exists in several variations and different programming languages. For the sake of simplicity I’m going to use POCO for the rest of the post since I’m a .NET guy, but same applies of course to all other versions. The English <a href="http://en.wikipedia.org/wiki/Plain_Old_CLR_Object">Wikipedia side</a> defines the term “Plain Old CLR Object” as the following:     </p>
<p>”… <em>The term is used to contrast a simple object with one that is designed to be used with a complicated, special object frameworks such as an </em><em>ORM</em><em> component. Another way to put it is that POCO&#8217;s are objects unencumbered with inheritance or attributes needed for specific frameworks …</em>”</p>
<p>To me personally, POCO is just a simple, but very important principle or guideline. POCO for me means, that you should strive to limit the contact area of your own code and the code of third party frameworks as much as possible. This includes staying away from third-party frameworks with heavy attribute usage and / or inheritance requirements. Why should you do this? 2 reasons seem to be important to me:</p>
<ul>
<li><strong>Orthogonality</strong>. Two parts of a system, like features, components, classes, whatever are called orthogonal when changes in one don’t affect the other. Following a POCO approach in a solution can greatly support orthogonality in my personal experience. It helps you to design and build solutions that are easy to change and very adaptable to new requirements or frameworks (Ever tried to migrate a Microsoft CAB based solution?). Which leads to the second IMHO very important aspect:      </li>
<li><strong>Reversibility</strong>. In the end of the day we’re all human. Sometimes we design the wrong way, sometimes the framework doesn’t work as expected, sometimes a particular framework isn’t exactly the right one any more when requirements change drastically. All those things happen. All those things can can come up in any project. POCO can help a lot in those situations, because it limits the impact of external frameworks or components to your code. </li>
</ul>
<p>POCO mostly comes up in the context of an ORM solution. However, the concept of POCO is not directly bound to persistence or even domain models. Which leads me back to the entry of the post and Ralfs tweet. What is the main distinction between a domain model and something we might call a data model? In my opinion this is BEHAVIOR. The term POCO itself has nothing to do with behavior itself (at least from my perspective). Totally different aspects IMHO. So why should a model consisting of POCOs be called data model?    </p>
<p>Am I fighting on lost ground here, missing something or confusing something?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bjoernrochel.de/2010/02/25/plain-old-clr-c-object/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Diving into the StoryTeller trunk, Part 11.3: Commands strike back</title>
		<link>http://www.bjoernrochel.de/2010/02/15/diving-into-the-storyteller-trunk-part-11-3-commands-strike-back/</link>
		<comments>http://www.bjoernrochel.de/2010/02/15/diving-into-the-storyteller-trunk-part-11-3-commands-strike-back/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 19:21:20 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[StoryTeller]]></category>

		<guid isPermaLink="false">http://www.bjoernrochel.de/?p=762</guid>
		<description><![CDATA[One of the things that can hit you really hard when writing blog posts about open source software (like StoryTeller is), is the fact that your posts tend to get very fast outdated, especially when you don&#8217;t pay that much attention to the detail (like I did, sigh). If you&#8217;re not aware of what I&#8217;m [...]]]></description>
			<content:encoded><![CDATA[<p>One of the things that can hit you really hard when writing blog posts about open source software (like StoryTeller is), is the fact that your posts tend to get very fast outdated, especially when you don&#8217;t pay that much attention to the detail (like I did, sigh). If you&#8217;re not aware of what I&#8217;m talking about, it&#8217;s StoryTellers command story. I&#8217;m not sure when it changed but it definitely has changed and I needed to update my last post (<a href="http://www.bjoernrochel.de/2010/01/09/diving-into-the-storyteller-trunk-part-11-2-more-on-commands/" target="_blank">11.2</a>) quite a bit in order to reflect the changes. Today I would like to conclude my trip through StoryTellers UI infrastructure with a look at how Commands are integrated into the Screen Activation Lifecycle.</p>
<p>Some of my older posts on the topic showed that the component responsible for Screen activation and deactivation in StoryTeller is the ScreenConductor. However, when the ScreenConductor activates or deactivates a Screen, it delegates a major part of work to the so called IShellService. The only implementer of this interface, the ShellService, is just a little facade around three things.</p>
<ol>
<li>The ICommandbar, which is the main toolbar of StoryTeller</li>
<li>the IOptionsMenu, which is a kind of Shortcut menu for StoryTellers Commands and</li>
<li>the IScreenObjectRegistry, which acts as a store  / front-end for the current Command registration.</li>
</ol>
<pre class="brush: csharp">

    public class ShellService : IShellService
    {
        private readonly ICommandBar _Commands;
        private readonly IOptionsMenu _options;
        private readonly IScreenObjectRegistry _registry;

        public ShellService(
              IScreenObjectRegistry registry,
              ICommandBar Commands,
              IOptionsMenu options)
        {
            _registry = registry;
            _Commands = Commands;
            _options = options;
        }

        #region IShellService Members

        public void ActivateScreen(IScreen screen)
        {
            _registry.ClearTransient();
            screen.Activate(_registry);
            refill();
        }

        public void ClearTransient()
        {
            _registry.ClearTransient();
            refill();
        }

        public void Start()
        {
            refill();
        }

        #endregion

        private void refill()
        {
            _Commands.Refill(_registry.Actions);
            _options.Refill(_registry.Actions);
        }
</pre>
<p>You can see some interesting aspects in the short code above.</p>
<ol>
<li>The word transient appears several times. StoryTeller differentiates between two types of Commands: Permanent Commands and transient Commands. Permanent Commands are displayed, well permanently, while transient Commands are what I depicted as contextual Commands. They are Commands which should be only visible in a particular context.
<p /></li>
<li>Contextualization of Commands is handled on a per Screen basis in StoryTeller. Every time a Screen gets activated or deactivated the ICommandBar and the IOptionsMenu get reset and completely rebuild. With this you can have a very different Command UI depending on which Screen is activated.
<p /></li>
<li>The actual Command configuration in the Screen Activation Lifecycle is completely delegated to the active Screen. In his Activate() method he receives a reference to the IScreenObjectRegistry which can be used in order to start the Command configuration via a small fluent API.
<p /></li>
</ol>
<pre class="brush: csharp">

    public interface IScreenObjectRegistry
    {
        //Gets a collection of all currently known command configurations
        IEnumerable&lt;ScreenAction&gt; Actions { get; }

        //Removes all transient command configurations from the registry
        void ClearTransient();

        //DSL starting point for the configuration of transient Commands
        IActionExpression Action(string name);

        //DSL starting point for the configuration of permanent Commands
        IActionExpression PermanentAction(string name);
    }
</pre>
<p>The following code snippet shows an example of how this API could be leveraged inside a Screen.</p>
<pre class="brush: csharp">

        public void Activate(IScreenObjectRegistry screenObjects)
        {
            screenObjects
                .Action(&quot;Save&quot;)
                .Bind(ModifierKeys.Control, Key.S)
                 .To(_save); //This can be either Systen.Action or an System.Windows.Input.ICommand

            screenObjects
                .Action(&quot;Cancel&quot;)
                .Bind(Key.Escape)
                .To(_cancel);
        }
</pre>
<p>Gabriel Schenker has <a href="http://www.lostechies.com/blogs/gabrielschenker/archive/2010/01/08/fluent-silverlight-table-of-content.aspx" target="_blank">written an excellent series on how to write such a fluent API</a>. Although it&#8217;s targeting Silverlight, most of the involved problems are explained in detail there, so forgive me if I don&#8217;t dive into the actual DSL implementation.</p>
<p><strong>Some final thoughts</strong></p>
<p>Making the Screen responsible for setting up his Commands makes a lot of sense to me, since the Screen is the unit which gets plugged into the UI infrastructure and it also very likely plays the role of the Command receiver in terms of the classic GoF pattern description. This doesn&#8217;t necessary mean that Screens are the only place for Command configuration. The initialization of modules in a Composite application is also a very likely place for registration of permanent Commands.</p>
<p>I consider having a fluent API for configuring the Commands also a plus, because it IMHO makes the actual Command configuration a lot easier and accessible. I&#8217;ve used the same setup (fluent API + delegation to screen) on my last 3 projects and it always worked for me like a charm.</p>
<p>Like I mentioned in the previous post, what I don&#8217;t like that much is the idea of mixing in visual aspects (Icon, Size, Location) into the Command configuration, mostly because I&#8217;ve been burned by this in the past when facing complex menus, like the ribbon. I think it&#8217;s a good idea to externalize the visual aspect via XML, at least for all the static stuff.</p>
<p><strong>This is it</strong></p>
<p>This was the last post about StoryTeller (at least for a while). It has been an interesting voyage which taught me a lot about UI infrastructure design, StructureMap usage and Convention over Configuration. Although it was primarily my learning excercise I hope you took something interesting with you from this blog series, too.</p>
<p>I&#8217;m going to continue my research on UI architecture with another deep dive into <a href="http://devlicio.us/blogs/rob_eisenberg/default.aspx" target="_blank">Rob Eisenbergs</a> <a href="http://www.codeplex.com/caliburn" target="_blank">Caliburn </a>soon. If your interested I would be very happy to have you with me on that trip . . .</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bjoernrochel.de/2010/02/15/diving-into-the-storyteller-trunk-part-11-3-commands-strike-back/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How to: Integrate a Topshelf based service with VS Setup projects</title>
		<link>http://www.bjoernrochel.de/2010/01/09/how-to-integrate-a-topshelf-based-service-with-vs-setup-projects/</link>
		<comments>http://www.bjoernrochel.de/2010/01/09/how-to-integrate-a-topshelf-based-service-with-vs-setup-projects/#comments</comments>
		<pubDate>Sat, 09 Jan 2010 19:40:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[Topshelf]]></category>
		<category><![CDATA[MSI]]></category>

		<guid isPermaLink="false">http://www.bjoernrochel.de/?p=749</guid>
		<description><![CDATA[We’ve recently started to migrate all of our Windows Services from a classic ServiceBase based approach to the hosting framework Topshelf. 
Previously we used the standard ServiceInstaller / ServiceProcessInstaller tandem to integrate our services with MSI deployment. This does not work with Topshelf (since Topshelf does the service installation itself via the Registry). However it’s [...]]]></description>
			<content:encoded><![CDATA[<p>We’ve recently started to migrate all of our Windows Services from a classic ServiceBase based approach to the hosting framework Topshelf. </p>
<p>Previously we used the standard ServiceInstaller / ServiceProcessInstaller tandem to integrate our services with MSI deployment. This does not work with Topshelf (since Topshelf does the service installation itself via the Registry). However it’s pretty easy to write a custom installer for that. You can do something like this:</p>
<pre class="brush: csharp">
    public class TopshelfInstaller : Installer
    {
        private const string AssemblyIdentifier = &quot;TopshelfAssembly&quot;;
        private const string InstallUtilAssemblyParameter = &quot;assemblypath&quot;;

        public override void Install(IDictionary stateSaver)
        {
            var topshelfAssembly = Context.Parameters[InstallUtilAssemblyParameter];
            stateSaver.Add(AssemblyIdentifier, topshelfAssembly);

            RunHidden(topshelfAssembly, &quot;/install&quot;);

            base.Install(stateSaver);
        }

        public override void Uninstall(IDictionary savedState)
        {
            var topshelfAssembly = savedState[AssemblyIdentifier].ToString();

            RunHidden(topshelfAssembly, &quot;/uninstall&quot;);

            base.Uninstall(savedState);
        }

        private static void RunHidden(string primaryOutputAssembly, string arguments)
        {
            var startInfo = new ProcessStartInfo(primaryOutputAssembly)
            {
                WindowStyle = ProcessWindowStyle.Hidden,
                Arguments = arguments
            };

            using (var process = Process.Start(startInfo))
            {
                process.WaitForExit();
            }
        }
    }
</pre>
<p>The interesting part is this line:</p>
<pre class="brush: csharp">
var topshelfAssembly = Context.Parameters[InstallUtilAssemblyParameter];
</pre>
<p>Took me some time to find this. During installation the Parameter Dictionary attached to the Context contains the full target filename of the assembly being installed (key is “assemblypath”). With this path you can directly launch the “/install” or “/uninstall” command for the Topshelf based exe.</p>
<p>HTH</p>
<p>P.S.:  <a href="http://devcity.net/Articles/339/3/article.aspx">This</a> resource pointed me in the right direction.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bjoernrochel.de/2010/01/09/how-to-integrate-a-topshelf-based-service-with-vs-setup-projects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Diving into the StoryTeller trunk, Part 11.2: More on Commands</title>
		<link>http://www.bjoernrochel.de/2010/01/09/diving-into-the-storyteller-trunk-part-11-2-more-on-commands/</link>
		<comments>http://www.bjoernrochel.de/2010/01/09/diving-into-the-storyteller-trunk-part-11-2-more-on-commands/#comments</comments>
		<pubDate>Sat, 09 Jan 2010 19:38:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[StoryTeller]]></category>

		<guid isPermaLink="false">http://www.bjoernrochel.de/?p=737</guid>
		<description><![CDATA[!!! Updated to current StoryTeller trunk on 15.02.2010 !!!
Let’s take a look at some of the questions I left unanswered in the last post.
Is the basic GoF Command pattern sufficient for a modern composite application?
The basic GoF Command pattern has no notion of visual state of a Command, such as (Is)Enabled or (Is)Visible. Its original [...]]]></description>
			<content:encoded><![CDATA[<p><strong>!!! Updated to current StoryTeller trunk on 15.02.2010 !!!</strong></p>
<p>Let’s take a look at some of the questions I left unanswered in the last post.</p>
<p><strong>Is the basic GoF Command pattern sufficient for a modern composite application?</strong></p>
<p>The basic GoF Command pattern has no notion of visual state of a Command, such as (Is)Enabled or (Is)Visible. Its original purpose was to encapsulate an action, so that it can be passed around and executed at some later point of time. Not more, not less.</p>
<pre class="brush: csharp">
interface ICommand
{
   void Execute();
}
</pre>
<p>Obviously real world desktop apps need something a bit more sophisticated. I’ve seen several infrastructures in my (not so old) career so far (home grown as well as OS alternatives), which extended this basic idea with at least one of those properties mentioned above.</p>
<p>Take for instance the P&amp;P Composite UI Application Block (now better known as part of the Smart Client Software Factory).  CAB implements a delegate based variation on the Command pattern. The delegate represents the action which is passed around. However, this delegate is managed by the Command class which has a notion of Status.</p>
<pre class="brush: csharp">
enum CommandStatus
{
    Enabled, //visible and enabled
    Disabled, //visible and disabled
    Unavailable //invisible
}
</pre>
<p>The WPF Command infrastructure version of the Command interface is more like the original pattern and adds the Enabled Property and an EnabledChangedEvent to the interface definition.</p>
<pre class="brush: csharp">
interface ICommand
{
    void Execute();
    bool Enabled {get;}
    event EventHandler EnabledChanged;
}
</pre>
<p>To be honest the Command interface <strong>never looked like the original GoF definition in ANY APPLICATION or project I’ve worked on so far</strong>. It always had a slight modification in one or another way.</p>
<p><strong>StoryTeller’s Command interface</strong></p>
<p>StoryTeller is a WPF based application, so naturally it gets the WPF Command infrastructure out of the box. However it composes the WPF ICommand into a StoryTeller specific structure, the IScreenAction.</p>
<pre class="brush: csharp">

public interface IScreenAction
{
     bool IsPermanent { get; set; }
     InputBinding Binding { get; set; }
     string Name { get; set; }
     Icon Icon { get; set; }
     ICommand Command { get; }
     bool ShortcutOnly { get; set; }
     void BuildButton(ICommandBar bar);
}
</pre>
<p>ScreenAction extends the capabilities of the original GoF-Pattern with a lot of metadata, mostly for visual aspects (Icon, Description). If you’re wondering why he included visual aspects: That basically tries to solve a reoccurring problem in composite apps:</p>
<p>In composite applications modules are not known at compile time to the infrastructure. Neither are all their capabilities and how they might be displayed in the infrastructure shell. Because of that, the infrastructure needs a dynamic, deferred way for doing the shells visual configuration at application startup.</p>
<p>One way to implement this is to delegate the responsibility for setting this up to the modules itself. This can be done during the module load time or every time a screen is displayed. This fits very well with the idea of the Open Closed Principle, since adding new modules/screens doesn’t require any reconfiguration/recompilation of other modules or the infrastructure. This is more or less the approach that StoryTeller takes.</p>
<p><strong>Some personal thoughts on IScreenAction</strong></p>
<p>I’ve worked on three applications in the past which followed down the same road. One thing I noticed throughout those three applications is that this approach isn’t really well suited when you’ve got strict and/or complex requirements about how the UI of an application should look. Let me clarify a bit what I mean:</p>
<ul>
<li> <strong>The Ordering Problem</strong>. Even if you organize tools representing commands in a simple toolbar (as StoryTeller does) you can very easily get into situations where the product owner wants to have the tools in a very specific order which is different to module load order,  some internal event order, whatever. I’ve encountered this several times now.
<p>First time we solved this by introducing a global constant class containing tool names. Very, very bad idea, do not repeat this. This introduces a kind of hidden temporal coupling, because now modules must be loaded in a particular order (so that a tool already exists to which we can refer by name).</p>
<p>StoryTellers take on this is a bit better (but IMHO not much). The Icon class has an Integer based Order property. All tools get sorted based on this property in StoryTellers CommandBar when it’s reloaded. This is less coupled, because it eliminates the temporal aspect of the coupling, but still has coupling.</li>
<li> <strong>API bloat with visual aspects</strong>. One area where I really started to find this approach annoying is when you stop having simple toolbars and start to use more complex menu types like for instance the Ribbon.  Taking the ribbon as an example: Now don’t have simply an ordering problem, but at minimum an icon problem (Normal icon vs. Quick Access Toolbar), a size problem (Displayed large or small) and a positioning problem (/Tab/Group/ElementGroup vs. /ApplicationMenu/Left).
<p>We added all those stuff to our Command registration and guess what, we weren’t happy with that. We created a monster API actually doing very little.</li>
</ul>
<p>So what do I (currently) prefer? Our current project (also using the Ribbon) completely strips the visual aspect of the Command. Our Command API looks very much like the WPF one, with the only addition of an Id property. The whole visual aspect is configured using an XML file which is loaded at application startup.</p>
<pre class="brush: xml">
&lt;Ribbon&gt;
   &lt;Tab&gt;
      &lt;Group&gt;
         &lt;Button imageId=”CancelIcon“ commandId=”CommandXYZ” /&gt;
      &lt;/Group&gt;
   &lt;/Tab&gt;
&lt;/Ribbon&gt;
</pre>
<p>I think you get the point. It works very well for our scope. (Slight warning though: This solution might not be the best in case you need to represent menu state based on dynamically loaded data).</p>
<p>See you next time for: Commands strike back <img src='http://www.bjoernrochel.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.bjoernrochel.de/2010/01/09/diving-into-the-storyteller-trunk-part-11-2-more-on-commands/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
