<?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:blogChannel="http://backend.userland.com/blogChannelModule" xmlns:dc="http://purl.org/dc/elements/1.1/" 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:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" version="2.0">
  <channel>
    <title>alcedo.com // software blog</title>
    <description>Occasional writing on software development by Fredrik Mörk</description>
    <link>http://softwareblog.alcedo.com/</link>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>BlogEngine.NET 1.6.0.0</generator>
    <language>en-GB</language>
    <blogChannel:blogRoll>http://softwareblog.alcedo.com/opml.axd</blogChannel:blogRoll>
    <blogChannel:blink>http://www.dotnetblogengine.net/syndication.axd</blogChannel:blink>
    <dc:creator>Fredrik Mörk</dc:creator>
    <dc:title>alcedo.com // software blog</dc:title>
    <geo:lat>0.000000</geo:lat>
    <geo:long>0.000000</geo:long>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/alcedo/software" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="alcedo/software" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
      <title>Who is concerned about the trigger?</title>
      <description>&lt;p&gt;If you have been reading some of the posts in my blog, you will know that sometimes I present a problem and a solution in an article which takes you through the thought process from making the first straightforward solution through refining that solution into a hopefully better code design. This is one of those posts.&lt;/p&gt;  &lt;p&gt;Let’s talk a bit about &lt;em&gt;separation of concerns&lt;/em&gt;. One scenario that I stumble upon fairly frequently when coding is the need for some code that should perform a task at a time based interval. This is nothing strange, and it is not very hard to achieve. But it still does present some challenges.&lt;/p&gt;  &lt;p&gt;In order to have a simple example, let’s say that we have a &lt;code&gt;TimeTeller&lt;/code&gt; class. It will, at a certain interval, tell us what time it is:&lt;/code&gt; &lt;/p&gt;  &lt;pre class="c#" name="code"&gt;var timeTeller = new TimeTeller(
    timeString =&amp;gt; Console.WriteLine(&amp;quot;The time is now {0}&amp;quot;, timeString))
{
    Interval = TimeSpan.FromSeconds(1)
};
timeTeller.Start();&lt;/pre&gt;

&lt;p&gt;It takes a callback method which will be called at the given interval, providing a string with the current time. Nice and simple. But it has two distinct drawbacks:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It’s not a very testable design, because of its asynchronous nature &lt;/li&gt;

  &lt;li&gt;The &lt;code&gt;TimeTeller&lt;/code&gt; class now has two concerns: telling time, and maintaining an interval mechanism &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;First, let’s look at a first implementation of the &lt;code&gt;TimeTeller&lt;/code&gt; class, as it is being used above:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;public class TimeTeller
{
    private readonly Action&amp;lt;string&amp;gt; timeStringCallback;
    private TimeSpan interval;
    private Timer timer;

    public TimeTeller(Action&amp;lt;string&amp;gt; timeStringCallback)
    {
        if (timeStringCallback == null) throw new ArgumentNullException(&amp;quot;timeStringCallback&amp;quot;);

        this.timeStringCallback = timeStringCallback;
    }

    public TimeSpan Interval
    {
        get
        {
            return interval;
        }
        set
        {
            interval = value;
            if (timer != null)
            {
                Start();
            }
        }
    }

    public void Start()
    {
        if (timer == null)
        {
            timer = new Timer(state =&amp;gt; TellTime());
        }

        timer.Change(Interval, Interval);
    }

    public void Stop()
    {
        if (timer != null)
        {
            timer.Dispose();
            timer = null;
        }
    }

    private void TellTime()
    {
        timeStringCallback(DateTime.Now.ToString(&amp;quot;HH:mm:ss&amp;quot;));
    }
}&lt;/pre&gt;

&lt;p&gt;As you can see, most of the code in the class is actually not about telling time, but rather about maintaining the interval using a &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx"&gt;Timer&lt;/a&gt;&lt;/code&gt;. In this code, telling time is more of a side effect than anything else. Also, if I would want to test this, it would involve some sort of waiting mechanism:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;using (AutoResetEvent waitHandle = new AutoResetEvent(false))
{
    var timeTeller = new TimeTeller(s =&amp;gt; { waitHandle.Set(); });
    timeTeller.Start();
    Assert.IsTrue(waitHandle.WaitOne(TimeSpan.FromSeconds(5)), &amp;quot;Callback method was not invoked.&amp;quot;);
}&lt;/pre&gt;

&lt;p&gt;This is not overly complicated, but as a test it has one flaw: it can fail for reasons that are not related to our code. If the build server happens to be under great pressure (or just very slow), perhaps the code is not executed as fast as we expect so the wait handle times out. Our code may be perfectly correct, but the test still fails. I am strongly of the opinion that tests should be designed in a way so they should fail only if there is something wrong with the code of the application, not because of anomalies in the surrounding environment.&lt;/p&gt;

&lt;p&gt;Now my code base has two problems. The test that is not optimal, and the fact that &lt;code&gt;TimeTeller&lt;/code&gt; violates the Single Responsibility Principle.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font style="background-color: #ffffff"&gt;In the &lt;a href="http://en.wikipedia.org/wiki/Single_responsibility_principle"&gt;Solid Responsibility Principle&lt;/a&gt;, a responsibility is sometimes described as a reason to change. The TimeTeller class in its current design may change for more than one reason: if we want to change how it is triggered, and if we want to change how it tells time.&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, first I want to remove the trigging mechanism from the &lt;code&gt;TimeTeller&lt;/code&gt; class. To do this, I design an &lt;code&gt;ITrigger&lt;/code&gt; interface:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;public interface ITrigger
{
    void RegisterAction(Action action);
    void UnregisterAction(Action action);
}&lt;/pre&gt;

&lt;p&gt;It’s extremely simple; I can register an &lt;code&gt;Action&lt;/code&gt; that will be invoked by the trigger, and I can unregister the &lt;code&gt;Action&lt;/code&gt;. Notice how this interface says nothing at all about &lt;em&gt;how&lt;/em&gt; the code will be trigged. From this point of view, that is of no importance. That is somebody else’s concern. Now I can refactor the &lt;code&gt;TimeTeller&lt;/code&gt; class to use an external trigger instead of maintaining its own trigging mechanism:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;public class TimeTeller
{
    private readonly Action&amp;lt;string&amp;gt; timeStringCallback;
    private readonly ITrigger trigger;

    public TimeTeller(Action&amp;lt;string&amp;gt; timeStringCallback, ITrigger trigger)
    {
        if (timeStringCallback == null) throw new ArgumentNullException(&amp;quot;timeStringCallback&amp;quot;);
        if (trigger == null) throw new ArgumentNullException(&amp;quot;trigger&amp;quot;);

        this.timeStringCallback = timeStringCallback;
        this.trigger = trigger;
    }

    public void Start()
    {
        trigger.RegisterAction(TellTime);
    }

    public void Stop()
    {
        trigger.UnregisterAction(TellTime);
    }

    private void TellTime()
    {
        timeStringCallback(DateTime.Now.ToString(&amp;quot;HH:mm:ss&amp;quot;));
    }
}&lt;/pre&gt;

&lt;p&gt;Notice how this class now has a much more focused design. There is a lot less code that is about &lt;em&gt;how&lt;/em&gt; to do stuff. Let’s say it has a lower &lt;em&gt;“how-to-what” ratio&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Great, but what about the trigger part? The code that I just ripped out of the &lt;code&gt;TimeTeller&lt;/code&gt; class needs to go somewhere, right? Right. I need to implement some sort of interval based trigger. Already at this point I realize that I will want to implement a couple of different triggers. I want the interval trigger to use with my &lt;code&gt;TimeTeller&lt;/code&gt; class. I will also want to make some sort of direct trigger that I can use to directly trig the functionality, which might be very useful in unit tests in order to “fake” the interval based trigging. So, I put the most basic stuff in a base class:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;public abstract class TriggerBase : ITrigger
{
    private Action action = () =&amp;gt; { };

    protected TriggerBase()
    {
        Enabled = true;
    }

    public bool Enabled { get; set; }

    public void RegisterAction(Action action)
    {
        this.action = (Action)Delegate.Combine(this.action, action);
    }

    public void UnregisterAction(Action action)
    {
        this.action = (Action)Delegate.Remove(this.action, action);
    }

    protected void TrigInternal()
    {
        if (Enabled)
        {
            action.Invoke();
        }
    }
}&lt;/pre&gt;

&lt;p&gt;This takes care of the bare necessities: it allows me to register and unregister &lt;code&gt;Action&lt;/code&gt; callbacks with the trigger, and have them invoked. Note that by using &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/30cyx32c.aspx"&gt;Delegate.Combine&lt;/a&gt;&lt;/code&gt; and &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.delegate.remove.aspx"&gt;Delegate.Remove&lt;/a&gt;&lt;/code&gt;, I can register multiple actions with the same trigger, which might be handy. Now, let’s extend the base class to make the interval trigger:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;public class IntervalTrigger : TriggerBase
{
    private TimeSpan interval;
    private Timer timer;

    public IntervalTrigger()
    {
        StartInterval();
    }

    public TimeSpan Interval
    {
        get
        {
            return interval;
        }
        set
        {
            interval = value;
            StartInterval();
        }
    }

    private void StartInterval()
    {
        if (timer == null)
        {
            timer = new Timer(state =&amp;gt; TrigInternal());
        }

        timer.Change(Interval, Interval);
    }

    private void StopInterval()
    {
        if (timer != null)
        {
            timer.Dispose();
        }
    }
}&lt;/pre&gt;

&lt;p&gt;You can see how the &lt;code&gt;IntervalTrigger&lt;/code&gt; implementation is very much like the code we removed from &lt;code&gt;TimeTeller&lt;/code&gt;. Now when we use the &lt;code&gt;TimeTeller&lt;/code&gt; class, we simply provide an &lt;code&gt;IntervalTrigger&lt;/code&gt; that will take care of calling into the &lt;code&gt;TimeTeller&lt;/code&gt; at the given interval:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;var timeTeller = new TimeTeller(
    timeString =&amp;gt; Console.WriteLine(&amp;quot;The time is now {0}&amp;quot;, timeString),
    new IntervalTrigger { Interval = TimeSpan.FromSeconds(1) });
timeTeller.Start();&lt;/pre&gt;

&lt;p&gt;Now that we have separated the concerns &lt;em&gt;how to call code at a given interval&lt;/em&gt; and &lt;em&gt;how to tell time&lt;/em&gt;, we also get a much nicer setup for testing. As I mentioned previously, I was planning to implement some sort of direct trigger that can be used for instance in tests:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;public class DirectTrigger : TriggerBase
{
    public void Trig()
    {
        TrigInternal();
    }
}&lt;/pre&gt;

&lt;p&gt;By passing a &lt;code&gt;DirectTrigger&lt;/code&gt; to &lt;code&gt;TimeTeller&lt;/code&gt;, I can now easily control exactly when it is being called into, and it is done in a synchronous manner. The asynchronous test above can be rewritten into a synchronous one instead:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;bool callbackWasInvoked = false;
var trigger = new DirectTrigger();
var timeTeller = new TimeTeller(s =&amp;gt; { callbackWasInvoked = true; }, trigger);
timeTeller.Start();
trigger.Trig();
Assert.IsTrue(callbackWasInvoked, &amp;quot;Callback method was not invoked.&amp;quot;);&lt;/pre&gt;

&lt;p&gt;This test is not time sensitive anymore, but will be very tolerant for slow build environments and such. &lt;/p&gt;

&lt;p&gt;One nice thing about having moved the whole trigging concern out of the &lt;code&gt;TimeTeller&lt;/code&gt; is that we can now allow the code to be trigged in new ways, without the &lt;code&gt;TimeTeller&lt;/code&gt; even knowing about it. I used this fact when rewriting the test for instance. But what if I suddenly got the requirement that the &lt;code&gt;TimeTeller&lt;/code&gt; should be able to tell time at a given interval, but there should also be a possibility to invoke it directly, at will. As it happens, this is now very easy to achieve. I just make a new &lt;code&gt;ITrigger&lt;/code&gt; implementation: &lt;/p&gt;

&lt;pre class="c#" name="code"&gt;public class CompositeTrigger : TriggerBase
{
    public CompositeTrigger(params ITrigger[] triggers)
    {
        foreach (ITrigger trigger in triggers)
        {
            Add(trigger);
        }
    }
    public void Add(ITrigger trigger)
    {
        trigger.RegisterAction(TrigInternal);
    }

    public void Remove(ITrigger trigger)
    {
        trigger.UnregisterAction(TrigInternal);
    }
}&lt;/pre&gt;

&lt;p&gt;This gives me the option to combine any triggers I want, and the &lt;code&gt;TimeTeller&lt;/code&gt; is still unaware:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;DirectTrigger directTrigger = new DirectTrigger();
IntervalTrigger intervalTrigger = new IntervalTrigger
	{
		Interval = TimeSpan.FromSeconds(5)
	};
CompositeTrigger trigger = new CompositeTrigger(directTrigger, intervalTrigger);
var timeTeller = new TimeTeller(s =&amp;gt; { callbackWasInvoked = true; }, trigger);&lt;/pre&gt;

&lt;p&gt;This will cause &lt;code&gt;TimeTeller&lt;/code&gt; will be invoked once every 5 seconds, and whenever any code calls &lt;code&gt;directTrigger.Trig()&lt;/code&gt;. In the sample project that I have linked to in the end there is also an &lt;code&gt;AsyncTrigger&lt;/code&gt; which is a flavor of the &lt;code&gt;DirectTrigger&lt;/code&gt; that will invoke the target callbacks on a separate thread, so that the calling code is not blocked.&lt;/p&gt;

&lt;p&gt;To sum it up, by separating concerns like this you will hopefully end up with a code design where both types and tests are more focused on their primary task. There will be more &lt;em&gt;what &lt;/em&gt;and less &lt;em&gt;how &lt;/em&gt;in the code.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://j.mp/XoMYYc"&gt;Download sample code from my BitBucket repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fsoftwareblog.alcedo.com%2fpost%2f2013%2f02%2f07%2fWho-is-concerned-about-the-trigger.aspx"&gt;&lt;img border="0" alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fsoftwareblog.alcedo.com%2fpost%2f2013%2f02%2f07%2fWho-is-concerned-about-the-trigger.aspx" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alcedo/software/~4/c3LnGPURPNc" height="1" width="1"/&gt;</description>
      <link>http://softwareblog.alcedo.com/post/2013/02/07/Who-is-concerned-about-the-trigger.aspx</link>
      <author>fredrik</author>
      <comments>http://softwareblog.alcedo.com/post/2013/02/07/Who-is-concerned-about-the-trigger.aspx#comment</comments>
      <guid>http://softwareblog.alcedo.com/post.aspx?id=9d2cab73-df00-4b55-ae76-11632d6a46aa</guid>
      <pubDate>Thu, 07 Feb 2013 07:00:00 +0200</pubDate>
      <dc:publisher>fredrik</dc:publisher>
      <pingback:server>http://softwareblog.alcedo.com/pingback.axd</pingback:server>
      <pingback:target>http://softwareblog.alcedo.com/post.aspx?id=9d2cab73-df00-4b55-ae76-11632d6a46aa</pingback:target>
      <slash:comments>3</slash:comments>
      <trackback:ping>http://softwareblog.alcedo.com/trackback.axd?id=9d2cab73-df00-4b55-ae76-11632d6a46aa</trackback:ping>
      <wfw:comment>http://softwareblog.alcedo.com/post/2013/02/07/Who-is-concerned-about-the-trigger.aspx#comment</wfw:comment>
      <wfw:commentRss>http://softwareblog.alcedo.com/syndication.axd?post=9d2cab73-df00-4b55-ae76-11632d6a46aa</wfw:commentRss>
    </item>
    <item>
      <title>This static thing, is it evil or not?</title>
      <description>&lt;p&gt;Say the word &lt;em&gt;static&lt;/em&gt; to a developer and see what happens. If nothing at all happens, you should be a little bit worried. As a bare minimum you should get some sort of reaction indicating caution. I keep bumping into scenarios where the presence of static doesn't really solve any problems, but instead just makes things harder.&lt;/p&gt;  &lt;p&gt;First, I would like to make it clear that, at least to me, static comes in two forms. Or, well, three forms to be more precise.&lt;/p&gt;  &lt;h2&gt;Static functions&lt;/h2&gt;  &lt;p&gt;There is something called a &lt;em&gt;pure function&lt;/em&gt;.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;A function is said to be pure if it always returns the same result for the same input, and if it has no observable side effects.&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;If the above statement is true it should not make any difference whether the function is static or not. Since it should return the exact same result every time for a given input, it can’t use any other data for its work, since any other data may mutate over time. In that sense, pure functions can just as well be made static. &lt;/p&gt;  &lt;p&gt;It's important to notice both criteria for a pure function: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Always returns the same result for the same input &lt;/li&gt;    &lt;li&gt;No side effects &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;As an example we can look at the &lt;code&gt;DateTime&lt;/code&gt; structure in .NET. It has some static methods and properties. If we look at &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.datetime.compare.aspx"&gt;DateTime.Compare&lt;/a&gt;&lt;/code&gt; we can see that it takes two &lt;code&gt;DateTime&lt;/code&gt; values as input, and returns a &lt;code&gt;boolean&lt;/code&gt;, indicating whether the two values represent the same instant in time or not. This method will always give the same result for the same input. If you pass in two &lt;code&gt;DateTime&lt;/code&gt; values that represent the same time, it will &lt;em&gt;always&lt;/em&gt; return &lt;code&gt;true&lt;/code&gt;. Also, it will have no side effects, it will not modify any state in your system, or in the objects passed to it.&lt;/p&gt;  &lt;p&gt;The property &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.datetime.utcnow.aspx"&gt;DateTime.UtcNow&lt;/a&gt;&lt;/code&gt; is also static, and will also not have any side effects by modifying anything. But it's not a pure function, since it will return a new value on each call (at least for the purpose of this discussion; in reality it may return the same value on several calls if they are done within a very short time frame). &lt;/p&gt;  &lt;p&gt;As we can conclude is that &lt;code&gt;DateTime.Compare&lt;/code&gt; can be easily tested while &lt;code&gt;DateTime.UtcNow&lt;/code&gt; cannot be easily tested.&lt;/p&gt;  &lt;h2&gt;Static state&lt;/h2&gt;  &lt;p&gt;If we move on to &lt;em&gt;static state&lt;/em&gt; we are talking about data that is shared by all code in a program, and with state it’s a completely different ball game. State is mutable. What one part of the system does, will affect other parts of the system. The results of various operations is “sticky”, it remains in the system.&lt;/p&gt;  &lt;p&gt;The one key area where I tend to come across the most trouble in relation to static state is when writing tests for software, and I like my tests. They help me sleep at night. Writing &lt;em&gt;reliable &lt;/em&gt;unit tests for software that has static state is &lt;em&gt;hard&lt;/em&gt;. If there is no way to mock that state away, it borders to the impossible. State from one test may “leak” to the next test being executed. A common sign of this is when you have a suite of tests where some tests fail when run as part of the suite, but pass when run separately.&lt;/p&gt;  &lt;p&gt;Introducing static state also has an effect on life-time management of objects, of course. It may very well be that for the system that you are making, there really should be only one instance of this data in one session. However, this is typically related to the life-time and scope management of the instances of that type, not to the functionality in the type itself.&lt;/p&gt;  &lt;p&gt;Also, when introducing static state you pretty much remove the possibility to run unit tests in parallel, since they will suddenly interfere with each other. &lt;/p&gt;  &lt;h2&gt;Design implications&lt;/h2&gt;  &lt;p&gt;When you decide to have a type with internal static state, you are making decisions for the user of that type that the user can’t do anything about. Consuming code is stuck to relate to the fact that there is static state in there. This may work well for a given scenario, but not in another. In this perspective, it’s obviously a lot more useful to &lt;strong&gt;not&lt;/strong&gt; make such decisions on behalf of the consuming code but instead leave that up to the consumer. If a static usage scenario fits the context then that option is still available to the consumer.&lt;/p&gt;  &lt;h2&gt;TL;DR&lt;/h2&gt;  &lt;p&gt;Please, please pretty please: with the exception of pure functions, &lt;em&gt;do &lt;strong&gt;not&lt;/strong&gt; make types or functions static unless it actually is the only way to solve your problem. It is much more likely to create problems than to solve one.&lt;/em&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alcedo/software/~4/tPtfgqn9Rq4" height="1" width="1"/&gt;</description>
      <link>http://softwareblog.alcedo.com/post/2012/12/11/This-static-thing-is-it-evil-or-not.aspx</link>
      <author>fredrik</author>
      <comments>http://softwareblog.alcedo.com/post/2012/12/11/This-static-thing-is-it-evil-or-not.aspx#comment</comments>
      <guid>http://softwareblog.alcedo.com/post.aspx?id=1510f941-34fd-4604-baad-c0f1bdced527</guid>
      <pubDate>Tue, 11 Dec 2012 08:27:00 +0200</pubDate>
      <dc:publisher>fredrik</dc:publisher>
      <pingback:server>http://softwareblog.alcedo.com/pingback.axd</pingback:server>
      <pingback:target>http://softwareblog.alcedo.com/post.aspx?id=1510f941-34fd-4604-baad-c0f1bdced527</pingback:target>
      <slash:comments>5</slash:comments>
      <trackback:ping>http://softwareblog.alcedo.com/trackback.axd?id=1510f941-34fd-4604-baad-c0f1bdced527</trackback:ping>
      <wfw:comment>http://softwareblog.alcedo.com/post/2012/12/11/This-static-thing-is-it-evil-or-not.aspx#comment</wfw:comment>
      <wfw:commentRss>http://softwareblog.alcedo.com/syndication.axd?post=1510f941-34fd-4604-baad-c0f1bdced527</wfw:commentRss>
    </item>
    <item>
      <title>Crashing the Visual Studio debugger using DebuggerDisplay</title>
      <description>&lt;p&gt;If you already know and use the &lt;code&gt;DebuggerDisplay&lt;/code&gt; you can &lt;a href="#howtocrashthedebugger"&gt;fast-forward to the evil stuff&lt;/a&gt;. Otherwise, keep reading to learn a new useful tool and also how not to use it.&lt;/p&gt;  &lt;h2&gt;Introduction to DebuggerDisplay&lt;/h2&gt;  &lt;p&gt;Let’s start with a quick demonstration of when and how &lt;code&gt;DebuggerDisplay&lt;/code&gt; is useful. Let’s say you have some code like this:&lt;/p&gt;  &lt;pre class="c#" name="code"&gt;public class Person
{
    public string Name { get; set; }
}

public class Employee : Person
{
    public string Department { get; set; }
}&lt;/pre&gt;

&lt;p&gt;Now, let’s say that you have a variable in your code that references an &lt;code&gt;IEnumerable&amp;lt;Employee&amp;gt;&lt;/code&gt;. If you watch that value using the debugger, it can look like this:&lt;/p&gt;

&lt;p&gt;&lt;img title="Employee list without DebuggerDisplay" alt="Employee list without DebuggerDisplay" src="http://softwareblog.alcedo.com/image.axd?picture=employee-list-without-debuggerdisplay.png" width="510" height="373" /&gt;&lt;/p&gt;

&lt;p&gt;We can see that there is a sequence of &lt;code&gt;Employee&lt;/code&gt; objects, but not much more. If we wanted to verify that there is an &lt;code&gt;Employee&lt;/code&gt; instance with the name “Sophie Jackson” we would need to expand each object to examine its &lt;code&gt;Name&lt;/code&gt; property which is a tedious task to say the least. This is where &lt;code&gt;DebuggerDisplay&lt;/code&gt; can help out. By decorating the &lt;code&gt;Employee&lt;/code&gt; class with the &lt;code&gt;DebuggerDisplay&lt;/code&gt; attribute, we can control how the debugger will display the object:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;[DebuggerDisplay(&amp;quot;Employee [Name = {Name}, Department = {Department}]&amp;quot;)]
public class Employee : Person
{
    public string Department { get; set; }
}&lt;/pre&gt;

&lt;p&gt;Now, if we check the value of the &lt;code&gt;employees&lt;/code&gt; variable as above, it will instead look like this:&lt;/p&gt;

&lt;p&gt;&lt;img title="Employee list with DebuggerDisplay" alt="Employee list with DebuggerDisplay" src="http://softwareblog.alcedo.com/image.axd?picture=employee-list-with-debuggerdisplay.png" width="510" height="373" /&gt;&lt;/p&gt;

&lt;p&gt;Now it’s obviously a lot easier to find the employee called “Sophie Jackson”. Just browse through the list and you will quickly see whether that &lt;code&gt;Employee&lt;/code&gt; instance is there or not.&lt;/p&gt;

&lt;h2&gt;More advanced usage&lt;/h2&gt;

&lt;p&gt;The debugger will evaluate the expression found in the &lt;code&gt;DebuggerDisplay&lt;/code&gt; attribute and show the value. Can this be used to do more complex things than to get a value from a property? Yes, it can. However, I urge you to resist the temptation to do fancy stuff here. The &lt;code&gt;DebuggerDisplay&lt;/code&gt; attribute can have unwanted side effects, as we will see further down in this article. Let’s look at an example:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;[DebuggerDisplay(&amp;quot;Employee [Name = {Name}, EmpYears = {((int)(System.DateTime.Now - EmploymentDate).TotalDays / 365)}]&amp;quot;)]
public class Employee : Person
{
	public string Department { get; set; }
	public DateTime EmploymentDate { get; set; }
}&lt;/pre&gt;

&lt;p&gt;Again, watching the &lt;code&gt;employees&lt;/code&gt; variable in the debugger:&lt;/p&gt;

&lt;p&gt;&lt;img title="Employee list with DebuggerDisplay expression" alt="Employee list with DebuggerDisplay expression" src="http://softwareblog.alcedo.com/image.axd?picture=employee-list-with-debuggerdisplay-expression.png" width="510" height="373" /&gt;&lt;/p&gt;

&lt;p&gt;You can see how each object is presented with a number that is calculated based on the difference between the current date and &lt;code&gt;EmploymentDate&lt;/code&gt;, converted to years and cast to an int.&lt;/p&gt;

&lt;p&gt;Now, while this is a very useful feature, it should be used with care. If we consume the class used in this example from code written in VB.NET this is what we get:&lt;/p&gt;

&lt;p&gt;&lt;img title="VB.NET cannot interpret C# expression" alt="VB.NET cannot interpret C# expression" src="http://softwareblog.alcedo.com/image.axd?picture=vbnet-cannot-interpret-csharp-expression.png" width="973" height="334" /&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the debugger now fails to evaluate the expression calculating the number of years. The reason is explained in the documentation:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Expressions are evaluated by the expression evaluator of the language of the current stack frame and not by the evaluator of the language in which the expression was written. This can cause unpredictable results when the languages are different.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So instead of the evaluated expression, you get an error message. The same happens if you for instance have a typo in the property name:&lt;/p&gt;

&lt;p&gt;&lt;img title="Employee list with misspelled property" alt="Employee list with misspelled property" src="http://softwareblog.alcedo.com/image.axd?picture=employee-list-with-misspelled-property.png" width="725" height="364" /&gt;&lt;/p&gt;

&lt;p&gt;As we can see, the &lt;code&gt;DebuggerDisplay&lt;/code&gt; attribute is very useful, but should be used to evaluate very simple and “cheap” values. Personally I only tend to use it to fetch values from property getters that just returns the value from a backing field with no other logic being involved. Above all, make sure to not have &lt;code&gt;DebuggerDisplay&lt;/code&gt; invoke any code that till mutate any state…&lt;/p&gt;

&lt;h2 id="howtocrashthedebugger"&gt;How DebuggerDisplay may crash your debugger&lt;/h2&gt;

&lt;p&gt;As we have seen from the above examples it’s not very hard to make the debugger fail to evaluate the expression in a &lt;code&gt;DebuggerDisplay&lt;/code&gt; attribute, but it does so in a nice and forgiving manner: it simply replaces the value placeholder with an error message instead of the evaluated expression. However, it is possible (even simple) to write an expression that instead will make you see this:&lt;/p&gt;

&lt;p&gt;&lt;img title="Employee list with crashed debugger" alt="Employee list with crashed debugger" src="http://softwareblog.alcedo.com/image.axd?picture=employee-list-with-crashed-debugger.png" width="416" height="301" /&gt;&lt;/p&gt;

&lt;p&gt;Now, that is not nice. I actually experience this in a project where this error started to appear among the developers and where we at first couldn’t identify what caused the environment to crash, since there (at first) were no obvious pattern of where the crash happened. After a while one of the team members found the offender. It was a &lt;code&gt;DebuggerDisplay&lt;/code&gt; attribute crafted like this:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;[DebuggerDisplay(&amp;quot;Employee [Name = {base.Name}, Department = {Department}]&amp;quot;)]
public class Employee : Person
{
    public string Department { get; set; }
    public DateTime EmploymentDate { get; set; }
}&lt;/pre&gt;

&lt;p&gt;Note the &lt;code&gt;base.Name&lt;/code&gt; construct. This is what caused the debugger to crash. I found this somewhat surprising (perhaps even to be considered a bug in the debugger?), especially since it works well to use the construct &lt;code&gt;this.Name&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fsoftwareblog.alcedo.com%2fpost%2f2012%2f12%2f04%2fCrashing-the-Visual-Studio-debugger-using-DebuggerDisplay.aspx"&gt;&lt;img border="0" alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fsoftwareblog.alcedo.com%2fpost%2f2012%2f12%2f04%2fCrashing-the-Visual-Studio-debugger-using-DebuggerDisplay.aspx" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alcedo/software/~4/hcGuUaIn57E" height="1" width="1"/&gt;</description>
      <link>http://softwareblog.alcedo.com/post/2012/12/04/Crashing-the-Visual-Studio-debugger-using-DebuggerDisplay.aspx</link>
      <author>fredrik</author>
      <comments>http://softwareblog.alcedo.com/post/2012/12/04/Crashing-the-Visual-Studio-debugger-using-DebuggerDisplay.aspx#comment</comments>
      <guid>http://softwareblog.alcedo.com/post.aspx?id=d3a459c3-588d-4b08-a089-8b216ab479ff</guid>
      <pubDate>Tue, 04 Dec 2012 21:48:04 +0200</pubDate>
      <dc:publisher>fredrik</dc:publisher>
      <pingback:server>http://softwareblog.alcedo.com/pingback.axd</pingback:server>
      <pingback:target>http://softwareblog.alcedo.com/post.aspx?id=d3a459c3-588d-4b08-a089-8b216ab479ff</pingback:target>
      <slash:comments>14</slash:comments>
      <trackback:ping>http://softwareblog.alcedo.com/trackback.axd?id=d3a459c3-588d-4b08-a089-8b216ab479ff</trackback:ping>
      <wfw:comment>http://softwareblog.alcedo.com/post/2012/12/04/Crashing-the-Visual-Studio-debugger-using-DebuggerDisplay.aspx#comment</wfw:comment>
      <wfw:commentRss>http://softwareblog.alcedo.com/syndication.axd?post=d3a459c3-588d-4b08-a089-8b216ab479ff</wfw:commentRss>
    </item>
    <item>
      <title>Øredev 2012, Day 2</title>
      <description>&lt;p&gt;The second day of &amp;Oslash;redev was started with a keynote by &lt;a href="http://weblog.raganwald.com/"&gt;Reginald Braithwaite&lt;/a&gt;, called &lt;em&gt;&amp;ldquo;The Rebellion Imperative&amp;rdquo;&lt;/em&gt;. With a very humble attitude, he delivered a talk with the main message that &lt;em&gt;&amp;ldquo;If Reg can make it up onto the stage of &amp;Oslash;redev, I can [fill in your own blanks]&amp;rdquo;&lt;/em&gt;. He talked about his own background, how he fell in love with coding (including programming in SNOBALL, which seems to be a &amp;hellip;peculiar language), and also discussing market dynamics, and what to do (and not to do) in order to be a rebellion on a market. &lt;a href="http://vimeo.com/53265664"&gt;Watch it on Vimeo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Then I went to listen to &lt;a href="http://damianedwards.wordpress.com/"&gt;Damian Edwards&lt;/a&gt; who talked (and demoed) how to make real-time web applications in ASP.NET using &lt;a href="https://github.com/SignalR/SignalR"&gt;SignalR&lt;/a&gt;. This is a very interesting library for building multi-user web applications where you want to enable users to get feedback in real-time based on what other users do. Apparently it scales very well and functions well in load-balanced scenarios as well. One thing that I really like with the SignalR team is their efforts in making clients available on varioys platforms, such as iOS and Android. (Video not online yet)&lt;/p&gt;
&lt;p&gt;The next person to take on the stage, in the same room as Damian, was &lt;a href="http://www.coderox.se/"&gt;Johan Lindfors&lt;/a&gt;. His topic was &lt;em&gt;&amp;ldquo;Windows Phone Development Best Practices&amp;rdquo;&lt;/em&gt; and he shared some insights both about tools and approaches based on personal experience. I got a few good tips on tools that I should look into, such as the &lt;a href="http://blogs.msdn.com/b/ptorr/archive/2010/10/30/that-memory-thing-i-promised-you.aspx"&gt;MemoryDiagnosticsHelper&lt;/a&gt; by &lt;a href="http://blogs.msdn.com/b/ptorr/"&gt;Peter Torr&lt;/a&gt;, which Johan also has made into a &lt;a href="http://nuget.org/packages/MemoryDiagnosticsHelper/1.0.2"&gt;Nuget package&lt;/a&gt;. (Video not online yet)&lt;/p&gt;
&lt;p&gt;After lunch I went on to listen to &lt;a href="http://blog.stevensanderson.com/"&gt;Steven Sanderson&lt;/a&gt;&amp;rsquo;s &lt;em&gt;&amp;ldquo;Build web apps much faster&amp;rdquo;&lt;/em&gt;. During the talk he built (using some pre-cooked code samples) a simple taxi booking web site using the static site generator making a static html/js frontend, and using &lt;a href="http://www.windowsazure.com/en-us/home/scenarios/mobile-services/"&gt;Azure Mobile Services&lt;/a&gt; for the backend. Mobile Services looks quite interesting, but one thing that bothered me was that js code for intercepting calls to the database (for transforming data before inserts for instance) was edited within the control panel in the web browser. This feels like code that I would definitely want to have under source control. That may very well be possible, but it was not demoed during this talk (or during demos of the feature in the Microsoft booth). (Video not online yet)&lt;/p&gt;
&lt;p&gt;After streak of rather techincal and relatively high-paced talks, I went on to listen to &lt;a href="http://www.billyhollis.com/"&gt;Billy Hollis&lt;/a&gt; talk about &lt;em&gt;&amp;ldquo;Interaction and Navigation Patterns for Modern User Experience&amp;rdquo;&lt;/em&gt;. This was mainly a walkthrough of various UX design approaches and their uses. &lt;a href="http://vimeo.com/53154352"&gt;Watch on Vimeo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A few weeks before the conference, Microsoft announced &lt;a href="http://www.typescriptlang.org/"&gt;TypeScript&lt;/a&gt;. They call it &amp;ldquo;a language for application-scale JavaScript development&amp;rdquo; and the aim is essentially to provide a developer experience than many experience with JavaScript. Mads Torgersen, one of the inventors of TypeScript (and also a member of the C# language team) gave a coding-based talk showing some of the features of the language and how it functions. He also pointed out the &lt;a href="http://www.typescriptlang.org/Playground/"&gt;TypeScript playground&lt;/a&gt;, where you can write TypeScript and having it translated to JavaScript in real-time, which seems like a great learning and exploration tool. &lt;a href="http://vimeo.com/53153273"&gt;Watch on Vimeo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The last regular session for the day that I went to was &lt;em&gt;&amp;ldquo;Rocking the Enterprise with the Kinect Experience&amp;rdquo;&lt;/em&gt; with &lt;a href="http://weblogs.asp.net/gsusx/default.aspx"&gt;Jesus Rodriguez&lt;/a&gt;. During his session he demonstrated how to work with the data streams from the Kinect device in order to let a user control a piece of software, and he also showed a couple of business application (mostly sales related) that used the Kinect for user input. Unfortunately the Kinect did not work flawlessly, but it was still a very interesting session where he also used members of the audience (such as myself) to help out with the demos. &lt;a href="http://vimeo.com/55017253"&gt;Watch on Vimeo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;After the dinner break it was time for an evening keynote, which was a talk by &lt;a href="http://alexanderbard.blogspot.se/"&gt;Alexander Bard&lt;/a&gt;. The title was &lt;em&gt;&amp;ldquo;The Rebels Come Out Online &amp;ndash; what if the Internet is something much bigger than we think?&amp;rdquo;&lt;/em&gt;. This was a very interesting and thought provoking talk, and probably the one talk during the conference that caused the largest amount of discussion afterwards. The talk was rooted in the ideas that has shaped the way we look at our history, suggesting that we are using the wrong perspective when looking at it, and ultimately arriving in what the Internet is doing to our society, and pointing towards the historical reasons for it to happen. &lt;a href="http://vimeo.com/55758949"&gt;Watch on Vimeo&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alcedo/software/~4/wfHNgv9UJxs" height="1" width="1"/&gt;</description>
      <link>http://softwareblog.alcedo.com/post/2012/11/11/c398redev-2012-Day-2.aspx</link>
      <author>Fredrik</author>
      <comments>http://softwareblog.alcedo.com/post/2012/11/11/c398redev-2012-Day-2.aspx#comment</comments>
      <guid>http://softwareblog.alcedo.com/post.aspx?id=d9d1b1a3-613f-4ea5-b3d7-95da5863eb36</guid>
      <pubDate>Sun, 11 Nov 2012 23:13:00 +0200</pubDate>
      <dc:publisher>Fredrik</dc:publisher>
      <pingback:server>http://softwareblog.alcedo.com/pingback.axd</pingback:server>
      <pingback:target>http://softwareblog.alcedo.com/post.aspx?id=d9d1b1a3-613f-4ea5-b3d7-95da5863eb36</pingback:target>
      <slash:comments>12</slash:comments>
      <trackback:ping>http://softwareblog.alcedo.com/trackback.axd?id=d9d1b1a3-613f-4ea5-b3d7-95da5863eb36</trackback:ping>
      <wfw:comment>http://softwareblog.alcedo.com/post/2012/11/11/c398redev-2012-Day-2.aspx#comment</wfw:comment>
      <wfw:commentRss>http://softwareblog.alcedo.com/syndication.axd?post=d9d1b1a3-613f-4ea5-b3d7-95da5863eb36</wfw:commentRss>
    </item>
    <item>
      <title>Øredev 2012, Day 1</title>
      <description>&lt;p&gt;This year I had the opportunity to attend Øredev all three conference days. I will post summary blog posts for each of the days, updating them with links to the session videos as they become available, which this year seems to happen very quickly. When writing this it’s Friday afternoon, the last keynote starts in about 30 minutes, and a good number of videos are already online.&lt;/p&gt;  &lt;p align="left"&gt;The day started off with a keynote by &lt;a href="http://www.davidrowan.com/"&gt;David Rowan&lt;/a&gt;, editor of the &lt;a href="http://www.wired.co.uk/news/david-rowans-blog"&gt;UK edition of Wired magazine&lt;/a&gt;. He was talking about how to use our skills as software developers to make the world a better place, bringing up a string of examples, such as &lt;a href="https://docs.google.com/a/alcedo.com/document/pub?id=1SGcfQz13ce4FfB-QHKF3WLwxHoCRGBouuvZn-3aoX0k"&gt;Hurricane Hackers&lt;/a&gt;, that amongst other things built a tool showing a live stream of the hurricane on a map (&lt;a href="http://www.huffingtonpost.com/2012/10/29/hurricane-hackers-brainstorm-storm-response_n_2039048.html"&gt;read more in Huffington Post&lt;/a&gt;). &lt;a href="http://vimeo.com/52995245"&gt;Watch the keynote on Vimeo&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Then I chose to attend &lt;a href="http://www.irisclasson.com/"&gt;Iris Classon&lt;/a&gt;'s talk. She gave an inspiring and thought provoking talk about software development from a newbie's perspective, and showing how more experienced developers have stuff to learn from the beginners. She also shared some result from studies on pair programming, where it had showed that pairs with two junior programmers or one junior and one senior performed better than a senior-senior pair. &lt;a href="http://vimeo.com/53276459"&gt;Watch on Vimeo&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;From Iris' talk it was a quite natural transition to go listen to &lt;a href="http://lisacrispin.com/"&gt;Lisa Crispin&lt;/a&gt; talking about how pairing adds value. She pointed out key gains such as how it helps us keep focus, how it leads to better solutions, how it helps us find errors quicker. She also pointed out that for pairing to work, everybody in the organization needs to understand the value, and how there must be a supportive culture around it. (session not online yet)&lt;/p&gt;  &lt;p&gt;From these sessions that were more wetware-focused, I went to listen to a more technical talk, where &lt;a href="http://www.galasoft.ch/"&gt;Laurent Bugnion&lt;/a&gt; shared some insights in working with the MVVM pattern in Windows Phone 8 and Windows 8. It was an interesting session that was mostly a coding demo (I tend to like those), showing how to solve things like having design time data in your views so that you can use graphical design tools such as Blend. &lt;a href="http://vimeo.com/53068482"&gt;Watch the session on Vimeo&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Laurent is the creator of MVVMLight, the MVVM framework that we used for &lt;a href="http://softwareblog.alcedo.com/post/2012/10/27/Announcing-the-Diversify-app-for-c398redev-2012.aspx"&gt;our Øredev app&lt;/a&gt;. In that app we had an issue with static viewmodels that we had solved, so we chatted with him afterwards about how he would have chosen to solve that, and it turned out that we had done it &amp;quot;the right way&amp;quot;. To our delight it also turned out that he used the app &lt;a href="https://twitter.com/LBugnion/status/266213422797049856"&gt;and was very happy with it&lt;/a&gt; &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://softwareblog.alcedo.com/image.axd?picture=wlEmoticon-smile_1.png" /&gt;&lt;/p&gt;  &lt;p&gt;Next in line was &lt;a href="http://www.ironshay.com/"&gt;Shay Friedman&lt;/a&gt; that had a talk called &lt;em&gt;“What?!? C# could do that???”&lt;/em&gt;. It was a talk that was mostly centered around tricks around using &lt;code&gt;dynamic&lt;/code&gt; in C#. &lt;a href="http://vimeo.com/53068486"&gt;Watch the session on Vimeo&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The last technical session for the day was &lt;em&gt;“Advanced RavenDB”&lt;/em&gt; with &lt;a href="http://ayende.com/blog"&gt;Ayende&lt;/a&gt;. I have played around a little (far too little) with RavenDB and find it very interesting, so it was very nice to get a slightly deeper introduction by its creator. A couple of nice features that stood out was the &lt;a href="http://ayende.com/blog/4680/ravendb-working-with-the-query-statistics"&gt;statistics&lt;/a&gt;, where where you can get the total count for a query, and a subset of the result (such as a page) in one roundtrip to the database, and &lt;a href="http://ayende.com/blog/4696/raven-suggest"&gt;the suggestions feature&lt;/a&gt;, where you can do more fuzzy searches (in order to handle slight misspellings). &lt;a href="http://vimeo.com/53068487"&gt;Watch the session on Vimeo&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The last thing that happened day one was the closing keynote by &lt;a href="http://www.mccarthyshow.com/"&gt;Jim McCarthy&lt;/a&gt;, titled &lt;em&gt;“Culture hacking and the coming era of magnificence”&lt;/em&gt;. It was quite a different experience from other keynote speeches that I have seen. Very passionate, bordering to preaching, but an interesting experience. &lt;a href="http://vimeo.com/53081836"&gt;Watch it on Vimeo&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alcedo/software/~4/7UEs5aEutF4" height="1" width="1"/&gt;</description>
      <link>http://softwareblog.alcedo.com/post/2012/11/09/c398redev-2012-Day-1.aspx</link>
      <author>fredrik</author>
      <comments>http://softwareblog.alcedo.com/post/2012/11/09/c398redev-2012-Day-1.aspx#comment</comments>
      <guid>http://softwareblog.alcedo.com/post.aspx?id=b808333f-bd34-4b7c-830e-86d514589807</guid>
      <pubDate>Fri, 09 Nov 2012 15:31:47 +0200</pubDate>
      <dc:publisher>fredrik</dc:publisher>
      <pingback:server>http://softwareblog.alcedo.com/pingback.axd</pingback:server>
      <pingback:target>http://softwareblog.alcedo.com/post.aspx?id=b808333f-bd34-4b7c-830e-86d514589807</pingback:target>
      <slash:comments>4</slash:comments>
      <trackback:ping>http://softwareblog.alcedo.com/trackback.axd?id=b808333f-bd34-4b7c-830e-86d514589807</trackback:ping>
      <wfw:comment>http://softwareblog.alcedo.com/post/2012/11/09/c398redev-2012-Day-1.aspx#comment</wfw:comment>
      <wfw:commentRss>http://softwareblog.alcedo.com/syndication.axd?post=b808333f-bd34-4b7c-830e-86d514589807</wfw:commentRss>
    </item>
    <item>
      <title>Announcing the Diversify app for Øredev 2012</title>
      <description>&lt;p&gt;Last spring when attending a Lean Coffee get-together in Malmö, I briefly spoke to &lt;a href="https://twitter.com/jakobklamra"&gt;Jakob Klamra&lt;/a&gt; (who is a member of the &lt;a href="http://oredev.org/2012"&gt;Øredev&lt;/a&gt; program committee) and asked him whether there were any thoughts on exposing the conference program data through some sort of API. He didn’t have any such information at the time. A few weeks ago, &lt;a href="http://oredev.org/2012/mobile"&gt;Øredev announced a competition&lt;/a&gt; where developers were invited to create mobile apps based on the conference data, now available in an XML file. I have no idea if those two events were related, but I like to think they are &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://softwareblog.alcedo.com/image.axd?picture=wlEmoticon-smile.png" /&gt;&lt;/p&gt;  &lt;p&gt;Either way, I found this to be a nice challenge, and pitched the idea to my colleagues, and soon a team was formed that happily started hacking away (hosting the code in a Mercurial repository on BitBucket, and also using Trello to have some sort of control of who was what, and what needed to be done). The team consisted of &lt;a href="https://twitter.com/__mattias__"&gt;Mattias Larsson&lt;/a&gt;, &lt;a href="https://twitter.com/micaelcarlstedt"&gt;Micael Carlstedt&lt;/a&gt;, &lt;a href="https://twitter.com/niclascarlstedt"&gt;Niclas Carlstedt&lt;/a&gt;, &lt;a href="https://twitter.com/markuswallen"&gt;Markus Wallén&lt;/a&gt;, &lt;a href="https://twitter.com/sebbe_bebbe"&gt;Sebastian Johansson&lt;/a&gt; and myself.&lt;/p&gt;  &lt;p&gt;The app is supposed to function as a companion before and during the conference. The main functionality is that it offers you to easily navigate and explore in the conference program, and build your own personalized conference program by “favoriting” sessions. It also features a twitter feed, listening to stuff related to the conference and the app. One focus of the design has been to allow you to explore. From almost every view, there is a way to move on and get information about related stuff. One example is when you are looking at a session, from this view you can in one touch navigate to&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;a page highlighting the room in which the session is on a map &lt;/li&gt;    &lt;li&gt;a page showing all sessions in that room during the conference &lt;/li&gt;    &lt;li&gt;a page showing details about the speaker (OK, this typically requires two interactions; scroll to the bottom of the page and then tap the speaker) &lt;/li&gt;    &lt;li&gt;a page showing details about each other session running in other rooms at the same time &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This may be the most extreme example, but it’s not unique in its concept.&lt;/p&gt;  &lt;p&gt;One other thing that the app does is that it invites to sharing information about the conference. You can (again with very few interactions) share info about a session or speaker to social networks.&lt;/p&gt;  &lt;p&gt;There is an update submitted to the market place which will add a couple of features (tell the app what days you will attend and it will filter the data throughout the app accordingly and, as a personal touch, the app authors’ suggestions for some sessions we find extra interesting). If you happen to have an unlocked developer phone, &lt;a href="http://j.mp/Pmu8Ct"&gt;you can grab the XAP file for that update here&lt;/a&gt;. Otherwise, go ahead and &lt;a href="http://j.mp/QUTbLo"&gt;get the app from the Windows Phone Marketplace&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Below you find a gallery with screenshots.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:66721397-FF69-4ca6-AEC4-17E6B3208830:00e326b0-502b-4868-b682-efa073ea219a" class="wlWriterEditableSmartContent"&gt;&lt;table border=0 cellspacing=0 cellpadding=0 style='outline:none;border-style:none;margin:0px;padding:0px;width:400px;border-collapse:collapse;' &gt;                     &lt;tr&gt;                        &lt;td colspan=2 style='outline:none;border-style:none;margin:0px;padding:5px 0px 5px 5px;width:157px;vertical-align:bottom;' &gt;                            &lt;a href="https://public.bay.livefilestore.com/y1pr6PcfmW2iqcxvAr06Kyz6bSi3EwD2A2GCTMiM4hVUCgZ2weH4RrMVnoERweg9TEcBLGPQ0FWjCpVLu08iH8D7g/1%20-%20splashscreen.png?psid=1" target="_blank" border="0" style="outline:none;border-style:none;margin:0px;padding:0px;"&gt;                                &lt;img style="outline:none;border-style:none;padding:0px;margin:0px;border:0px;background:none;background-image:none;vertical-align:bottom;" border="0" alt="View album" title="View album" width="157" height="157" src="http://softwareblog.alcedo.com/image.axd?picture=-210681046825BABC32.png" /&gt;&lt;/a&gt;                        &lt;/td&gt;                        &lt;td colspan=3 style='vertical-align:middle;margin:0px;padding:5px 5px 5px 0px;outline:none;border-style:none;width:223px' &gt;                            &lt;div style="margin-left:10px;top:-3%;" &gt;                                &lt;div style='width:223px;overflow:visible;'&gt;&lt;a style="text-decoration:none;" href="https://skydrive.live.com/redir.aspx?cid=f9ccba65913abf8d&amp;amp;page=browse&amp;amp;resid=F9CCBA65913ABF8D!1003&amp;amp;type=5&amp;amp;Bsrc=Photomail&amp;amp;Bpub=SDX.Photos" target="_blank"&gt;&lt;span  style="line-height:1.26em;padding:0px;width:223px;font-size:26pt;font-family:'Segoe UI', helvetica, arial, sans-serif;"  defaultText="Enter album name here"&gt;Diversify &amp;Oslash;redev 2012 App&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;                                &lt;div style="padding:10px 0px 0px 0px;margin:0px;"&gt;                                   &lt;table border=0 cellspacing=0 cellpadding=0 style="margin:0px;padding:0px;outline:none;border-style:none;border-collapse:collapse;width:auto;"&gt;                                        &lt;tr&gt;                                            &lt;td style="vertical-align:top;outline:none;border-style:none;margin:0px;padding:10px 15px 6px 0px;"&gt;&lt;a href="https://skydrive.live.com/redir.aspx?cid=f9ccba65913abf8d&amp;amp;page=play&amp;amp;resid=F9CCBA65913ABF8D!1003&amp;amp;type=5&amp;amp;Bsrc=Photomail&amp;amp;Bpub=SDX.Photos" border="0" target="_blank" style="font-family:'Segoe UI', helvetica, arial, sans-serif;font-size:8pt;outline:none;border-style:none;text-decoration: none;padding:0px;margin:0px;"&gt;VIEW SLIDE SHOW&lt;/a&gt;&lt;/td&gt;                                            &lt;td style="vertical-align:top;outline:none;border-style:none;margin:0px;padding:10px 0px 6px 0px;"&gt;&lt;a href="https://skydrive.live.com/redir.aspx?cid=f9ccba65913abf8d&amp;amp;page=downloadphotos&amp;amp;resid=F9CCBA65913ABF8D!1003&amp;amp;type=5&amp;amp;Bsrc=Photomail&amp;amp;Bpub=SDX.Photos" border="0" target="_blank" style="font-family:'Segoe UI', helvetica, arial, sans-serif;font-size:8pt;outline:none;border-style:none;text-decoration: none;padding:0px;margin:0px;"&gt;DOWNLOAD ALL&lt;/a&gt;&lt;/td&gt;                                        &lt;/tr&gt;                                                                           &lt;/table&gt;                                                                                                     &lt;/div&gt;                                                            &lt;/div&gt;                        &lt;/td&gt;                     &lt;/tr&gt;                    &lt;tr&gt;&lt;td style='vertical-align:bottom;outline:none;border-style:none;padding:0px 5px 5px 5px;margin:0px;width:76px;height:76px;' &gt;&lt;a href="https://public.bay.livefilestore.com/y1pceCvv6QyaC3bnueSXiZqBZFXH0tNJgPVoMFduAvSlj7GJQuCCJ8M91ijOnRW5hKzWGkaxTpyN-8H58bb-kF_kQ/6%20-%20twitter%20feed.png?psid=1" border="0" target="_blank" style="font-family:'Segoe UI', helvetica, arial, sans-serif;font-size:8pt;outline:none;border-style:none;text-decoration: none;padding:0px;margin:0px;"&gt;&lt;img style="outline:none;border-style:none;padding:0px;margin:0px;border:0px;background:none;background-image:none;vertical-align:bottom;" border="0" width="76" alt="View album" title="View album" height="76" src="http://softwareblog.alcedo.com/image.axd?picture=119776721613DE2865.png" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td style='vertical-align:bottom;outline:none;border-style:none;padding:0px 5px 5px 0px;margin:0px;width:76px;height:76px;' &gt;&lt;a href="https://public.bay.livefilestore.com/y1ph1uCBXrbkTKTARpMYDiGRZj2VlyDIAlnBfnjbN6qrmJa1XzDiIv1kdhTS8i6J6Frp5RD3ZnQaw7PlptDBhKecA/5%20-%20speaker%20detail.png?psid=1" border="0" target="_blank" style="font-family:'Segoe UI', helvetica, arial, sans-serif;font-size:8pt;outline:none;border-style:none;text-decoration: none;padding:0px;margin:0px;"&gt;&lt;img style="outline:none;border-style:none;padding:0px;margin:0px;border:0px;background:none;background-image:none;vertical-align:bottom;" border="0" width="76" alt="View album" title="View album" height="76" src="http://softwareblog.alcedo.com/image.axd?picture=-20948565577EECA5F1.png" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td style='vertical-align:bottom;outline:none;border-style:none;padding:0px 5px 5px 0px;margin:0px;width:76px;height:76px;' &gt;&lt;a href="https://public.bay.livefilestore.com/y1pcM1NtyVXW-fPLmK-icu_94ARiloQUfE_TBVWGqnQGxybgOCk8sOK5WfwjeJphd4VFFxrAwxY40sB79xj-cvtsg/8%20-%20about%20us.png?psid=1" border="0" target="_blank" style="font-family:'Segoe UI', helvetica, arial, sans-serif;font-size:8pt;outline:none;border-style:none;text-decoration: none;padding:0px;margin:0px;"&gt;&lt;img style="outline:none;border-style:none;padding:0px;margin:0px;border:0px;background:none;background-image:none;vertical-align:bottom;" border="0" width="76" alt="View album" title="View album" height="76" src="http://softwareblog.alcedo.com/image.axd?picture=7264049702CD9F8AA.png" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td style='vertical-align:bottom;outline:none;border-style:none;padding:0px 5px 5px 0px;margin:0px;width:76px;height:76px;' &gt;&lt;a href="https://public.bay.livefilestore.com/y1pT5jIyvi1gCE25EBUaEEUlDh3oRwT2VAle8wWI8uur5E7SmFPNRiBD4k4GsJWW1nu48hXKwiEGTJoxH9Y-n2C7A/4%20-%20session%20detail.png?psid=1" border="0" target="_blank" style="font-family:'Segoe UI', helvetica, arial, sans-serif;font-size:8pt;outline:none;border-style:none;text-decoration: none;padding:0px;margin:0px;"&gt;&lt;img style="outline:none;border-style:none;padding:0px;margin:0px;border:0px;background:none;background-image:none;vertical-align:bottom;" border="0" width="76" alt="View album" title="View album" height="76" src="http://softwareblog.alcedo.com/image.axd?picture=-134470865545D5C8EF.png" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td style='vertical-align:bottom;outline:none;border-style:none;padding:0px 5px 5px 0px;margin:0px;width:76px;height:76px;' &gt;&lt;a href="https://public.bay.livefilestore.com/y1pJijXXU51WgvgFVkMEXSvpcgvkvMbk2r2dlx_xezXvKjH-3MJ0_3iWujoGBDvlL7VApQfpfJHDtZGe0U4mKdkUQ/7%20-%20tweet%20detail.png?psid=1" border="0" target="_blank" style="font-family:'Segoe UI', helvetica, arial, sans-serif;font-size:8pt;outline:none;border-style:none;text-decoration: none;padding:0px;margin:0px;"&gt;&lt;img style="outline:none;border-style:none;padding:0px;margin:0px;border:0px;background:none;background-image:none;vertical-align:bottom;" border="0" width="76" alt="View album" title="View album" height="76" src="http://softwareblog.alcedo.com/image.axd?picture=153172488873C31BA7.png" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style='vertical-align:bottom;outline:none;border-style:none;padding:0px 5px 5px 5px;margin:0px;width:76px;height:76px;' &gt;&lt;a href="https://public.bay.livefilestore.com/y1pgf_jCKIfTo5lijm66_tNpWjsuLKrMf-aG0bE99oPTz8h_LThXfffQSvEMXf2m5BqoIis1Gyb9B6CEb95wRBOxA/3%20-%20list%20of%20sessions.png?psid=1" border="0" target="_blank" style="font-family:'Segoe UI', helvetica, arial, sans-serif;font-size:8pt;outline:none;border-style:none;text-decoration: none;padding:0px;margin:0px;"&gt;&lt;img style="outline:none;border-style:none;padding:0px;margin:0px;border:0px;background:none;background-image:none;vertical-align:bottom;" border="0" width="76" alt="View album" title="View album" height="76" src="http://softwareblog.alcedo.com/image.axd?picture=-5473710500CBEEBED.png" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td style='vertical-align:bottom;outline:none;border-style:none;padding:0px 5px 5px 0px;margin:0px;width:76px;height:76px;' &gt;&lt;a href="https://public.bay.livefilestore.com/y1p542Wrw-sp6N_c8bGOQlId_xexguoSy46warIrOhGy6sX98nbCpJoE6y24XUYxY6kosVKClRp9n30Z7lNHLETSw/2%20-%20my%20oredev.png?psid=1" border="0" target="_blank" style="font-family:'Segoe UI', helvetica, arial, sans-serif;font-size:8pt;outline:none;border-style:none;text-decoration: none;padding:0px;margin:0px;"&gt;&lt;img style="outline:none;border-style:none;padding:0px;margin:0px;border:0px;background:none;background-image:none;vertical-align:bottom;" border="0" width="76" alt="View album" title="View album" height="76" src="http://softwareblog.alcedo.com/image.axd?picture=-182461383677CD6979.png" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td style='vertical-align:bottom;outline:none;border-style:none;padding:0px 5px 5px 0px;margin:0px;width:76px;height:76px;' &gt;&amp;nbsp;&lt;/td&gt;&lt;td style='vertical-align:bottom;outline:none;border-style:none;padding:0px 5px 5px 0px;margin:0px;width:76px;height:76px;' &gt;&amp;nbsp;&lt;/td&gt;&lt;td style='vertical-align:bottom;outline:none;border-style:none;padding:0px 5px 5px 0px;margin:0px;width:76px;height:76px;' &gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/alcedo/software/~4/x9sZFzsd5LY" height="1" width="1"/&gt;</description>
      <link>http://softwareblog.alcedo.com/post/2012/10/27/Announcing-the-Diversify-app-for-c398redev-2012.aspx</link>
      <author>fredrik</author>
      <comments>http://softwareblog.alcedo.com/post/2012/10/27/Announcing-the-Diversify-app-for-c398redev-2012.aspx#comment</comments>
      <guid>http://softwareblog.alcedo.com/post.aspx?id=004aef21-3894-4ad0-a2f4-e17b0c9057db</guid>
      <pubDate>Sat, 27 Oct 2012 11:48:32 +0200</pubDate>
      <dc:publisher>fredrik</dc:publisher>
      <pingback:server>http://softwareblog.alcedo.com/pingback.axd</pingback:server>
      <pingback:target>http://softwareblog.alcedo.com/post.aspx?id=004aef21-3894-4ad0-a2f4-e17b0c9057db</pingback:target>
      <slash:comments>7</slash:comments>
      <trackback:ping>http://softwareblog.alcedo.com/trackback.axd?id=004aef21-3894-4ad0-a2f4-e17b0c9057db</trackback:ping>
      <wfw:comment>http://softwareblog.alcedo.com/post/2012/10/27/Announcing-the-Diversify-app-for-c398redev-2012.aspx#comment</wfw:comment>
      <wfw:commentRss>http://softwareblog.alcedo.com/syndication.axd?post=004aef21-3894-4ad0-a2f4-e17b0c9057db</wfw:commentRss>
    </item>
    <item>
      <title>Choose your assert with care</title>
      <description>&lt;p&gt;When you are writing unit tests in C#, regardless of what unit testing framework you are using there are a number of methods you can choose for performing your asserts. The most common ones are perhaps &lt;code&gt;Assert.AreEqual&lt;/code&gt;, &lt;code&gt;Assert.IsTrue&lt;/code&gt; and &lt;code&gt;Assert.IsFalse&lt;/code&gt; that are all present in both MS Test and NUnit (and probably others as well, but these two are were my main experience is, so I am primarily looking at those today).&lt;/p&gt;  &lt;p&gt;If you want to make an assert that a certain value meets a certain criteria, there are (at least) two ways of doing this. There is the &lt;code&gt;AreEqual&lt;/code&gt; way:&lt;/p&gt;  &lt;pre class="c#" name="code"&gt;[Test]
public void AssertAreEqual()
{
    IEnumerable&amp;lt;string&amp;gt; list = GetListOfStuff();
    Assert.AreEqual(4, list.Count());
}
&lt;/pre&gt;

&lt;p&gt;That's pretty straightforward, and the test will fail if &lt;code&gt;list.Count()&lt;/code&gt; return anything else than 4. Another approach is to use &lt;code&gt;IsTrue&lt;/code&gt;: &lt;/p&gt;

&lt;pre class="c#" name="code"&gt;[Test]
public void AssertIsTrue()
{
    IEnumerable&amp;lt;string&amp;gt; list = GetListOfStuff();
    Assert.IsTrue(list.Count() == 4);
}
&lt;/pre&gt;

&lt;p&gt;That will have pretty much the same effect. Apart from one big difference; this test will not tell you &lt;i&gt;in what way&lt;/i&gt; it failed. The test runner that you use will have less information about the fail for you in the second case. I will illustrate this with a couple of screenshots, showing how (the very excellent) &lt;a href="http://www.ncrunch.net/"&gt;NCrunch&lt;/a&gt; will visualize this: &lt;/p&gt;

&lt;p&gt;&lt;a href="http://softwareblog.alcedo.com/image.axd?picture=assert.areequal.ncrunch.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="assert.areequal.ncrunch" border="0" alt="assert.areequal.ncrunch" src="http://softwareblog.alcedo.com/image.axd?picture=assert.areequal.ncrunch_thumb.png" width="377" height="217" /&gt;&lt;/a&gt; 

  &lt;br /&gt;&lt;em&gt;NCrunch reporiting failed Assert.AreEqual&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://softwareblog.alcedo.com/image.axd?picture=assert.istrue.ncrunch.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="assert.istrue.ncrunch" border="0" alt="assert.istrue.ncrunch" src="http://softwareblog.alcedo.com/image.axd?picture=assert.istrue.ncrunch_thumb.png" width="376" height="214" /&gt;&lt;/a&gt; 

  &lt;br /&gt;&lt;em&gt;NCrunch reporting failed Assert.IsTrue&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As you can see, when using &lt;code&gt;AreEqual&lt;/code&gt;, the test runner is able to extract details about the failure, so that you can see the expected and actual values. When using &lt;code&gt;IsTrue&lt;/code&gt;, well, the expected value was &lt;code&gt;true&lt;/code&gt;, and the actual value was &lt;code&gt;false&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Here is a view of what Resharpers test runner makes of the tests. As you can see, you get the same information there.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://softwareblog.alcedo.com/image.axd?picture=asserts.in.nunit.runner.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="asserts.in.nunit.runner" border="0" alt="asserts.in.nunit.runner" src="http://softwareblog.alcedo.com/image.axd?picture=asserts.in.nunit.runner_thumb.png" width="632" height="352" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also note that NUnit’s &lt;code&gt;Assert.That&lt;/code&gt; will expose the same information as &lt;code&gt;Assert.AreEqual&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The bottom line is that choosing assert method is not only a matter about personal taste, it will also in a very concrete way affect the information that you get out of your failing tests. Use &lt;code&gt;Assert.IsTrue&lt;/code&gt; and &lt;code&gt;Assert.IsFalse&lt;/code&gt; only if you are actually verifying a boolean value (and no, &lt;code&gt;list.Count() == 4&lt;/code&gt; is not a boolean value in this context...).&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fsoftwareblog.alcedo.com%2fpost%2f2012%2f10%2f01%2fChoose-your-assert-with-care.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fsoftwareblog.alcedo.com%2fpost%2f2012%2f10%2f01%2fChoose-your-assert-with-care.aspx" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alcedo/software/~4/nbJ1hASFtG8" height="1" width="1"/&gt;</description>
      <link>http://softwareblog.alcedo.com/post/2012/10/01/Choose-your-assert-with-care.aspx</link>
      <author>fredrik</author>
      <comments>http://softwareblog.alcedo.com/post/2012/10/01/Choose-your-assert-with-care.aspx#comment</comments>
      <guid>http://softwareblog.alcedo.com/post.aspx?id=4b6b7386-6697-4bf3-b5e6-4171be67e96c</guid>
      <pubDate>Mon, 01 Oct 2012 22:38:09 +0200</pubDate>
      <dc:publisher>fredrik</dc:publisher>
      <pingback:server>http://softwareblog.alcedo.com/pingback.axd</pingback:server>
      <pingback:target>http://softwareblog.alcedo.com/post.aspx?id=4b6b7386-6697-4bf3-b5e6-4171be67e96c</pingback:target>
      <slash:comments>6</slash:comments>
      <trackback:ping>http://softwareblog.alcedo.com/trackback.axd?id=4b6b7386-6697-4bf3-b5e6-4171be67e96c</trackback:ping>
      <wfw:comment>http://softwareblog.alcedo.com/post/2012/10/01/Choose-your-assert-with-care.aspx#comment</wfw:comment>
      <wfw:commentRss>http://softwareblog.alcedo.com/syndication.axd?post=4b6b7386-6697-4bf3-b5e6-4171be67e96c</wfw:commentRss>
    </item>
    <item>
      <title>WIF and Colliding Namespaces</title>
      <description>&lt;p&gt;If you have worked some with Windows Identity Foundation you probably know that most of the types that you work with are found in the &lt;code&gt;Microsoft.IdentityModel.*&lt;/code&gt; namespaces. You have probably also noticed that more than a few of the type names in there are also used in corresponding locations in the &lt;code&gt;System.IdentityModel.*&lt;/code&gt; namespaces of the base class library. Examples of such type names are &lt;code&gt;Claim&lt;/code&gt; (in &lt;code&gt;Microsoft.IdentityModel.Claims&lt;/code&gt; and &lt;code&gt;System.IdentityModel.Claims&lt;/code&gt;) and &lt;code&gt;RequestSecurityToken&lt;/code&gt; (in &lt;code&gt;Microsoft.IdentityModel.Tokens&lt;/code&gt; and &lt;code&gt;System.IdentityModel.Tokens&lt;/code&gt;). Of course, these types are not replaceable with each other, so you need to make sure to reference the correct namespace when dealing with them. And that would not be so tricky if it was not for the fact that many of them also share some dependencies. &lt;/p&gt;  &lt;p&gt;For instance, let’s say you are working with &lt;code&gt;Saml2SecurityToken&lt;/code&gt; (found in &lt;code&gt;Microsoft.IdentityModel.Tokens.Saml2&lt;/code&gt;), it is derived from &lt;code&gt;SecurityToken&lt;/code&gt; (found in &lt;code&gt;System.IdentityModel.Tokens&lt;/code&gt;). In the same method, you need to use a &lt;code&gt;SecurityTokenDescriptor&lt;/code&gt;. Working with Windows Identity Foundation, more often than not you will want to use the counterpart found in the &lt;code&gt;Microsoft.IdentityModel.*&lt;/code&gt; namespaces rather than those found in &lt;code&gt;System.IdentityModel.*&lt;/code&gt;. To resolve this you will need to use namespace aliases. I have found that when using ReSharper to resolve this, it tends to import the &lt;code&gt;System.IndentityModel.*&lt;/code&gt; namespaces as usual, and set up aliases for the collisions in &lt;code&gt;Microsoft.IdentityModel.*&lt;/code&gt;:&lt;/p&gt;  &lt;pre class="c#" name="code"&gt;using System.IdentityModel.Tokens;
using SecurityTokenDescriptor = Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor;&lt;/pre&gt;

&lt;p&gt;I have also found that on a regular basis this is not very practical. For instance, quite a few of the types that you work with need to have aliases set up for them. In these cases I find it more practical to start off with manually setting up aliases for the few classes from the &lt;code&gt;System.IdentityModel.*&lt;/code&gt; that I want to use, and then have ReSharper resolve the others. Typically this results in a smaller number of regular &lt;code&gt;using&lt;/code&gt; directives.&lt;/p&gt;

&lt;p&gt;As an example, in one of my code files the following using directives:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;using System.IdentityModel.Tokens;
using Microsoft.IdentityModel.Claims;
using Saml2Attribute = Microsoft.IdentityModel.Tokens.Saml2.Saml2Attribute;
using Saml2AttributeStatement = Microsoft.IdentityModel.Tokens.Saml2.Saml2AttributeStatement;
using Saml2SecurityToken = Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityToken;
using SecurityTokenDescriptor = Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor;&lt;/pre&gt;

&lt;p&gt;...could be narrowed down to this:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;using Microsoft.IdentityModel.Claims;
using Microsoft.IdentityModel.Tokens;
using Microsoft.IdentityModel.Tokens.Saml2;
using SecurityToken = System.IdentityModel.Tokens.SecurityToken;&lt;/pre&gt;

&lt;p&gt;OK, perhaps not a huge difference, but that last one looks a lot less like a workaround than the first one, to me at least.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fsoftwareblog.alcedo.com%2fpost%2f2012%2f04%2f03%2fWIF-and-Colliding-Namespaces.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fsoftwareblog.alcedo.com%2fpost%2f2012%2f04%2f03%2fWIF-and-Colliding-Namespaces.aspx" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alcedo/software/~4/RJiNdJsNHB4" height="1" width="1"/&gt;</description>
      <link>http://softwareblog.alcedo.com/post/2012/04/03/WIF-and-Colliding-Namespaces.aspx</link>
      <author>fredrik</author>
      <comments>http://softwareblog.alcedo.com/post/2012/04/03/WIF-and-Colliding-Namespaces.aspx#comment</comments>
      <guid>http://softwareblog.alcedo.com/post.aspx?id=9ef2a8fd-ecd8-4778-ada8-aadd2fb07388</guid>
      <pubDate>Tue, 03 Apr 2012 12:59:13 +0200</pubDate>
      <dc:publisher>fredrik</dc:publisher>
      <pingback:server>http://softwareblog.alcedo.com/pingback.axd</pingback:server>
      <pingback:target>http://softwareblog.alcedo.com/post.aspx?id=9ef2a8fd-ecd8-4778-ada8-aadd2fb07388</pingback:target>
      <slash:comments>5</slash:comments>
      <trackback:ping>http://softwareblog.alcedo.com/trackback.axd?id=9ef2a8fd-ecd8-4778-ada8-aadd2fb07388</trackback:ping>
      <wfw:comment>http://softwareblog.alcedo.com/post/2012/04/03/WIF-and-Colliding-Namespaces.aspx#comment</wfw:comment>
      <wfw:commentRss>http://softwareblog.alcedo.com/syndication.axd?post=9ef2a8fd-ecd8-4778-ada8-aadd2fb07388</wfw:commentRss>
    </item>
    <item>
      <title>What is the value of definitions?</title>
      <description>Yesterday on Twitter, &lt;a href="http://twitter.com/Johannormen"&gt;Johan Normén&lt;/a&gt; drew my attention to a naming pattern for tests (&lt;a href="http://rockjohan.wordpress.com/2012/03/01/a-more-like-user-story-telling-unit-testing-pattern/"&gt;which he quickly published a blog post about&lt;/a&gt;, and where most credit should apparently go to &lt;a href="http://twitter.com/lowendahl"&gt;Patrik Löwendahl&lt;/a&gt;) that I found quite interesting. It was being compared to the naming convention that has previously been suggested by &lt;a href="http://twitter.com/RoyOsherove"&gt;Roy Osherove&lt;/a&gt; (&lt;a href="http://osherove.com/blog/2005/4/3/naming-standards-for-unit-tests.html"&gt;MethodName_StateUnderTest_ExpectedBehavior&lt;/a&gt;). The two naming conventions view the system under test from slightly different angles. While Roy's convention is &amp;quot;method based&amp;quot;, this other convention can be said to be more &amp;quot;scenario based&amp;quot;.   &lt;p&gt;As a side effect, this also sparked a little discussion regarding the definition of a unit test. And it made me think a little bit. Is this urge to have a definition interesting? Does it add value? The &lt;em&gt;intended&lt;/em&gt; value is probably that it can shorten communication a bit. I can say &lt;em&gt;&amp;quot;unit test&amp;quot;&lt;/em&gt;, and people I talk to will immediately know what I mean, have the same image of tests with a certain scope and level of isolation.&lt;/p&gt;  &lt;p&gt;But that's not how we function, is it? &lt;/p&gt;  &lt;p&gt;We can see this pattern all around, not only when discussing technicalities in code. &lt;a href="http://twitter.com/marcoarment"&gt;Marco Arment&lt;/a&gt; posted an article a couple of days ago called &amp;quot;&lt;a href="http://www.marco.org/2012/02/25/right-vs-pragmatic"&gt;Right versus pragmatic&lt;/a&gt;&amp;quot;, which highlighted how we often try to force &amp;quot;the right&amp;quot; way to do things on people, instead of observing &lt;em&gt;how they actually behave&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;I often feel that definitions like &amp;quot;unit tests&amp;quot; do the same thing. It doesn't matter if somewhere there is a definition saying that &amp;quot;&lt;em&gt;a bucket can be labeled &lt;strong&gt;unit test&lt;/strong&gt; only if it is not more than 50% full&lt;/em&gt;&amp;quot;. No matter how hard we try, different people will still fill different amounts of water into the bucket and stick a &amp;quot;unit test&amp;quot; label on it. &lt;/p&gt;  &lt;p&gt;Instead, I like to use a more pragmatic approach. The water in your bucket should not need any external connections. That's a good test. If you want to call it a &amp;quot;unit test&amp;quot;, feel free to do so. The only thing I am interested in, is &amp;quot;is this test well-designed?&amp;quot;. Sticking a label to it will not make it better or worse. It could, if all people could agree on one definition. In that case, this definition could contain characteristics for well-designed tests. But there will be no such agreement, because we are people. That's what we do. We absorb information, we apply our own experiences and preferences to it, and then we use it. What comes out will be different for different people.&lt;/p&gt;  &lt;p&gt;A definition is supposed to make communication simpler, faster, shorter and more clear. Instead I often see how it creates discussion about the definition itself. Instead of helping us focus more on the challenge at hand, the definition becomes a challenge in itself.&lt;/p&gt;  &lt;p&gt;So these definitions, do they not fill any purpose at all? Well, I think they do, but not they purpose the seem intended to fill. Instead of facilitate communication, I think that they facilitate thinking. They make us discuss, which forces us to think. Discussion and thinking creates and shares knowledge, and that adds value. But when I need things done, that’s not where they help me.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fsoftwareblog.alcedo.com%2fpost%2f2012%2f03%2f02%2fWhat-is-the-value-of-definitions.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fsoftwareblog.alcedo.com%2fpost%2f2012%2f03%2f02%2fWhat-is-the-value-of-definitions.aspx" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alcedo/software/~4/uv-DG73OFIg" height="1" width="1"/&gt;</description>
      <link>http://softwareblog.alcedo.com/post/2012/03/02/What-is-the-value-of-definitions.aspx</link>
      <author>fredrik</author>
      <comments>http://softwareblog.alcedo.com/post/2012/03/02/What-is-the-value-of-definitions.aspx#comment</comments>
      <guid>http://softwareblog.alcedo.com/post.aspx?id=5d206750-0569-4626-80ec-dca254855e1d</guid>
      <pubDate>Fri, 02 Mar 2012 07:40:00 +0200</pubDate>
      <dc:publisher>fredrik</dc:publisher>
      <pingback:server>http://softwareblog.alcedo.com/pingback.axd</pingback:server>
      <pingback:target>http://softwareblog.alcedo.com/post.aspx?id=5d206750-0569-4626-80ec-dca254855e1d</pingback:target>
      <slash:comments>5</slash:comments>
      <trackback:ping>http://softwareblog.alcedo.com/trackback.axd?id=5d206750-0569-4626-80ec-dca254855e1d</trackback:ping>
      <wfw:comment>http://softwareblog.alcedo.com/post/2012/03/02/What-is-the-value-of-definitions.aspx#comment</wfw:comment>
      <wfw:commentRss>http://softwareblog.alcedo.com/syndication.axd?post=5d206750-0569-4626-80ec-dca254855e1d</wfw:commentRss>
    </item>
    <item>
      <title>A somewhat messy date</title>
      <description>&lt;p&gt;Today's blog post is not about programming. Not directly anyway. Today I will talk about user experience. &lt;/p&gt;  &lt;p&gt;I &lt;em&gt;usually&lt;/em&gt; think that Google does pretty well when it comes to the user experience. Today however, I stumbled upon a surprising and rather irritating... um, feature. You know how you can limit the search results in time, so that you get results from the last 24 hours, last week, last month and so on? Well, I wanted to do the opposite. I wanted results that was approximately one year old, or older. Luckily, in the end of the timing choices, there is a &lt;em&gt;Custom range&lt;/em&gt; alternative. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://softwareblog.alcedo.com/image.axd?picture=02-fixed.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="02-fixed" border="0" alt="02-fixed" src="http://softwareblog.alcedo.com/image.axd?picture=02-fixed_thumb.png" width="866" height="610" /&gt;&lt;/a&gt;    &lt;br /&gt;&lt;em&gt;The options for limiting the search result in time.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;When you click on &lt;em&gt;Custom range&lt;/em&gt;, the page will show a couple of text boxes where you can type the dates the dates between which the search should be limited. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://softwareblog.alcedo.com/image.axd?picture=03.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="03" border="0" alt="03" src="http://softwareblog.alcedo.com/image.axd?picture=03_thumb.png" width="170" height="251" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now, as you may know, dates is a messy field. Here in Sweden we write dates in one way (which happens to conform to the ISO standard). In the US dates are written entirely differently. In France, they write dates like in the US, but they the month and day switch places. In short, when you give the use a text box for writing dates, the ice gets very thin.&lt;/p&gt;  &lt;p&gt;Google is obviously aware of this, so they provide an example of how they want you to write the date. Right above the &lt;em&gt;Search&lt;/em&gt; button they show you a date in the form that they want, and it happens to be in the US format. Note how the date is carefully chosen so that the French shall not be confused. It is obvious that the first number is the month and the second is the day, since there are only 12 months in a year.&lt;/p&gt;  &lt;p&gt;Great! So I put in the dates that interest me:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://softwareblog.alcedo.com/image.axd?picture=04.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="04" border="0" alt="04" src="http://softwareblog.alcedo.com/image.axd?picture=04_thumb.png" width="169" height="251" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;...and then I click the &lt;em&gt;Search&lt;/em&gt; button. Now it gets confusing. Google tells me that they dates I entered are not valid.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://softwareblog.alcedo.com/image.axd?picture=05.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="05" border="0" alt="05" src="http://softwareblog.alcedo.com/image.axd?picture=05_thumb.png" width="168" height="287" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;So, just to try it out, I enter dates &lt;em&gt;my&lt;/em&gt; way instead. I am after all using the Swedish Google site (even though I run it in English). &lt;/p&gt;  &lt;p&gt;&lt;a href="http://softwareblog.alcedo.com/image.axd?picture=06.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="06" border="0" alt="06" src="http://softwareblog.alcedo.com/image.axd?picture=06_thumb.png" width="171" height="293" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;And when I click Search, this is what I get:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://softwareblog.alcedo.com/image.axd?picture=07.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="07" border="0" alt="07" src="http://softwareblog.alcedo.com/image.axd?picture=07_thumb.png" width="869" height="607" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;It works out just fine! Now, notice how the dates that I typed into the text boxes has now been translated into the US date format. If I just click the &lt;em&gt;Search&lt;/em&gt; button again, I get the same error as before: that the dates are not valid. &lt;/p&gt;  &lt;p&gt;Not very intuitive.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alcedo/software/~4/6fPVSv6Yplw" height="1" width="1"/&gt;</description>
      <link>http://softwareblog.alcedo.com/post/2012/02/17/A-somewhat-messy-date.aspx</link>
      <author>fredrik</author>
      <comments>http://softwareblog.alcedo.com/post/2012/02/17/A-somewhat-messy-date.aspx#comment</comments>
      <guid>http://softwareblog.alcedo.com/post.aspx?id=bb820e0d-97ea-441d-a3b8-b107d454983b</guid>
      <pubDate>Fri, 17 Feb 2012 14:28:57 +0200</pubDate>
      <dc:publisher>fredrik</dc:publisher>
      <pingback:server>http://softwareblog.alcedo.com/pingback.axd</pingback:server>
      <pingback:target>http://softwareblog.alcedo.com/post.aspx?id=bb820e0d-97ea-441d-a3b8-b107d454983b</pingback:target>
      <slash:comments>4</slash:comments>
      <trackback:ping>http://softwareblog.alcedo.com/trackback.axd?id=bb820e0d-97ea-441d-a3b8-b107d454983b</trackback:ping>
      <wfw:comment>http://softwareblog.alcedo.com/post/2012/02/17/A-somewhat-messy-date.aspx#comment</wfw:comment>
      <wfw:commentRss>http://softwareblog.alcedo.com/syndication.axd?post=bb820e0d-97ea-441d-a3b8-b107d454983b</wfw:commentRss>
    </item>
  </channel>
</rss>
