<feed version="0.3" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns="http://purl.org/atom/ns#" xml:lang="en-US"><title>Daniel Cazzulino's Blog</title><link rel="alternate" type="text/html" href="http://www.clariusconsulting.net/blogs/kzu/default.aspx" /><tagline type="text/html">data wants to be free, and xml is the key</tagline><id>http://www.clariusconsulting.net/blogs/kzu/default.aspx</id><author><url>http://www.clariusconsulting.net/blogs/kzu/default.aspx</url></author><generator url="http://communityserver.org" version="1.0.1.50214">Community Server</generator><modified>2008-04-18T01:44:08Z</modified><entry><title>Donut Oriented Programming</title><link rel="alternate" type="text/html" href="http://www.clariusconsulting.net/blogs/kzu/archive/2008/07/24/DonutOrientedProgramming.aspx" /><id>e6de741d-39cb-46fc-b8ae-6ce6880bcef9:79265</id><created>2008-07-24T20:17:52Z</created><content type="text/html" mode="escaped">&lt;p&gt;&lt;strong&gt;Donut Oriented Programming&lt;/strong&gt;: DOP is a required discipline that you need to adhere to when your app will use VERY slow internet connection, such as in Cambodia and some other developing countries. Every action on the application that requires a roundrip to a server on the internet, should result in a donut being displayed to indicate that something is going on.&lt;/p&gt;&lt;img src="http://www.clariusconsulting.net/aggbug.aspx?PostID=79265" width="1" height="1"&gt;</content><slash:comments>0</slash:comments><wfw:commentRss>http://www.clariusconsulting.net/blogs/kzu/commentrss.aspx?PostID=79265</wfw:commentRss></entry><entry><title>The need for nullable reference types to advertise optional constructor dependencies</title><link rel="alternate" type="text/html" href="http://www.clariusconsulting.net/blogs/kzu/archive/2008/07/18/Theneedfornullablereferencetypestoadvertiseoptionalconstructordependencies.aspx" /><id>e6de741d-39cb-46fc-b8ae-6ce6880bcef9:78620</id><created>2008-07-18T02:42:44Z</created><content type="text/html" mode="escaped">&lt;p&gt;In "traditional" OOP, you advertise your class required dependencies via constructor arguments:&lt;/p&gt;&lt;pre&gt;public Foo(IOutput output, ILogger logger, ...)&lt;/pre&gt;
&lt;p&gt;Typically, the first few lines of code will check that these dependencies are not null. &lt;/p&gt;
&lt;p&gt;Optional dependencies may be provided as properties, which you can leave unset (null). &lt;/p&gt;
&lt;p&gt;Internally, in order to avoid a multitude of conditionals checking for nulls, you might have your own &lt;a href="http://en.wikipedia.org/wiki/Null_Object_pattern"&gt;"null" implementations&lt;/a&gt; of the dependencies' interfaces (i.e. NullLogger which does nothing). This way the code is more readable, and you can always assume the dependencies are non-null and you'll never get a NullReferenceException ;)&lt;/p&gt;
&lt;p&gt;One problem with property dependency injection is that you can't readily tell which properties are dependencies, and with constructor arguments, you cannot specify which ones are optional (can be passed null OK). &lt;/p&gt;
&lt;p&gt;I think a much more consistent approach, and one that would integrate very well with the &lt;a href="http://msdn.microsoft.com/en-us/library/1t3y8s4s.aspx"&gt;nullable value types&lt;/a&gt; functionality in .NET, is to introduce the concept of a nullable reference type:&lt;/p&gt;&lt;pre&gt;public Foo(IOutput output, ILogger? logger, ...)&lt;/pre&gt;
&lt;p&gt;What this tells the caller, is that the first argument is a required dependency, while the second can be null. I believe the .NET framework should go one step further and give the implementer a null implementation of the interface or abstract class if the argument is null. This way, you get rid of all nulls in your apps.&lt;/p&gt;
&lt;p&gt;You can also avoid depending on properties to advertise optional dependencies (and an associated custom attribute such as &lt;a href="http://blogs.msdn.com/kcwalina/archive/2008/04/25/MEF.aspx"&gt;MEF&lt;/a&gt; in order to indicate it's a dependency and not a regular property).&lt;/p&gt;&lt;img src="http://www.clariusconsulting.net/aggbug.aspx?PostID=78620" width="1" height="1"&gt;</content><slash:comments>1</slash:comments><wfw:commentRss>http://www.clariusconsulting.net/blogs/kzu/commentrss.aspx?PostID=78620</wfw:commentRss></entry><entry><title>Do you really care about Stub vs Mock?</title><link rel="alternate" type="text/html" href="http://www.clariusconsulting.net/blogs/kzu/archive/2008/07/05/77747.aspx" /><id>e6de741d-39cb-46fc-b8ae-6ce6880bcef9:77747</id><created>2008-07-05T11:49:48Z</created><content type="text/html" mode="escaped">&lt;p&gt;I've argued in the past that this &lt;a href="http://www.clariusconsulting.net/blogs/kzu/archive/2007/12/27/48594.aspx"&gt;theoretical discussion is utterly useless&lt;/a&gt;. In my experience you need slightly different things from your &lt;a href="http://www.martinfowler.com/bliki/TestDouble.html"&gt;test doubles&lt;/a&gt; at different times and depending on the scenarios and what you care about testing in a particular test. &lt;/p&gt; &lt;p&gt;If you're not using any mock/stub framework, you're typically creating manual test aids that morph (so that you can reuse them) as your tests evolve, and end up encompassing a mixture of a fake (i.e. you might put in an in-memory implementation), a stub (flags to tell you whether given members were called) and a mock (you might provide delegates to execute when members are executed, so that you can throw/callback/whatever). I've done this countless times before jumping to a framework/library to help me with this, and I know this is the &lt;a href="http://www.clariusconsulting.net/blogs/kzu/archive/2007/12/21/47152.aspx"&gt;continuum most developers live in&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Yet, we still see discussions like &lt;a href="http://www.ayende.com/Blog/archive/2008/06/29/Rhino-Mocks-3.5-Design-Decisions-The-role-of-Stub-vs.aspx"&gt;Rhino Mocks 3.5 Design Decisions: The role of Stub vs. Mock&lt;/a&gt;, were the user is asked to make a choice that he will seldom understand without reading the theoretical background. This is counter-productive IMO.&lt;/p&gt; &lt;p&gt;Compare the original two versions with &lt;a href="http://www.mockframeworks.com/moq"&gt;Moq&lt;/a&gt;'s version:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public void &lt;/span&gt;When_user_forgot_password_should_save_user()
{
    &lt;span style="color: blue"&gt;var &lt;/span&gt;userRepository = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;IUserRepository&lt;/span&gt;&amp;gt;();
    &lt;span style="color: blue"&gt;var &lt;/span&gt;smsSender = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;ISmsSender&lt;/span&gt;&amp;gt;();

    &lt;span style="color: blue"&gt;var &lt;/span&gt;theUser = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;User &lt;/span&gt;{ HashedPassword = &lt;span style="color: #a31515"&gt;"this is not hashed password" &lt;/span&gt;};

    userRepository.Expect(x =&amp;gt; x.GetUserByName(&lt;span style="color: #a31515"&gt;"ayende"&lt;/span&gt;)).Returns(theUser);

    &lt;span style="color: blue"&gt;var &lt;/span&gt;controllerUnderTest = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;LoginController&lt;/span&gt;(userRepository.Object, smsSender.Object);

    controllerUnderTest.ForgotMyPassword(&lt;span style="color: #a31515"&gt;"ayende"&lt;/span&gt;);

    userRepository.Verify(x =&amp;gt; x.Save(theUser));
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;As you see, the way you use the "mock" is what makes it look more like a stub or a "true" mock (i.e. you verify all expectations, and you create it with &lt;a href="http://www.clariusconsulting.net/labs/moq/html/90760C57.htm"&gt;MockBehavior.Strict&lt;/a&gt;). You don't have to pick a Stub vs Mock.&lt;/p&gt;
&lt;p&gt;This simplifies the learning curve on the framework, and basically allows you to set intuitive options that don't force you entirely in one way or the other (the combination of Expect...Verifiable...Verify allows for VERY flexible usage).&lt;/p&gt;
&lt;p&gt;I hope just like everyone's now seeing the value of NOT having an explicit record-reply model, we'll move past this rigid theoretical frame and into a more pragmatic and flexible view of mocking in general.&lt;/p&gt;&lt;img src="http://www.clariusconsulting.net/aggbug.aspx?PostID=77747" width="1" height="1"&gt;</content><slash:comments>1</slash:comments><wfw:commentRss>http://www.clariusconsulting.net/blogs/kzu/commentrss.aspx?PostID=77747</wfw:commentRss></entry><entry><title>Mocking protected members with Moq</title><link rel="alternate" type="text/html" href="http://www.clariusconsulting.net/blogs/kzu/archive/2008/07/05/MockingprotectedmemberswithMoq.aspx" /><id>e6de741d-39cb-46fc-b8ae-6ce6880bcef9:77737</id><created>2008-07-05T10:09:15Z</created><content type="text/html" mode="escaped">&lt;p&gt;If you're familiar with &lt;a href="http://www.mockframeworks.com/moq"&gt;Moq&lt;/a&gt;, you know that it relies on lambda expressions heavily. This is very good as you get full support from intellisense and refactoring features in Visual Studio. However, it also means you're for the most part restricted to setting expectations on things that your code has access too (public or internal members). &lt;/p&gt; &lt;p&gt;This is especially annoying with protected members, which are very common in template method pattern, factory methods, etc. In this case, you can't simply set an expectation with a lambda expression, as you have no access from the "outside" to the protected member. Being an important scenario, though, we wanted to add support for it.&lt;/p&gt; &lt;p&gt;We could have just extend the core Mock&amp;lt;T&amp;gt; API and add loosely-typed members that received strings (i.e. &lt;code&gt;mock.Expect("Foo")&lt;/code&gt;). This would have been bad from the guidance point of view, as it would make for an easy path to "hell" for people not familiar with lambda expression ("mmm... I could use this overload with that lambda thinghy, or just use the simpler string-based overload..."). We'd much rather keep people using strong-typed, lambda-based expectations rather than jumping at the ease of strings.&lt;/p&gt; &lt;p&gt;So, we reached a compromise: we implemented protected expectations using strings, but it will only work for non-public members :). We also didn't want to make this functionality too easy to discover, so we expose it as an extension method that you enable by importing the &lt;code&gt;Moq.Protected&lt;/code&gt; namespace:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;Moq.Protected;&lt;/pre&gt;
&lt;p&gt;then you use the &lt;code&gt;Protected&lt;/code&gt; "extension point":&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;mock = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;CommandBase&lt;/span&gt;&amp;gt;();
mock.Protected()
     .Expect&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515"&gt;"Execute"&lt;/span&gt;)
     .Returns(5);
&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;Expect&lt;/code&gt; overload receiving a type parameter specifies the return value from the invocation. You also have &lt;code&gt;ExpectGet/Set&lt;/code&gt; members, which expose the same functionality of the strong-typed lambda versions.&lt;/p&gt;
&lt;p&gt;Note how rather than polluting the main API with extension overloads receiving strings, we hang all members from the &lt;code&gt;IProtectedMock&lt;/code&gt; returned from the &lt;code&gt;Protected()&lt;/code&gt; method call. That's an interesting use of extension methods I think, which you also get to see quite a lot in newer C# 3.5 libraries such as &lt;a href="http://autofac.googlecode.com/"&gt;Autofac&lt;/a&gt; and &lt;a href="http://www.codeplex.com/umbrella"&gt;Umbrella&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Another difference in the invocation style for expectations is the argument matching. Here, I couldn't find an easier way to specify then than using a separate class, &lt;a href="http://www.clariusconsulting.net/labs/moq/html/169D5A34.htm"&gt;ItExpr&lt;/a&gt; to specify them:&lt;/p&gt;&lt;pre class="code"&gt;mock.Protected()
    .Expect&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515"&gt;"Execute"&lt;/span&gt;,
        &lt;span style="color: #2b91af"&gt;ItExpr&lt;/span&gt;.IsAny&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt;())
    .Returns(&lt;span style="color: blue"&gt;true&lt;/span&gt;);
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;The need for this is subtle, and lies in the fact that the Expect method is not receiving a lambda expression, unlike the strong-typed version, and the alternatives were far worse. So basically &lt;a href="http://www.clariusconsulting.net/labs/moq/html/169D5A34.htm"&gt;ItExpr&lt;/a&gt; is an expression-returning version of the &lt;a href="http://www.clariusconsulting.net/labs/moq/html/FBE0FFA5.htm"&gt;It&lt;/a&gt; class. I still haven't figured out how you would use custom matchers in this scenario. I guess it would involve building the expression trees just like we do to reconstruct the same expression that would result from using the matcher in the lambda Expect.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If you want to play with it, just go ahead and get the &lt;a href="http://code.google.com/p/moq/downloads/list"&gt;latest version from Google Code&lt;/a&gt;. 
&lt;p&gt;Don't forget to give us feedback through the &lt;a href="http://groups.google.com/group/moqdisc/"&gt;discussion list&lt;/a&gt; or &lt;a href="http://code.google.com/p/moq/issues/list"&gt;issue tracker&lt;/a&gt;.
&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://www.clariusconsulting.net/aggbug.aspx?PostID=77737" width="1" height="1"&gt;</content><slash:comments>2</slash:comments><wfw:commentRss>http://www.clariusconsulting.net/blogs/kzu/commentrss.aspx?PostID=77737</wfw:commentRss></entry><entry><title>Moq 2.5 shipped: lots of good news!</title><link rel="alternate" type="text/html" href="http://www.clariusconsulting.net/blogs/kzu/archive/2008/07/04/77643.aspx" /><id>e6de741d-39cb-46fc-b8ae-6ce6880bcef9:77643</id><created>2008-07-04T19:10:52Z</created><content type="text/html" mode="escaped">&lt;p&gt;Today we shipped Moq v2.5. It's been a while since RC1 (a month or so feels&amp;nbsp; so long for an open source agile project!) and we god very good feedback and suggestions for the final release. I'm pretty happy with the current drop and felt it was time for a new stable release. &lt;/p&gt; &lt;p&gt;The change log is quite extensive and yet there are quite a few fixes and improvements here and there that are not reflected in it. Over the next few posts I'll be showcasing the various new features. For now, here's the log:&lt;/p&gt; &lt;p&gt;Version 2.5&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Added support for mocking protected members  &lt;li&gt;Added new way of extending argument matchers which is now very straightforward  &lt;li&gt;Added support for mocking events  &lt;li&gt;Added support for firing events from expectations  &lt;li&gt;Removed usage of MBROs which caused inconsistencies in mocking features  &lt;li&gt;Added ExpectGet and ExpectSet to better support properties, and provide better intellisense.  &lt;li&gt;Added verification with expressions, which better supports Arrange-Act-Assert testing model (can do Verify(m =&amp;gt; m.Do(...)))  &lt;li&gt;Added Throws&amp;lt;TException&amp;gt;  &lt;li&gt;Added mock.CallBase property to specify whether the virtual members base implementation should be called  &lt;li&gt;Added support for implementing, setting expectations and verifying additional interfaces in the mock, via the new mock.As&amp;lt;TInterface&amp;gt;() method (thanks Fernando Simonazzi!)  &lt;li&gt;Improved argument type matching for Is/IsAny&amp;nbsp; (thanks Jeremy.Skinner!)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;My personal favorites: streamlined custom matchers (you can completely replace the built-in It.IsXXX matchers), mocking events and adding interfaces to a mock (I'll expand on those soon).&lt;/p&gt; &lt;p&gt;Go ahead and get the &lt;a href="http://code.google.com/p/moq/downloads/list"&gt;latest version from Google Code&lt;/a&gt;. &lt;/p&gt; &lt;p&gt;As usual, we'd love to hear your feedback at the &lt;a href="http://groups.google.com/group/moqdisc/"&gt;discussion list&lt;/a&gt; or &lt;a href="http://code.google.com/p/moq/issues/list"&gt;issue tracker&lt;/a&gt;, and patches are always welcome :)&lt;/p&gt;&lt;img src="http://www.clariusconsulting.net/aggbug.aspx?PostID=77643" width="1" height="1"&gt;</content><slash:comments>2</slash:comments><wfw:commentRss>http://www.clariusconsulting.net/blogs/kzu/commentrss.aspx?PostID=77643</wfw:commentRss></entry><entry><title>Cool ajax loader image generator</title><link rel="alternate" type="text/html" href="http://www.clariusconsulting.net/blogs/kzu/archive/2008/07/03/Coolajaxloaderimagegenerator.aspx" /><id>e6de741d-39cb-46fc-b8ae-6ce6880bcef9:77392</id><created>2008-07-03T10:58:13Z</created><content type="text/html" mode="escaped">&lt;p&gt;Just found (via &lt;a href="http://weblogs.manas.com.ar/bcardiff/"&gt;Brian&lt;/a&gt;) about this cool site to &lt;a href="http://www.ajaxload.info/"&gt;generate ajax-like loading donnuts&lt;/a&gt; like this one:&lt;/p&gt; &lt;p&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" alt="ajax-loader" src="http://www.clariusconsulting.net/images/blogs/kzu/Coolajaxloaderimagegenerator_D293/ajaxloader.gif"&gt;&lt;/p&gt;&lt;img src="http://www.clariusconsulting.net/aggbug.aspx?PostID=77392" width="1" height="1"&gt;</content><slash:comments>1</slash:comments><wfw:commentRss>http://www.clariusconsulting.net/blogs/kzu/commentrss.aspx?PostID=77392</wfw:commentRss></entry><entry><title>June 18-2008 can be a great day for the Web</title><link rel="alternate" type="text/html" href="http://www.clariusconsulting.net/blogs/kzu/archive/2008/06/17/74687.aspx" /><id>e6de741d-39cb-46fc-b8ae-6ce6880bcef9:74687</id><created>2008-06-17T20:54:59Z</created><content type="text/html" mode="escaped">&lt;p&gt;&lt;a href="http://www.spreadfirefox.com/en-US/worldrecord/"&gt;And you can be part of it&lt;/a&gt;. The latest and greatest browser ever can make history and &lt;a href="http://www.spreadfirefox.com/en-US/worldrecord/"&gt;you can help&lt;/a&gt;!&lt;/p&gt;&lt;img src="http://www.clariusconsulting.net/aggbug.aspx?PostID=74687" width="1" height="1"&gt;</content><slash:comments>0</slash:comments><wfw:commentRss>http://www.clariusconsulting.net/blogs/kzu/commentrss.aspx?PostID=74687</wfw:commentRss></entry><entry><title>VS2008 SP1 Beta: DON'T install without first backing up your settings!</title><link rel="alternate" type="text/html" href="http://www.clariusconsulting.net/blogs/kzu/archive/2008/06/05/73321.aspx" /><id>e6de741d-39cb-46fc-b8ae-6ce6880bcef9:73321</id><created>2008-06-05T07:21:13Z</created><content type="text/html" mode="escaped">&lt;p&gt;I lost them all in the process :((((&lt;/p&gt;&lt;img src="http://www.clariusconsulting.net/aggbug.aspx?PostID=73321" width="1" height="1"&gt;</content><slash:comments>1</slash:comments><wfw:commentRss>http://www.clariusconsulting.net/blogs/kzu/commentrss.aspx?PostID=73321</wfw:commentRss></entry><entry><title>Mesh synchronization of KML files through FeedSync</title><link rel="alternate" type="text/html" href="http://www.clariusconsulting.net/blogs/kzu/archive/2008/05/28/MeshsynchronizationofKMLfilesthroughFeedSync.aspx" /><id>e6de741d-39cb-46fc-b8ae-6ce6880bcef9:70812</id><created>2008-05-28T14:14:23Z</created><content type="text/html" mode="escaped">
		&lt;p&gt;We've been working for the past few days on a &lt;a href="http://mesh4x.org"&gt;mesh4x&lt;/a&gt; adapter that can synchronize a potentially big KML file at a very granular level (styles, placemarks, folders, etc.) so that you can collaboratively edit these large files without having to resolve spurious "conflicts".&lt;/p&gt;
		&lt;p&gt;From &lt;a href="http://edjez.instedd.org/2008/05/build-maps-collaboratively-with-new.html"&gt;Ed's blog post&lt;/a&gt;: &lt;/p&gt;
		&lt;blockquote&gt;
				&lt;p&gt;This could be synchronized peer-to-peer (a KML on your disk to a KML on a USB drive or someone else's box) as well as via a 'cloud' web service. Note this is changing the data inside the KML, it is &lt;strong&gt;not just 'file sharing'&lt;/strong&gt;. The adapter knows about KML and keeps track of versions of fine-grained elements (pushpins, placemarks, polygons) inside the same file. It is an example of how a data mesh could be used to synchronize fine-grained data between applications.&lt;/p&gt;
		&lt;/blockquote&gt;
		&lt;p&gt;
				&lt;b&gt;Update&lt;/b&gt;: Read more &lt;a href="http://feeds.feedburner.com/%7Er/edjez/%7E3/297090861/improvements-to-mesh4x-kml-adapter.html"&gt;about the latest version&lt;/a&gt; (including single-file storage, KMZ support, etc.).&lt;br /&gt;&lt;/p&gt;
		&lt;p&gt;I believe this is one of the first instances of a mesh-style synchronization that really proves the point and possibilities of &lt;a href="http://feedsync.org"&gt;FeedSync&lt;/a&gt; and also &lt;a href="http://mesh.com"&gt;Live Mesh&lt;/a&gt;. Something that &lt;a href="http://www.joelonsoftware.com/items/2008/05/01.html"&gt;Joel Spolsky clearly didn't get&lt;/a&gt;.&lt;/p&gt;
		&lt;p&gt;This technology is going to change the way we think about applications, data ownership and sharing. It's actually a pity that some people is focusing on the one *&lt;strong&gt;sample&lt;/strong&gt;* application that Microsoft is showing (file/folder sharing) to evaluate it.&lt;/p&gt;&lt;img src="http://www.clariusconsulting.net/aggbug.aspx?PostID=70812" width="1" height="1"&gt;</content><slash:comments>1</slash:comments><wfw:commentRss>http://www.clariusconsulting.net/blogs/kzu/commentrss.aspx?PostID=70812</wfw:commentRss></entry><entry><title>A practical example on how to mock static classes without TypeMock</title><link rel="alternate" type="text/html" href="http://www.clariusconsulting.net/blogs/kzu/archive/2008/05/18/mock_statics_without_typemock.aspx" /><id>e6de741d-39cb-46fc-b8ae-6ce6880bcef9:69123</id><created>2008-05-18T20:00:55Z</created><content type="text/html" mode="escaped">
		&lt;p&gt;WCF is the second biggest framework after ASP.NET that sooner or later forces you to use a static "context" property to do anything beyond the trivial stuff. ASP.NET has the HttpContext.Current, whereas WCF has the WebOperationContext.Current for example.&lt;/p&gt;
		&lt;p&gt;My friend &lt;a href="http://weblogs.asp.net/cibrax"&gt;Pablo Cibraro&lt;/a&gt; proves &lt;a href="http://weblogs.asp.net/cibrax/archive/2008/05/16/unit-tests-for-wcf.aspx"&gt;how you can quite easily make your implementations that depend on such static contexts testable&lt;/a&gt; without resorting to &lt;a href="http://www.google.com/search?hl=en&amp;amp;q=typemock%20mock%20static%20classes"&gt;black-magic voodoo TypeMock&lt;/a&gt; kind of stuff. Any .NET developer can trivially introduce an indirection to make their classes testable, even if they depend on static classes. &lt;/p&gt;
		&lt;p&gt;So, don't buy a product just because you're lazy and want to avoid creating a few wrapper classes and interfaces. Most of them can be copied directly from Reflector's API rendering. And once you have the interfaces, you can just use &lt;a href="http://mockframeworks.com/moq"&gt;MoQ&lt;/a&gt; or &lt;a href="http://mockframeworks.com/rhino"&gt;Rhino&lt;/a&gt; (or whichever &lt;a href="http://mockframeworks.com/"&gt;mock framework&lt;/a&gt; you like) to mock them any way you want.&lt;/p&gt;
		&lt;p&gt;Always use the simplest thing that could possibly work.&lt;/p&gt;
		&lt;b&gt;Update&lt;/b&gt;: added a reference to other mock frameworks that can be used to the same effect. Apparently some people get picky if you have a preference and it happens to be the one you built :)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update II&lt;/b&gt;: For those that didn't follow the discussion over at &lt;a href="http://weblogs.asp.net/rosherove/archive/2008/05/19/two-faced-commits-how-the-alt-net-community-is-becoming-more-and-more-dogmatic.aspx"&gt;Roy's blog&lt;/a&gt;, I'll &lt;a href="http://weblogs.asp.net/rosherove/archive/2008/05/19/two-faced-commits-how-the-alt-net-community-is-becoming-more-and-more-dogmatic.aspx#6201926"&gt;repeat an analogy&lt;/a&gt; that better explains what my point was with &lt;a href="http://www.clariusconsulting.net/blogs/kzu/archive/2008/05/18/mock_statics_without_typemock.aspx"&gt;my previous post on mocking statics&lt;/a&gt;:
&lt;blockquote&gt;&lt;p&gt;If you are not careful enough and can shoot yourself in the foot, the less shotguns you have around the house, the better. 
&lt;/p&gt;&lt;p&gt;That said, you may have a big, ugly, old contender where you really need the biggest shotgun you can get. But you'll be giving it to your very best guys, not to the newbie soldier.
&lt;/p&gt;&lt;p&gt;Better to teach the newbies how to shoot smaller objectives with a regular pistol first (the whole point of Pablo's post on mocking WCF static context).
&lt;/p&gt;&lt;p&gt;Some may say this sounds somewhat paternalist. I think that's pragmatism.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;I'd rather show developers how to work around statics imposed by some "legacy" framework they happen to use (i.e. WCF and ASP.NET static contexts) by using typical OO techniques such as the one &lt;a href="http://weblogs.asp.net/cibrax/archive/2008/05/16/unit-tests-for-wcf.aspx"&gt;explained by Pablo&lt;/a&gt;, than giving them a bazooka and spending endless hours explaining how to NOT overuse it. &lt;/p&gt;&lt;p&gt;For the record, the technique is *exactly* the same used the ASP.NET MVC team, I don't hear anyone calling HttpContextBase and friends "&lt;a href="http://www.elilopian.com/2008/05/19/mocking-frameworks-dream-feature/"&gt;utterly useless wrappers&lt;/a&gt;". I find it hard to think about a case where such a technique could not be applied to make new code written to interact/integrate with a legacy system testable. Would love to find a counter example.&lt;/p&gt;&lt;p&gt;Sometimes it's just that the solution ends up being much simpler than you initially thought. How hard do you think it is to do the ASP.NET MVC trick for the ASP.NET HttpContext? Go &lt;a href="http://www.codeplex.com/aspnet"&gt;get the sources&lt;/a&gt;, find class MvcHandler and see for yourself.&lt;/p&gt;&lt;p&gt;Also, &lt;a href="http://weblogs.asp.net/cibrax/archive/2008/05/20/unit-tests-for-wcf-and-moq-part-ii.aspx"&gt;Pablo clarified&lt;/a&gt; that his &lt;a href="http://weblogs.asp.net/cibrax/archive/2008/05/16/unit-tests-for-wcf.aspx"&gt;original post&lt;/a&gt; was how to mock the WCF context, regardless of its static nature (as you could still pass it to your implementation's constructor), when it's neither an interface, nor a class with any virtuals that enable easy mocking.&lt;/p&gt;&lt;p&gt;More to the &lt;a href="http://blogs.msdn.com/scottdensmore/archive/2004/05/25/140827.aspx"&gt;case against statics and singletons at Scott's blog&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;img src="http://www.clariusconsulting.net/aggbug.aspx?PostID=69123" width="1" height="1"&gt;</content><slash:comments>6</slash:comments><wfw:commentRss>http://www.clariusconsulting.net/blogs/kzu/commentrss.aspx?PostID=69123</wfw:commentRss></entry><entry><title>Live Mesh FeedSync: an overview of the protocol under the hood</title><link rel="alternate" type="text/html" href="http://www.clariusconsulting.net/blogs/kzu/archive/2008/04/29/62598.aspx" /><id>e6de741d-39cb-46fc-b8ae-6ce6880bcef9:62598</id><created>2008-04-29T16:16:44Z</created><content type="text/html" mode="escaped">
		&lt;p&gt;I already mentioned why I think Live Mesh is cool and that I think the most important part of it, &lt;a href="http://feedsync.org"&gt;FeedSync&lt;/a&gt;, is being largely ignored by reviewers. Fortunately, there's an extensive interview with the team that goes quite deep in FeedSync and how it works. Go watch it, it's good info.&lt;/p&gt;
		&lt;p&gt;At the most basic level, FeedSync is a mechanism to associate versioning "headers" to arbitrary objects (items), and an algorithm to merge and detect conflicts based on that header information. Replace "header" with "extension element" and "arbitrary object" with "RSS/Atom Item" and you have the XML feed version of it:&lt;/p&gt;
		&lt;pre class="code"&gt;
				&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;
				&lt;span style="color: rgb(163, 21, 21);"&gt;item &lt;/span&gt;
				&lt;span style="color: red;"&gt;xmlns:sx&lt;/span&gt;
				&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;http://feedsync.org/2007/feedsync&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;title&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Buy groceries&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;title&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:sync &lt;/span&gt;&lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;0a7903db47fb0fff&lt;/span&gt;' &lt;span style="color: red;"&gt;updates&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;1&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:history &lt;/span&gt;&lt;span style="color: red;"&gt;sequence&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;1&lt;/span&gt;' &lt;span style="color: red;"&gt;by&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;kzu&lt;/span&gt;'&lt;span style="color: blue;"&gt;/&amp;gt;&lt;br /&gt; &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:sync&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;item&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
		&lt;p&gt;The sx:sync element is the versioning header. Every time the item is updated (say, by another user/device), a new sx:history element is added and the updates attribute is incremented:&lt;/p&gt;
		&lt;pre class="code"&gt;
				&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;
				&lt;span style="color: rgb(163, 21, 21);"&gt;item&lt;/span&gt;
				&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt; &amp;lt;&lt;/span&gt;
				&lt;span style="color: rgb(163, 21, 21);"&gt;title&lt;/span&gt;
				&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Buy groceries&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;title&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:sync &lt;/span&gt;&lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;0a7903db47fb0fff&lt;/span&gt;' &lt;span style="color: red;"&gt;updates&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;2&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;   &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:history &lt;/span&gt;&lt;span style="color: red;"&gt;sequence&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;2&lt;/span&gt;' &lt;span style="color: red;"&gt;by&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;font color="#0000ff"&gt;vga&lt;/font&gt;'&lt;span style="color: blue;"&gt;/&amp;gt;&lt;br /&gt;   &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:history &lt;/span&gt;&lt;span style="color: red;"&gt;sequence&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;1&lt;/span&gt;' &lt;span style="color: red;"&gt;by&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;kzu&lt;/span&gt;'&lt;span style="color: blue;"&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt; &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:sync&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;item&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
		&lt;a href="http://11011.net/software/vspaste"&gt;
		&lt;/a&gt;
		&lt;p&gt;If v1 of the item was updated simultaneously by two users and you try to merge them, you'd end up with something like the following:&lt;/p&gt;
		&lt;pre class="code"&gt;
				&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;
				&lt;span style="color: rgb(163, 21, 21);"&gt;item&lt;/span&gt;
				&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt; &amp;lt;&lt;/span&gt;
				&lt;span style="color: rgb(163, 21, 21);"&gt;title&lt;/span&gt;
				&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Buy groceries&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;title&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:sync &lt;/span&gt;&lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;0a7903db47fb0fff&lt;/span&gt;' &lt;span style="color: red;"&gt;updates&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;2&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;   &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:history &lt;/span&gt;&lt;span style="color: red;"&gt;sequence&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;2&lt;/span&gt;' &lt;span style="color: red;"&gt;by&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;kzu&lt;/span&gt;'&lt;span style="color: blue;"&gt;/&amp;gt;&lt;br /&gt;   &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:history &lt;/span&gt;&lt;span style="color: red;"&gt;sequence&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;1&lt;/span&gt;' &lt;span style="color: red;"&gt;by&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;kzu&lt;/span&gt;'&lt;span style="color: blue;"&gt;/&amp;gt;&lt;br /&gt;   &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:conflicts&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;     &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;item&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;       &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;title&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Buy icecream&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;title&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;       &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;customer &lt;/span&gt;&lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;1&lt;/span&gt;' &lt;span style="color: blue;"&gt;/&amp;gt;&lt;br /&gt;       &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:sync &lt;/span&gt;&lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;0a7903db47fb0fff&lt;/span&gt;' &lt;span style="color: red;"&gt;updates&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;2&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;         &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:history &lt;/span&gt;&lt;span style="color: red;"&gt;sequence&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;2&lt;/span&gt;' &lt;span style="color: red;"&gt;by&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;vga&lt;/span&gt;'&lt;span style="color: blue;"&gt;/&amp;gt;&lt;br /&gt;         &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:history &lt;/span&gt;&lt;span style="color: red;"&gt;sequence&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;1&lt;/span&gt;' &lt;span style="color: red;"&gt;by&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;kzu&lt;/span&gt;'&lt;span style="color: blue;"&gt;/&amp;gt;&lt;br /&gt;       &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:sync&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;     &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;item&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;   &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:conflicts&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt; &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:sync&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;item&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
		&lt;a href="http://11011.net/software/vspaste"&gt;
		&lt;/a&gt;
		&lt;p&gt;Notice the added sx:conflicts element, which contains the conflicting item in its entirety. The algorithm provides a consistent selection of a default "winner" from the merge (in this case my v2 item, rather than &lt;a title="vga's blog" href="http://clariusconsulting.net/vga"&gt;Victor&lt;/a&gt;'s). This gives you a consistent state across the mesh. But note that the merge operation with conflict does NOT resolve the conflict. It just surfaces it in a predictable way.&lt;/p&gt;
		&lt;p&gt;Needless to say, the default winner might not be what the end user wants, so at that point the application can surface the conflict (i.e. a different icon for the item) and allow him to resolve it in a different way (i.e. doing a full content diff and picking the new state). Alternatively, a specific implementation of an item store/adapter (i.e. the feedsync-enabled store for files) can provide automatic resolution if it so wishes to, such as doing an auto-merge of the file contents.&lt;/p&gt;
		&lt;p&gt;
				&lt;a href="http://weblogs.asp.net/cibrax/archive/2008/04/22/overview-of-feedsync-support-in-the-microsoft-sync-framework.aspx"&gt;Pablo has more info&lt;/a&gt; on how it works and the way the &lt;a href="http://msdn2.microsoft.com/en-us/sync/default.aspx"&gt;Microsoft Sync Framework&lt;/a&gt; exposes this. &lt;/p&gt;
		&lt;p&gt;It seems really simple at first glance, doesn't it? The devil is in the details, as usual. It's obviously a RESTful approach to synchronization, where the item payload is the actual representation of the state. This means that upon conflict, all you have is the state. Implementing automatic conflict resolution can be quite tricky as a consequence.&lt;/p&gt;
		&lt;h2&gt;Automatic Conflict Resolution?&lt;/h2&gt;
		&lt;p&gt;As part of our &lt;a href="http://www.mesh4x.org"&gt;Mesh4x&lt;/a&gt; implementation with &lt;a href="http://instedd.org"&gt;InSTEDD&lt;/a&gt;, we're thinking about ways to increase the chances of automatic conflict resolution, as it's generally desirable and you don't want to be bothering your users for every apparently conflicting change. Think about a very simple example: tags. Say both user A and B add a tag at the same time, and then they synchronize:&lt;/p&gt;
		&lt;p&gt;Initial state of both A and B (say, created by yet another user, C):&lt;/p&gt;
		&lt;pre class="code"&gt;
				&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;
				&lt;span style="color: rgb(163, 21, 21);"&gt;item&lt;/span&gt;
				&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;  &amp;lt;&lt;/span&gt;
				&lt;span style="color: rgb(163, 21, 21);"&gt;title&lt;/span&gt;
				&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Buy groceries&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;title&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:sync &lt;/span&gt;&lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;0a7903db47fb0fff&lt;/span&gt;' &lt;span style="color: red;"&gt;updates&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'1'&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:history &lt;/span&gt;&lt;span style="color: red;"&gt;sequence&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;font color="#0000ff"&gt;1&lt;/font&gt;' &lt;span style="color: red;"&gt;by&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;font color="#0000ff"&gt;C&lt;/font&gt;'&lt;span style="color: blue;"&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;  &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:sync&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;item&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
		&lt;a href="http://11011.net/software/vspaste"&gt;
		&lt;/a&gt;
		&lt;p&gt;User A changes item by adding a category "to-do" (again, notice the new sx:history):&lt;/p&gt;
		&lt;pre class="code"&gt;
				&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;
				&lt;span style="color: rgb(163, 21, 21);"&gt;item&lt;/span&gt;
				&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;  &amp;lt;&lt;/span&gt;
				&lt;span style="color: rgb(163, 21, 21);"&gt;title&lt;/span&gt;
				&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Buy groceries&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;title&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;category&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;to-do&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;category&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:sync &lt;/span&gt;&lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;0a7903db47fb0fff&lt;/span&gt;' &lt;span style="color: red;"&gt;updates&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;2&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:history &lt;/span&gt;&lt;span style="color: red;"&gt;sequence&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;2&lt;/span&gt;' &lt;span style="color: red;"&gt;by&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;A&lt;/span&gt;'&lt;span style="color: blue;"&gt;/&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:history &lt;/span&gt;&lt;span style="color: red;"&gt;sequence&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;1&lt;/span&gt;' &lt;span style="color: red;"&gt;by&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;C&lt;/span&gt;'&lt;span style="color: blue;"&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;  &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:sync&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;item&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
		&lt;a href="http://11011.net/software/vspaste"&gt;
		&lt;/a&gt;
		&lt;p&gt;Whereas user B changes it by adding a different category "supermarket":&lt;/p&gt;
		&lt;pre class="code"&gt;
				&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;
				&lt;span style="color: rgb(163, 21, 21);"&gt;item&lt;/span&gt;
				&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;  &amp;lt;&lt;/span&gt;
				&lt;span style="color: rgb(163, 21, 21);"&gt;title&lt;/span&gt;
				&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Buy groceries&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;title&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;category&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;supermarket&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;category&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:sync &lt;/span&gt;&lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;0a7903db47fb0fff&lt;/span&gt;' &lt;span style="color: red;"&gt;updates&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;2&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:history &lt;/span&gt;&lt;span style="color: red;"&gt;sequence&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;2&lt;/span&gt;' &lt;span style="color: red;"&gt;by&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;B&lt;/span&gt;'&lt;span style="color: blue;"&gt;/&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:history &lt;/span&gt;&lt;span style="color: red;"&gt;sequence&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;1&lt;/span&gt;' &lt;span style="color: red;"&gt;by&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;C&lt;/span&gt;'&lt;span style="color: blue;"&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;  &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:sync&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;item&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
		&lt;a href="http://11011.net/software/vspaste"&gt;
		&lt;/a&gt;
		&lt;p&gt;When they sync, the algorithm will detect a conflict, as we have the same sequence number but with different "by". It will pick a default winner (say, A's change). But clearly this is a case where we could apply auto-merge semantics if we knew the operation each user performed. &lt;/p&gt;
		&lt;p&gt;You might be tempted to say: just do a content merge and that's it! But the semantics of a merge of state cannot be applied generically (i.e. a Company element gets an IsBankrupt='true' value from one user, and a new Invoice element from another: at the business logic level, the two changes cannot be merged. If the company went bankrup, you can no longer receive invoices from it), and it's even quite tricky with XML elements that can be moved around, renamed, deleted and re-inserted across multiple versions, etc.&lt;/p&gt;
		&lt;p&gt;So one approach we're thinking is to add command-pattern like hints that an adapter/store can use as hints for automatic conflict resolution and state reconstruction for merging. In the case above, maybe the XML adapter expresses user A operation as a combination of the item payload, the sync versioning header, and diff information about what was changed (added an element inmediately after the first child element of the root, in terms of XPath):&lt;/p&gt;
		&lt;pre class="code"&gt;
				&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;
				&lt;span style="color: rgb(163, 21, 21);"&gt;item&lt;/span&gt;
				&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;  &amp;lt;&lt;/span&gt;
				&lt;span style="color: rgb(163, 21, 21);"&gt;title&lt;/span&gt;
				&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Buy groceries&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;title&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;category&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;to-do&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;category&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:sync &lt;/span&gt;&lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;0a7903db47fb0fff&lt;/span&gt;' &lt;span style="color: red;"&gt;updates&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;2&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:history &lt;/span&gt;&lt;span style="color: red;"&gt;sequence&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;2&lt;/span&gt;' &lt;span style="color: red;"&gt;by&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;A&lt;/span&gt;'&lt;span style="color: blue;"&gt;/&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:history &lt;/span&gt;&lt;span style="color: red;"&gt;sequence&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;1&lt;/span&gt;' &lt;span style="color: red;"&gt;by&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;C&lt;/span&gt;'&lt;span style="color: blue;"&gt;/&amp;gt;&lt;br /&gt;  &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;sx:sync&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;diff &lt;/span&gt;&lt;span style="color: red;"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;.../xmldiff&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;add &lt;/span&gt;&lt;span style="color: red;"&gt;match&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;/*[1]&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;category&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;to-do&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;category&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;add&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;  &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;diff&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;item&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;
		&lt;a href="http://11011.net/software/vspaste"&gt;
		&lt;/a&gt;
		&lt;p&gt;The new diff element would be very similar in spirit to the &lt;a href="http://msdn.microsoft.com/en-us/xml/bb190622.aspx"&gt;XML Diff and Patch&lt;/a&gt; tool from &lt;a href="http://msdn.microsoft.com/en-us/library/aa302294.aspx"&gt;Microsoft&lt;/a&gt; and would make it easier for the XML adapter to determine if a given change is compatible for auto-merge (i.e. it's not a change in a node that was removed, etc.). &lt;/p&gt;
		&lt;p&gt;I think different adapters might benefit from surfacing different conflict resolution hints. A database may include schema manipulation statements to perform upgrades, for example.&lt;/p&gt;
		&lt;p&gt;This is exploratory field as we try to make for the best user experience possible. We don't want to end up in the Groove approach where your choices are: save your changes as a different item, or discard your changes :S.&lt;/p&gt;
		&lt;p&gt; &lt;/p&gt;
		&lt;p&gt;What do you think?&lt;/p&gt;&lt;img src="http://www.clariusconsulting.net/aggbug.aspx?PostID=62598" width="1" height="1"&gt;</content><slash:comments>1</slash:comments><wfw:commentRss>http://www.clariusconsulting.net/blogs/kzu/commentrss.aspx?PostID=62598</wfw:commentRss></entry><entry><title>Live Mesh Everywhere: open source and cross-platform</title><link rel="alternate" type="text/html" href="http://www.clariusconsulting.net/blogs/kzu/archive/2008/04/24/61728.aspx" /><id>e6de741d-39cb-46fc-b8ae-6ce6880bcef9:61728</id><created>2008-04-24T13:19:18Z</created><content type="text/html" mode="escaped">
		&lt;p&gt;
		&lt;/p&gt;
		&lt;p&gt;You have probably read or &lt;a title="Ray Ozzie's Live Mesh Overview video" href="http://channel9.msdn.com/showpost.aspx?postid=399578"&gt;listened&lt;/a&gt; all the (maybe a bit vague) information about the &lt;a title="MOE Google Search" href="http://www.google.com/search?hl=en&amp;amp;q=mesh+operating+environment&amp;amp;btnG=Search"&gt;Mesh Operating Environment&lt;/a&gt; (MOE): a platform that will allow multiple applications and devices to participate in the &lt;a title="Live Mesh Google Search" href="http://www.google.com/search?hl=en&amp;amp;q=microsoft%20live%20mesh"&gt;Live Mesh&lt;/a&gt;.  &lt;/p&gt;
		&lt;p&gt;Let's get to the more technical details now, and leave the end-user marketing to someone else ;).  &lt;/p&gt;
		&lt;p&gt;At the core of Live Mesh is &lt;a href="http://feedsync.org"&gt;FeedSync&lt;/a&gt;, a public spec by Microsoft, &lt;a href="http://en.wikipedia.org/wiki/Simple_Sharing_Extensions"&gt;evolved from&lt;/a&gt; the &lt;a href="http://msdn2.microsoft.com/en-us/xml/bb510102.aspx"&gt;"old" days of SSE&lt;/a&gt;. It didn't get its deserved attention IMO back in the day, even though you could put together the pieces from Ray's announcement and later adoption by other products and figure out Live Mesh was coming sooner or later. &lt;a href="http://edjez.instedd.org/"&gt;Ed Jezierski&lt;/a&gt; got me interested in it WAY back, and as a result, I created the &lt;a title="SimpleSharing @ CodePlex" href="http://www.codeplex.com/sse"&gt;first open source implementation&lt;/a&gt; of the spec.  &lt;/p&gt;
		&lt;p&gt;To understand its importance you need to first understand what FeedSync is. The most succinct definition I could come up with is:  &lt;/p&gt;
		&lt;blockquote&gt;
				&lt;p&gt;
						&lt;em&gt;FeedSync is a definition of a versioning header (or metadata) and its associated creation, update and deletion behavior as well as a generic conflict detection algorithm based on it, which can be attached to an arbitrary piece of data.&lt;/em&gt;
				&lt;/p&gt;
		&lt;/blockquote&gt;
		&lt;p&gt;The interesting part of it, as you are probably realizing already, is NOT the XML microformat itself, or its representation in an RSS/Atom feed, but rather the behavior and semantics associated with it, which you can rely on to be present at compliant endpoints.  &lt;/p&gt;
		&lt;p&gt;The specification defines the behavior for merging (arguably the most important one) data between two "feeds" (think of these as "streams of data with associated versioning header/metadata") in a consistent manner. It's two-way sync for the masses. &lt;/p&gt;
		&lt;p&gt;Of course, specs without implementations are seldom of any use. Microsoft is providing their own with the &lt;a href="http://msdn2.microsoft.com/en-us/sync/default.aspx"&gt;Microsoft Synchronization Framework&lt;/a&gt; (which does other things in addition to supporting FeedSync), and now Live Mesh. But nothing forbids the community from building compliant cross-platform open source alternative implementations. &lt;/p&gt;
		&lt;p&gt;Being an open source fan myself, and being lucky enough to work for an &lt;a href="http://instedd.org"&gt;organization whose goal is to produce open source software to help in the humanitarian space&lt;/a&gt;, I'm glad to announce that we have already been working actively in this space, and we just released early versions of our ongoing projects at &lt;a href="http://code.google.com/p/mesh4x/"&gt;Google Code&lt;/a&gt;. &lt;/p&gt;
		&lt;h2&gt;
		&lt;/h2&gt;
		&lt;h2&gt;Mesh for X&lt;/h2&gt;
		&lt;p&gt;Or Mesh4x for "short", is an umbrella project by &lt;a href="http://instedd.org"&gt;InSTEDD&lt;/a&gt; under which we're producing Mesh4j and Mesh4n (Java and .NET respectively) versions of a unified implementation and library design/API for FeedSync synchronization between arbitrary repositories of data (i.e. databases, files, spreadsheets, etc.). We may very well come up with Mesh4py (Phyton), Mesh4r (Ruby) or whatever we or the community need to satisfy data synchronization scenarios. &lt;/p&gt;
		&lt;p&gt;The Mesh4n version is coming straight from its old place in CodePlex, but you expect it to evolve together with the Mesh4j version. Our goal is to keep feature-parity on both. This version of FeedSync for .NET is being used by &lt;a href="http://www.strongangel3.net/mhs"&gt;Microsoft Humanitarian Systems&lt;/a&gt; (MHS) in Afganistan to synchronize disparate data sources in extreme and low connectivity conditions as mentioned by &lt;a href="http://blog.jonudell.net/2007/07/12/a-conversation-with-ted-okada-about-the-work-of-microsoft-humanitarian-systems/"&gt;Ted Okada&lt;/a&gt; (i.e. to achieve two-way synchronization of disconnected Access databases, Excel files and plain RSS files on a pendrive, between any of them!). &lt;/p&gt;
		&lt;p&gt;At this time, both libraries provide the basic synchronization algorithm and Sync (metadata) data model, as well as the core interfaces to create your own repository adapters to expose data from arbitrary sources for FeedSync synchronization. We'll be building concrete repository adapters during the next few weeks. The most interesting one for me is the Mobile repository, which should allow you to sync two repositories over cellphones, without cellphone internet connection or even a data plan (which needless to say is not very frequent in the under-developed or even developing world). &lt;/p&gt;
		&lt;p&gt;We'll also be looking for refactoring opportunities to simplify certain scenarios and accomodate the future roadmap for FeedSync.  &lt;/p&gt;
		&lt;p&gt;  &lt;/p&gt;
		&lt;p&gt;Some people have argued this is just another consumer-oriented Microsoft-thinghy that will hardly make a difference in anything. I believe that's a mistake, as it's ignoring the underpinning technology, the fact that it's a public specification, and that it can be applied to really free the data once and for all, regardless of platform, application, format, language, etc. This is the very reason I'm not excited at all by all the &lt;a title="Wikipedia on Atom" href="http://en.wikipedia.org/wiki/Atom_%28standard%29"&gt;Atom Publishing Protocol&lt;/a&gt;&lt;a href="http://www.infoq.com/news/2008/03/microsoft-atompub"&gt;fuss that's happening&lt;/a&gt;&lt;a href="http://www.25hoursaday.com/weblog/2008/02/28/WindowsLivePlatformNewsMicrosoftStandardizesOnAtomPubForWebServicesAndOtherStories.aspx"&gt;these&lt;/a&gt;&lt;a href="http://blogs.msdn.com/astoriateam/archive/2008/02/13/atompub-support-in-the-ado-net-data-services-framework.aspx"&gt;days&lt;/a&gt;. Web 2.0/AJAX + APP is SO client-server... but that's for another post, another day. &lt;/p&gt;
		&lt;p&gt;  &lt;/p&gt;
		&lt;p&gt;Stay tunned as I'll be posting more detailed (and practical) information about Mesh4x in the coming weeks, as well as the cool stuff we're doing with &lt;a href="http://instedd.org"&gt;InSTEDD&lt;/a&gt; as part of its &lt;a href="http://instedd.org/about"&gt;goal of helping in the humanitarian space by applying technology&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;img src="http://www.clariusconsulting.net/aggbug.aspx?PostID=61728" width="1" height="1"&gt;</content><slash:comments>2</slash:comments><wfw:commentRss>http://www.clariusconsulting.net/blogs/kzu/commentrss.aspx?PostID=61728</wfw:commentRss></entry><entry><title>MoQ now uses xUnit for its unit tests</title><link rel="alternate" type="text/html" href="http://www.clariusconsulting.net/blogs/kzu/archive/2008/04/22/MoQnowusesxUnitforitsunittests.aspx" /><id>e6de741d-39cb-46fc-b8ae-6ce6880bcef9:61177</id><created>2008-04-22T14:27:03Z</created><content type="text/html" mode="escaped">&lt;p&gt;After talking to a few guys during the MVP summit and the proceedings of the ALT.NET conference, I decided to give &lt;a title="xUnit home page" href="http://www.codeplex.com/xunit/"&gt;xUnit&lt;/a&gt; a serious try. &lt;/p&gt; &lt;p&gt;I'm quite pleased with it. Using .NET idioms rather than excessive attributes (i.e. [SetUp] vs class constructor, [TearDown] vs IDisposable, etc.) is a good thing. &lt;/p&gt; &lt;p&gt;"Upgrading" was quite easy: for the most part, it was a search &amp;amp; replace of:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;[Test] =&amp;gt; [Fact]  &lt;li&gt;[SetUp] =&amp;gt; ""  &lt;li&gt;[TearDown] =&amp;gt; ""  &lt;li&gt;Assert.That =&amp;gt; Assert.True  &lt;li&gt;Assert.Fail =&amp;gt; Assert.True(false,  &lt;li&gt;Assert.Isxxx =&amp;gt; Assert.xxx  &lt;li&gt;Assert.Arexxx =&amp;gt; Assert.xxx&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The only tricky one which took the most time was replacing all the [ExpectedException] attributes with Assert.Throws. I like xUnit approach better, but it was annoying anyways. The good thing is that I deleted some code that was not used as the exceptions were being thrown before, and I didn't realize 'cause I was using [ExpectedException]. &lt;/p&gt; &lt;p&gt;Renaming [Test] to [Fact] also has IMO a very good consequence: it forces you to think about your test method names as fact statements that make sense as an english sentence. I've argued with my team about the value of that, and we had a convention for [Test] that the method names must start with "Should". This also has the same effect, but being kind of enforced by the framework is better. The following test will now bother you when you read it:&lt;/p&gt;&lt;pre&gt;[Fact]&lt;br&gt;public void InvokeWithTwoArgs()&lt;/pre&gt;
&lt;p&gt;you can no longer say that the method name expresses a fact. It's a subconscious thing, nothing to be too passionate about, but it helps, believe me. &lt;/p&gt;
&lt;p&gt;One minor issue is that in order to use &lt;a href="http://www.testdriven.net/"&gt;TDD.NET&lt;/a&gt; to run the tests, you need to run the xUnit installer tool (included in MoQ trunk at Lib\xUnit\xunit.installer.exe) to explicitly enable the runner. Unfortunately, once you do that, you can no longer use TDD.NET to run NUnit tests (or any of its &lt;a href="http://www.testdriven.net/"&gt;supported test frameworks&lt;/a&gt;): you need to re-run the tool and disable TDD.NET support explicitly. But I'm confident it's just a matter of time before it's supported out of the box in TDD.NET.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So far, I think xUnit brings a fresh perspective to unit test frameworks. Challenging the status quo generally results in interesting new ideas IMO :) &lt;/p&gt;&lt;img src="http://www.clariusconsulting.net/aggbug.aspx?PostID=61177" width="1" height="1"&gt;</content><slash:comments>1</slash:comments><wfw:commentRss>http://www.clariusconsulting.net/blogs/kzu/commentrss.aspx?PostID=61177</wfw:commentRss></entry><entry><title>Improving MoQ to allow arrange-act-assert testing style</title><link rel="alternate" type="text/html" href="http://www.clariusconsulting.net/blogs/kzu/archive/2008/04/22/ImprovingMoQtoallowarrangeactasserttestingstyle.aspx" /><id>e6de741d-39cb-46fc-b8ae-6ce6880bcef9:61200</id><created>2008-04-22T15:45:16Z</created><content type="text/html" mode="escaped">
		&lt;p&gt;Today, the &lt;a href="http://code.google.com/p/moq/"&gt;MoQ&lt;/a&gt;&lt;a href="http://www.clariusconsulting.net/labs/moq/html/F3C3BE5A.htm"&gt;API&lt;/a&gt; lets you setup expectations and later verify them, like so:&lt;/p&gt;
		&lt;pre class="code"&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;Fact&lt;/span&gt;]
&lt;span style="color: blue;"&gt;public void &lt;/span&gt;FillingRemovesInventoryIfInStock()
{
    &lt;span style="color: green;"&gt;//arrange/setup
    &lt;/span&gt;&lt;span style="color: blue;"&gt;var &lt;/span&gt;order = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Order&lt;/span&gt;(TALISKER, 50);
    &lt;span style="color: blue;"&gt;var &lt;/span&gt;mock = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;IWarehouse&lt;/span&gt;&amp;gt;();

    &lt;span style="color: green;"&gt;//setup - expectations
    &lt;/span&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;mock.Expect(x =&amp;gt; x.HasInventory(TALISKER, 50)).Returns(&lt;span style="color: blue;"&gt;true&lt;/span&gt;);
&lt;/font&gt;&lt;/strong&gt;&lt;span style="color: green;"&gt;//act
    &lt;/span&gt;order.Fill(mock.Object);

    &lt;span style="color: green;"&gt;//assert
    &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Assert&lt;/span&gt;.True(order.IsFilled);
    &lt;span style="color: green;"&gt;//verify interaction
    &lt;/span&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;mock.VerifyAll();&lt;/font&gt;&lt;/strong&gt;
}
&lt;/pre&gt;
		&lt;p&gt;A very good feedback I got during the past &lt;a href="https://www.mvpsummit2008.com/"&gt;MVP Summit&lt;/a&gt; was that the current approach moves all the semantic relevance for mocks up to the setup phase of the test. In order words, it doesn't fit well in the Arrange-Act-Assert pattern, as effectively the "asserts" (expectations that must be met) are now in the "arrange" (or setup) phase of the test.&lt;/p&gt;
		&lt;p&gt;The Verify/VerifyAll call which is down at the assertion phase contains no semantic whatsoever about what it is you are expecting to happen. &lt;/p&gt;
		&lt;p&gt;In order to be accomodate this requirement, I'm gonna be adding a overload to Verify that takes the expression you want to verify:&lt;/p&gt;
		&lt;pre class="code"&gt;
				&lt;span style="color: green;"&gt;//assert
&lt;/span&gt;mock.Verify(x =&amp;gt; x.HasInventory(TALISKER, 50));&lt;/pre&gt;
		&lt;a href="http://11011.net/software/vspaste"&gt;
		&lt;/a&gt;
		&lt;a href="http://11011.net/software/vspaste"&gt;
		&lt;/a&gt;
		&lt;p&gt;This would bring back the assertion phase to the place it belongs, if that's what you need. And because the default behavior on MoQ mocks is that they never throw on unexpected invocations, you can use the Expect only to setup return values when you need them (I'm hesitant to rename Expect to Setup, as for people using strict mocks that prefer the VerifyAll approach, it won't make much sense). &lt;/p&gt;
		&lt;p&gt; &lt;/p&gt;
		&lt;p&gt;What do you think?&lt;/p&gt;&lt;img src="http://www.clariusconsulting.net/aggbug.aspx?PostID=61200" width="1" height="1"&gt;</content><slash:comments>0</slash:comments><wfw:commentRss>http://www.clariusconsulting.net/blogs/kzu/commentrss.aspx?PostID=61200</wfw:commentRss></entry><entry><title>Locating the active item in the solution explorer</title><link rel="alternate" type="text/html" href="http://www.clariusconsulting.net/blogs/kzu/archive/2008/04/18/Locatingtheactiveiteminthesolutionexplorer.aspx" /><id>e6de741d-39cb-46fc-b8ae-6ce6880bcef9:59922</id><created>2008-04-18T01:44:08Z</created><content type="text/html" mode="escaped">&lt;p&gt;Say you are working with a code file. At some point, you "Go To Definition" of another type, and now you have its code file opened. Or maybe you just run the solution to debug a weird issue that's happening, turn on "break when exception is thrown" option, and just when the exception is thrown, Visual Studio gets activated, and you get the relevant code file opened at the appropriate location.&lt;/p&gt; &lt;p&gt;Now, say you have a typical solution, which contains solution folders and many projects. Can you quickly locate the project/folder where the file is?&lt;/p&gt; &lt;p&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" alt="image" src="http://www.clariusconsulting.net/images/blogs/kzu/Locatingtheactiveiteminthesolutionexplor_185C/image.png"&gt; &lt;/p&gt; &lt;p&gt;I've found that MOST developers simply go fishing for the file, or look at the file path and pray the solution folders actually match physical folders so they can manually traverse it, etc. Turns out there's a much better alternative, which is to turn on "Track Active Item in Solution Explorer" under Tools &amp;gt; Options &amp;gt; Projects and Solutions:&lt;/p&gt; &lt;p&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" alt="image" src="http://www.clariusconsulting.net/images/blogs/kzu/Locatingtheactiveiteminthesolutionexplor_185C/image_3.png"&gt; &lt;/p&gt; &lt;p&gt;Now after clicking OK, the solution explorer is automatically expanded and the proper node selected:&lt;/p&gt; &lt;p&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" alt="image" src="http://www.clariusconsulting.net/images/blogs/kzu/Locatingtheactiveiteminthesolutionexplor_185C/image_4.png"&gt; &lt;/p&gt; &lt;p&gt;Much better, right?&lt;/p&gt; &lt;p&gt;Well, turns out that I'm pretty darn sure this option was ON by default in VS2002 and maybe even 2003. I &lt;a title="Make &amp;quot;Trake Active Item in Solution Explorer&amp;quot; be enabled by default" href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=105637"&gt;reported this back in 2005&lt;/a&gt; with a suggestion to turn it on by default again. It was resolved "By Design": &lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;...due to a significant amount of customer feedback we've received. The concern that people were raising about having this option enabled by default was that there were certain scenarios where there was a performance hit. &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Well, I tried it with the certainly big Enterprise Library 3.1 solution (no unit tests), which contains 38 projects with 1867 files in 1136 folders and haven't noticed any significant issue associated with enabling that option.&lt;/p&gt; &lt;p&gt;If you think the usability improvements from having this option on surpass the remote chance that in certain scenarios there may be a performance hit (?), please go and &lt;a title="Make &amp;quot;Trake Active Item in Solution Explorer&amp;quot; be enabled by default" href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=105637"&gt;vote to get it fixed&lt;/a&gt;. Believe me, &lt;a title="For those that think Microsoft Connect is useless" href="http://www.clariusconsulting.net/blogs/kzu/archive/2008/04/18/ForthosethatthinkMicrosoftConnectisuseless.aspx"&gt;we CAN make it change&lt;/a&gt;. I'm going to reopen the bug if there are significantly new voters.&lt;/p&gt;&lt;img src="http://www.clariusconsulting.net/aggbug.aspx?PostID=59922" width="1" height="1"&gt;</content><slash:comments>5</slash:comments><wfw:commentRss>http://www.clariusconsulting.net/blogs/kzu/commentrss.aspx?PostID=59922</wfw:commentRss></entry></feed>