<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-15137028</id><updated>2013-05-21T10:41:18.134+02:00</updated><category term='Visual Studio'/><category term='Fluent Assertions'/><category term='WCF RIA Services'/><category term='Architecture'/><category term='Metro'/><category term='Cookbook'/><category term='TFS'/><category term='DevDays10'/><category term='Build 2012'/><category term='Quality'/><category term='Testing'/><category term='C#'/><category term='Coding Guidelines'/><category term='dotnetmag'/><category term='ALM'/><category term='Agile'/><category term='CQRS'/><category term='WCF'/><category term='DevDays09'/><category term='ALM Practices'/><category term='Windows8'/><category term='Events'/><category term='Book'/><category term='Silverlight'/><category term='InRetrospect'/><title type='text'>Dennis Doomen.NET</title><subtitle type='html'>I have been working in the IT for over 14 years, and I'm now the Principal Consultant at Aviva Solutions. I regard myself as being very pragmatic, and I have a lot of experience with ALM, TDD, BDD, DDD,design patterns, architecture, Agile practices, TFS and Silverlight. I've also published Coding Guidelines for C# 3.0 and C# 4.0 and written an open-source framework for verifying unit test behavior called Fluent Assertions.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default?start-index=26&amp;max-results=25'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>299</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-15137028.post-6759773618352053729</id><published>2013-03-12T20:48:00.001+01:00</published><updated>2013-03-16T19:55:24.089+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Entity Framework 5 and 6 vs NHibernate 3 – The State of Affairs</title><content type='html'>&lt;p&gt;It has been &lt;a href="http://www.dennisdoomen.net/2010/03/is-entity-framework-40-ready-for-real.html"&gt;almost two years&lt;/a&gt; since I've last compared NHibernate and Entity Framework, so with the recent &lt;a href="http://blogs.msdn.com/b/adonet/archive/2013/02/27/ef6-alpha-3-available-on-nuget.aspx"&gt;alpha version&lt;/a&gt; of EF 6, it's about time to look at the current state of affair. I've been using NHibernate for more than 6 years so obviously I'm a bit biased. But I can't ignore that EF's feature list is growing and some of the things I like about the NHibernate eco-system such as code-based mappings and automatic migrations have found a place in EF. Moreover, EF is now &lt;a href="http://entityframework.codeplex.com/"&gt;open-source&lt;/a&gt;, so they're accepting &lt;a href="http://entityframework.codeplex.com/sourcecontrol/list/contributions"&gt;pull requests&lt;/a&gt; as well.  &lt;p&gt;&lt;a href="http://www.google.com/url?sa=i&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;frm=1&amp;amp;source=images&amp;amp;cd=&amp;amp;cad=rja&amp;amp;docid=TbN7N1aHwk-jTM&amp;amp;tbnid=uYw4IQNK-t15OM:&amp;amp;ved=0CAUQjRw&amp;amp;url=http%3A%2F%2Figossip.com%2Frocky-sylvester-vs-dolph-who-wins-vote&amp;amp;ei=EoI_UaXUGsOb1AWgpoGQAQ&amp;amp;bvm=bv.43287494,d.ZWU&amp;amp;psig=AFQjCNECStmtzz5TvSN3FSQvfSm9NtVjpg&amp;amp;ust=1363202923885110"&gt;&lt;img style="float: none; margin-left: auto; display: block; margin-right: auto" src="http://static.igossip.com/photos_2/september_2010/valleyboy_70284_Rocky_IV_Sylvester_Stallone_Dolph_Lundgren.jpg" width="500" height="333"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Rather than doing a typical feature-by-feature comparison, I'll be looking at those aspects of an object-relational mapper that I think are important when building large-scale enterprise applications. So let's see how those frameworks match up. Just for your information, I've been looking at &lt;a href="http://blogs.msdn.com/b/adonet/archive/2013/02/27/ef6-alpha-3-available-on-nuget.aspx"&gt;Entity Framework 6 Alpha 3&lt;/a&gt; and &lt;a href="http://nhforge.org/"&gt;NHibernate 3.3.1GA&lt;/a&gt;.  &lt;p&gt;&lt;strong&gt;Support for rich domain models&lt;/strong&gt;  &lt;p&gt;When you're practicing Domain Driven Design it is crucial to be able to model your domain using the right object-oriented principles. For example, you should be able to encapsulate data and only expose properties if that is needed by the functional requirements. If you model an association using a UML &lt;a href="http://www.sparxsystems.com/enterprise_architect_user_guide/modeling_languages/qualifiers.html"&gt;qualifier&lt;/a&gt;, you should be able to implement that using a &lt;font face="Consolas"&gt;IDictionary&amp;lt;T,T&amp;gt;&lt;/font&gt;. Similarly, collection properties should be based on &lt;font face="Consolas"&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/font&gt; or any of the newer &lt;a href="http://visualstudiomagazine.com/articles/2012/08/07/new-read-only-collection-interfaces-for-net.aspx"&gt;read-only collections&lt;/a&gt; introduced in .NET 4.5 so that your collections are protected by external changes.  &lt;p&gt;NHibernate supports all these requirements and adds quite a &lt;a href="http://nhibernate.hibernatingrhinos.com/17/mapping-collections-in-nhibernate-part-1"&gt;lot of flexibility&lt;/a&gt; like ordered and unordered sets. Unfortunately, neither EF5 or 6 supports mapping private fields (&lt;a href="http://entityframework.codeplex.com/wikipage?title=Design%20Meeting%20Notes%20-%20February%2020,%202013"&gt;yet&lt;/a&gt;) nor can you directly use a dictionary class. In fact, EF only supports &lt;font face="Consolas"&gt;ICollections&lt;/font&gt; of entities, so collections of &lt;a href="http://devlicio.us/blogs/casey/archive/2009/02/13/ddd-entities-and-value-objects.aspx"&gt;value objects&lt;/a&gt; are out of the question. One notable type that still isn't fully supported is the enum. It was introduced in EF5, but only if you target .NET 4.5. EF6 will fortunately fixes this so that it is also available in .NET 4.0 applications.  &lt;p&gt;A good ORM should also allow your domain model to be as &lt;a href="http://programmers.stackexchange.com/questions/181931/do-we-achieve-100-persistence-ignorance-solution-if-were-not-using-orms-poco"&gt;persistence ignorant&lt;/a&gt; as possible. In other words, you shouldn't need to decorate your classes with attributes or subclass some framework-provided base-class (something you might remember from Linq2Sql). Both frameworks impose some limitations such as protected default constructors or virtual members, but that's not going to be too much of an issue.  &lt;p&gt;&lt;strong&gt;Vendor support&lt;/strong&gt;  &lt;p&gt;Although Microsoft makes us believe that corporate clients only use SQL Server or SQL Azure, we all know that the opposite is much more true. The big drawback of EF compared to NH is that the latter has all the providers built-in. So whenever a new version of the framework is released you don't have to worry about vendor support.  &lt;p&gt;Both EF5 and NH 3.3 support various flavors of SQL Server/Azure, SQLite, PostgreSQL, Oracle, Sybase, Firebird and DB2. Most of these providers originate from EF 4, so they don’t support code-first (migrations) or the new DBContext façade. EF6 is still an alpha release and its provider model seems to contain some breaking changes so don't expect any support for anything other than Microsoft's own databases anytime soon.  &lt;p&gt;&lt;strong&gt;Support switching databases for automated testing purposes&lt;/strong&gt;  &lt;p&gt;Our architecture uses a repository pattern implementation that &lt;a href="http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=84"&gt;allows swapping&lt;/a&gt; the actual data mapper on-the-fly. Since we're heavily practicing Test Driven Development, we use this opportunity to approach our testing in different ways.  &lt;ol&gt; &lt;li&gt;We use an in-memory Dictionary for unit tests where the subject-under-test simply needs some data to be setup in a specific way (using &lt;a href="http://nat.truemesh.com/archives/000714.html"&gt;Test Data Builders&lt;/a&gt;).  &lt;li&gt;We use an in-memory SQLite database when we want to verify that NHibernate can process the LINQ query correctly and performs sufficiently using &lt;a href="http://www.hibernatingrhinos.com/products/nhprof"&gt;NHProf&lt;/a&gt;.  &lt;li&gt;We use an actual SQL Server for unit tests that verify that our mapping against the database schema is correct.  &lt;li&gt;We have some integration code that interacts with a third-party Oracle system that is tested on SQL Server on a local development box, but uses Oracle on our automated &lt;a href="http://www.specflow.org/specflownew/"&gt;SpecFlow&lt;/a&gt; build.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;So you can imagine switching between database providers without changing the mapping code is quite essential for us.  &lt;p&gt;During development, we decided that we did not care about the actual class that represented the integration tables, so we tried to use the Entity Framework model-first approach. Unfortunately, when you do that, you're basically locking yourself to a particular database. After switching back to our normal NHibernate approach, changing the connection string during deployment was enough to switch between SQL Server and Oracle. Fortunately this has also been possible since EF 4.1 and Jason Short wrote a &lt;a href="http://infinitecodex.com/infinitecodex/post/2011/03/22/Using-EF-41-Code-First-to-support-multiple-database-vendors.aspx"&gt;good&lt;/a&gt; blog post about that.  &lt;p&gt;&lt;strong&gt;Automatic schema migration&lt;/strong&gt;  &lt;p&gt;When you're practicing an agile methodology such as Scrum, you'll probably try to deliver a potentially shippable release at the end of every sprint. Part of being agile is that functionality can be added at any time where some of that might be affecting the database schema. The most traditional way of dealing with that is to generate or hand-write SQL scripts that are applied during deployment. The problem with SQL scripts is that they are tedious to write, might contain bugs, and are often closely coupled to the database vendor. Wouldn't it be great if the ORM framework would support some way of figuring out what version of the schema is being used and automatically upgrade the database scheme as part of your normal development cycle? Or what about the ability to revert the schema to an older version?  &lt;p&gt;The good news that this exists for both frameworks, but with a caveat. For instance, NHibernate doesn't support this out-of-the-box (although you can generate the initial schema). But with the help of another open-source project, &lt;a href="https://github.com/schambers/fluentmigrator/wiki"&gt;Fluent Migrations&lt;/a&gt;, you can get very far. We currently use it in an enterprise system and it works like a charm. The caveat is that the support for the various databases is not always at the same level. For instance, SQLite doesn't allow renaming a column and Fluent Migrations doesn't support it (although theoretically it could create a new column, copy the old data over, and drop the old column). As an example of a fluent migration supporting both an update as well as a rollback, check out this snippet.&lt;pre class="csharpcode"&gt;&lt;font size="2"&gt;[Migration(1)]&lt;br&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; TestCreateAndDropTableMigration: Migration&lt;br&gt;{&lt;br&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Up()&lt;br&gt;    {&lt;br&gt;        Create.Table(&lt;span class="str"&gt;"TestTable"&lt;/span&gt;)&lt;br&gt;            .WithColumn(&lt;span class="str"&gt;"Id"&lt;/span&gt;).AsInt32().NotNullable().PrimaryKey().Identity()&lt;br&gt;            .WithColumn(&lt;span class="str"&gt;"Name"&lt;/span&gt;).AsString(255).NotNullable().WithDefaultValue(&lt;span class="str"&gt;"Anonymous"&lt;/span&gt;);&lt;br&gt;&lt;br&gt;        Create.Table(&lt;span class="str"&gt;"TestTable2"&lt;/span&gt;)&lt;br&gt;            .WithColumn(&lt;span class="str"&gt;"Id"&lt;/span&gt;).AsInt32().NotNullable().PrimaryKey().Identity()&lt;br&gt;            .WithColumn(&lt;span class="str"&gt;"Name"&lt;/span&gt;).AsString(255).Nullable()&lt;br&gt;            .WithColumn(&lt;span class="str"&gt;"TestTableId"&lt;/span&gt;).AsInt32().NotNullable();&lt;br&gt;&lt;br&gt;        Create.Index(&lt;span class="str"&gt;"ix_Name"&lt;/span&gt;).OnTable(&lt;span class="str"&gt;"TestTable2"&lt;/span&gt;).OnColumn(&lt;span class="str"&gt;"Name"&lt;/span&gt;).Ascending()&lt;br&gt;            .WithOptions().NonClustered();&lt;br&gt;&lt;br&gt;        Create.Column(&lt;span class="str"&gt;"Name2"&lt;/span&gt;).OnTable(&lt;span class="str"&gt;"TestTable2"&lt;/span&gt;).AsBoolean().Nullable();&lt;br&gt;&lt;br&gt;        Create.ForeignKey(&lt;span class="str"&gt;"fk_TestTable2_TestTableId_TestTable_Id"&lt;/span&gt;)&lt;br&gt;            .FromTable(&lt;span class="str"&gt;"TestTable2"&lt;/span&gt;).ForeignColumn(&lt;span class="str"&gt;"TestTableId"&lt;/span&gt;)&lt;br&gt;            .ToTable(&lt;span class="str"&gt;"TestTable"&lt;/span&gt;).PrimaryColumn(&lt;span class="str"&gt;"Id"&lt;/span&gt;);&lt;br&gt;&lt;br&gt;        Insert.IntoTable(&lt;span class="str"&gt;"TestTable"&lt;/span&gt;).Row(&lt;span class="kwrd"&gt;new&lt;/span&gt; { Name = &lt;span class="str"&gt;"Test"&lt;/span&gt; });&lt;br&gt;    }&lt;br&gt;    &lt;br&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Down()&lt;br&gt;    {&lt;br&gt;        Delete.Table(&lt;span class="str"&gt;"TestTable2"&lt;/span&gt;);&lt;br&gt;        Delete.Table(&lt;span class="str"&gt;"TestTable"&lt;/span&gt;);&lt;br&gt;    }&lt;br&gt;}&lt;/font&gt;&lt;/pre&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;Entity Framework has something similar built-in since version 5. It's called &lt;a href="http://msdn.microsoft.com/en-US/data/jj591621"&gt;Code-First Migrations&lt;/a&gt; and looks surprisingly similar to Fluent Migrations. Just like the NHibernate solution has some limitations, EF's has as well and that is support from vendors. At the time of this writing not a single vendor supports Code-First Migrations. On the other hand, if you're only using SQL Server, SQL Express, SQL Compact or SQL Azure, there's nothing from stopping you to use it.&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Code-based mapping&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;If you remember the old days of NHibernate, you might recall those ugly XML files that were needed to configure the mapping of your .NET classes to the underlying database. &lt;a href="http://www.fluentnhibernate.org/"&gt;Fluent NHibernate&lt;/a&gt; has been offering a very nice fluent API for replacing those mappings with code. Not only does this prevent errors in the XML, it is also a very refactor-friendly approach. We've been using it for years and the extensive (and customizable) &lt;a href="https://github.com/jagregory/fluent-nhibernate/wiki/Conventions"&gt;convention-based&lt;/a&gt; mapping engine even allows &lt;a href="https://github.com/jagregory/fluent-nhibernate/wiki/Auto-mapping"&gt;auto-mapping&lt;/a&gt; entities to tables without the need of explicit mapping code. &lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;Strangely enough, NHibernate 3.2 has introduced a brand new fluent API that directly competes with Fluent NHibernate. Because of lack of documentation, I've never bothered to look at it, especially since Fluent NHibernate has been doing its job remarkedly. But during my research for this post I noticed that Adam Bar has written a &lt;a href="http://notherdev.blogspot.nl/2012/02/nhibernates-mapping-by-code-summary.html"&gt;very extensive series&lt;/a&gt; on the new API, and he actually managed to raise a renewed interest in the new API. &lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;Until Entity Framework 4.1 the only way to set-up the mapping was through its data model designer (not to be confused with an OO designer). But apparently the team behind it learned from Fluent Nhibernate and decided to introduce their own code-first approach, surprisingly named Code-First. In terms of convention-based mapping, it was quite limited, especially compared to Fluent NHibernate. EF 6 is going to introduce a lot of hooks for changing the conventions, both on property level as well as on class level. &lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Supporting custom types and collections&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;One of the guidelines in my own &lt;a href="http://csharpguidelines.codeplex.com/"&gt;coding guidelines&lt;/a&gt; is to consider wrapping primitive types with more domain-specific types. Conincedentily it is also one of the rules of &lt;a href="http://www.bennadel.com/resources/uploads/2012/ObjectCalisthenics.pdf"&gt;Object Calisthenetics&lt;/a&gt;. In Domain Driven Design these types are called &lt;a href="http://devlicio.us/blogs/casey/archive/2009/02/13/ddd-entities-and-value-objects.aspx"&gt;Value Objects&lt;/a&gt; and their purpose is to encapsulate all the data and behavior associated with a recurring domain concept. For instance, rather than having two separate &lt;font face="Consolas"&gt;DateTime&lt;/font&gt; properties to represent a period and separate methods for determining whether some point of time occurs within that period, I would prefer to have a dedicated &lt;font face="Consolas"&gt;Period&lt;/font&gt; class that contains all that logic. This approach results in a design that contains less duplication and is easier to understand. &lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;Contrary to NHibernate, Entity Framework doesn't offer anything like this and as far as I know, doesn't plan to. NH on the other hand offers a myriad of options for creating custom types, custom collections or even composite types. Granted, you have to do a bit of digging to find the right documentation (and &lt;a href="http://stackoverflow.com/questions/tagged/nhibernate"&gt;StackOverflow&lt;/a&gt; is your friend here), but if you do, it really helps to enrich your domain model. &lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Query flexibility&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;Some would argue that EF's LINQ support is much more mature, and until NH 3.2 I would have agreed. But since then, NH's LINQ support has improved substantially. For instance, during development we use an in-memory SQLite database in our query-related unit tests to make sure the query can actually be executed by NH. Before 3.2, we regularly ran into strange cast exceptions or exceptions because of unsupported expressions. Since 3.2, we've never seen those anymore. &lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;I haven't tried to run all our existing queries against EF, but I have no doubts that it would have any issue with it. In terms of non-LINQ querying, EF supports &lt;a href="http://msdn.microsoft.com/en-us/library/bb387145.aspx"&gt;Entity SQL&lt;/a&gt; as well as native SQL (although I don’t know if all vendors are supported). NHibernate offers the HQL, &lt;a href="http://nhforge.org/blogs/nhibernate/archive/2009/12/17/queryover-in-nh-3-0.aspx"&gt;QueryOver&lt;/a&gt; and Criteria APIs next to native vendor-specific SQL. Both frameworks support stored procedures. All in all plenty of flexibility. &lt;br /&gt;&lt;p&gt;&lt;strong&gt;Extensibility&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;EF 6 uses the &lt;a href="http://entityframework.codeplex.com/wikipage?title=EF%20Configuration%20and%20Extensibility"&gt;service locator&lt;/a&gt; pattern to allow replacing certain aspects of the framework at runtime. This is a good starting point for extensibility, but unfortunately the team always demonstrates this by replacing the pluralization service. As if someone would actually like to do that. Nonetheless, I'm sure the team's plan is to expose more extension points in the near future. &lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;NH has a very extensive set of observable collections called &lt;a href="https://www.google.com/search?q=nhibernate+listeners"&gt;listeners&lt;/a&gt; that can be used to hook &lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;into virtually every part of the framework. We've been using it for cross-cutting concerns, for hooking up auditing services and also for some CQRS related aspects. You can also tweak a lot of NH's behavior through &lt;a href="http://elliottjorgensen.com/nhibernate-api-ref/NHibernate.Cfg/Environment.html"&gt;configuration properties&lt;/a&gt; (although you'll have to Google…eh…Bing for the right examples). &lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Other notable features&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;Each of the frameworks has some unique features that don't fit in any of the other topics I've discussed up to now. A short summary:&lt;br&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Entity Framework 6 adds &lt;font face="Consolas"&gt;async&lt;/font&gt;/&lt;font face="Consolas"&gt;await&lt;/font&gt; support, a feature that NHibernate may never get due to the impact it has on the entire architecture.&lt;br&gt;&lt;br /&gt;&lt;li&gt;It also has built-in support for automatically reconnecting to the database, which is particularly useful for a known issue with SQL Azure.&lt;br&gt;&lt;br /&gt;&lt;li&gt;Both NHibernate as well as the Entity Framework support .NET 4.5, but only the latter gains some significant performance improvements from it. &lt;br&gt;&lt;br /&gt;&lt;li&gt;NHibernate has a unique selling point and that is its very advanced and pluggable &lt;a href="http://ayende.com/blog/3112/nhibernate-and-the-second-level-cache-tips"&gt;2nd level cache&lt;/a&gt;. This has allowed significant performance improvements in one of our projects, simply by caching reference data. &lt;br&gt;&lt;br /&gt;&lt;li&gt;NHibernate offers another unique feature called &lt;a href="http://ayende.com/blog/3979/nhibernate-futures"&gt;Futures&lt;/a&gt; that you can use to compose a set of queries and send them to the database as a single request.&lt;br&gt;&lt;br /&gt;&lt;li&gt;The Entity Framework allows creating a &lt;font face="Consolas"&gt;DBContext&lt;/font&gt; with an existing open connection. As far as I know that's not possible in NHibernate. &lt;br&gt;&lt;br /&gt;&lt;li&gt;Version 6 of the Entity Framework adds spatial support, something for which you need a 3rd party library to get that in NHibernate. Pedro Sousa wrote an &lt;a href="http://build-failed.blogspot.nl/2012/02/nhibernate-spatial-part-1.html"&gt;in-depth&lt;/a&gt; blog post series about that.&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Wrap-up&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;The big difference between Entity Framework and NHibernate from a developer perspective is that the former offers an integrated set of services whereas the latter requires the combination of several open-source libraries. That on itself is not a big issue - that's why we have &lt;a href="http://nuget.org/"&gt;NuGet&lt;/a&gt;, don't we? - but we've noticed that those libraries are not always up-to-date soon enough when new NHibernate versions are released.&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;From that same perspective NHibernate does offer a lot of flexibility and clearly shows its maturity. On the other hand, you could also see that as a potential barrier for new developers. It's just much easier to get started with Entity Framework than with NH. The documentation on Entity Framework is quite comprehensive and even the new functionality for version 6 is extensively documented using &lt;a href="http://entityframework.codeplex.com/wikipage?title=specs"&gt;feature specifications&lt;/a&gt;. The NHibernate &lt;a href="https://github.com/nhibernate/nhibernate-core"&gt;documentation&lt;/a&gt; has always been lagging behind a bit. For instance, the new mapping system is not even mentioned even though the reference documentation mentions the correct version. The information is available, but you just have to search a bit.&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;The fact that the EH is being developed using a Git source control &lt;a href="http://entityframework.codeplex.com/SourceControl/changeset/view/e95ca12e5ae6"&gt;repository&lt;/a&gt; is also a big plus. Just look at the &lt;a href="http://entityframework.codeplex.com/wikipage?title=specs"&gt;many pull requests&lt;/a&gt; they've been taking in. On the other hand, to my surprise somebody moved the NHibernate source code to GitHub while I wasn't paying attention. So on that aspect they are equals.&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;And does NHibernate have a future at all? Some would &lt;a href="http://notherdev.blogspot.nl/2012/09/is-nhibernate-dead.html"&gt;argue&lt;/a&gt; it is dead already. I don't agree though. Just look at the &lt;a href="https://github.com/nhibernate/nhibernate-core/graphs"&gt;statistics&lt;/a&gt; on GitHub; 240 forks, almost 200 pull requests and a lot of commits in the last few months. I do agree that NoSQL solutions like &lt;a href="http://ravendb.net/"&gt;RavenDB&lt;/a&gt; are extremely powerful and offer a lot of fun and flexibility for development, but the fact of the matter is that they are still not widely accepted by enterprises with a history in SQL Server or Oracle. &lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;Nevertheless, the RAD aspect of EF cannot be ignored and is important for small short-running projects where SQL Server is the norm. And for those projects, I would wholeheartedly recommend EF. But for the bigger systems where a NoSQL solution is not an option, especially those based on Domain Driven Design, NHibernate is still the king in town.&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;p&gt;As usual, I might have overlooked a feature or misinterpreted some aspect of both frameworks. If so, leave a comment, email me or drop me a tweet at &lt;a href="https://twitter.com/ddoomen"&gt;@ddoomen&lt;/a&gt;.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/6759773618352053729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=6759773618352053729&amp;isPopup=true' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/6759773618352053729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/6759773618352053729'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2013/03/entity-framework-56-vs-nhibernate-3.html' title='Entity Framework 5 and 6 vs NHibernate 3 – The State of Affairs'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-1689562668840921534</id><published>2013-01-02T21:20:00.001+01:00</published><updated>2013-01-02T21:20:54.138+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Book'/><category scheme='http://www.blogger.com/atom/ns#' term='dotnetmag'/><title type='text'>About ideas that stick</title><content type='html'>&lt;p&gt;A while ago, some business man from the US who travels a lot throughout the US as part of his job, was sitting in his airline's business lounge for a drink. Right after finishing his 2nd, an attractive women approached him and offered him a drink in exchange for somebody to talk to. Somewhere halfway finishing that drink the man passed out and awoke an indeterminate number of hours later……in a bathtub filled with ice.  &lt;p&gt;Totally confused by the situation and without a clue about where he was and what he was doing in this iced bathtub, he noticed a chair next to the tub. On top of the chair there was a hand-written sign saying "Don't Move. Call 911" and a cell phone. After dialing 911, and after explaining the situation to the woman on the phone, she asked "Is there a tube of some kind protruding from your lower back?". The man reached for his back and shockingly discovered that there was indeed something exiting his back. "Try to remain calm sir, but they've probably stolen one of your kidneys"… &lt;p&gt;This story is one of the many examples from the book titled &lt;a href="http://www.amazon.com/Made-Stick-Ideas-Survive-Others/dp/1400064287"&gt;Made to Stick, Why Some Ideas Survive and Others Die&lt;/a&gt; by Chip and Dan Heath. I didn't even have to reread the original version from the book; it just stuck with me. Apparently there's an entire theory that deals with the characteristics a story must have to stick. Don't worry, I'm not going to spoil the reading experience by sharing those characteristics right here.  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-T_pd2lQc-SA/UOSMZoTlu_I/AAAAAAAAJpU/j8ltOuwMdqg/clip_image001%25255B4%25255D.png?imgmax=800"&gt;&lt;img title="clip_image001" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="clip_image001" src="http://lh4.ggpht.com/-yzKUHKcQpKI/UOSMg09s1VI/AAAAAAAAJpc/X6uLdf7nf6k/clip_image001_thumb%25255B1%25255D.png?imgmax=800" width="275" height="413"&gt;&lt;/a&gt; &lt;p&gt;If you are a professional like me who regularly needs to convey some kind of message through a blog post, a presentation or even a tweet, you might learn a thing or two from this book as well. I'm not saying I'm a changed man, but it sure did contain some very useful tips that can help you bring back the message to its core. And if it doesn't bring you anything new after all, the book is still a lot of fun to read. It's packed with anecdotes and real-live stories that will most definitely surprise you.  &lt;p&gt;Oh, and for the record, the above story is a myth &lt;img class="wlEmoticon wlEmoticon-smile" style="border-top-style: none; border-left-style: none; border-bottom-style: none; border-right-style: none" alt="Smile" src="http://lh6.ggpht.com/-dSsSMnRgrvA/UOSWotNHJVI/AAAAAAAAJp4/NkJHCdB2fl8/wlEmoticon-smile%25255B2%25255D.png?imgmax=800"&gt;&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/1689562668840921534/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=1689562668840921534&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/1689562668840921534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/1689562668840921534'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2013/01/about-ideas-that-stick.html' title='About ideas that stick'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/-yzKUHKcQpKI/UOSMg09s1VI/AAAAAAAAJpc/X6uLdf7nf6k/s72-c/clip_image001_thumb%25255B1%25255D.png?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-2730014967211464293</id><published>2012-11-26T21:38:00.001+01:00</published><updated>2012-11-27T20:29:19.334+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ALM'/><category scheme='http://www.blogger.com/atom/ns#' term='Coding Guidelines'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='Quality'/><category scheme='http://www.blogger.com/atom/ns#' term='dotnetmag'/><title type='text'>The all new coding guidelines for C# 3.0, 4.0 and 5.0 have been published!</title><content type='html'>&lt;p&gt;After 50000 downloads and the recent final release of Visual Studio 2012 / C# 5.0 it was about time to do a thorough update of the &lt;a href="http://csharpguidelines.codeplex.com/"&gt;C# Coding Guidelines&lt;/a&gt;. Although most of the guidelines have been preserved, I’ve tried to rewrite several of them using a less formal and less verbose writing style. I’ve also improved the rational for some of them, shortened the introduction section, but added a refactoring heuristic I picked up from &lt;a href="http://lostechies.com/derickbailey/2012/10/31/abstraction-the-rule-of-three"&gt;this&lt;/a&gt; blog post. &lt;/p&gt; &lt;p&gt;Other minor improvements include getting rid of the vague term &lt;em&gt;identifier&lt;/em&gt;, applying the correct usage of the terms &lt;em&gt;arguments&lt;/em&gt; and &lt;em&gt;parameters&lt;/em&gt;, adding more cross-references between guidelines and adding various links to relevant articles. On the esthetic side, I’ve changed all code snippets to Consolas, reduced the line-spacing a bit, and changed the accent color to allow this version to stand out more from previous versions. &lt;/p&gt; &lt;p&gt;&lt;font color="#333333"&gt;&lt;strong&gt;So which guidelines were changed?&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Added a warning to AV1001 “Only create a constructor that returns a useful object” about potentially violating AV1000 and AV1561.  &lt;li&gt;AV1008 “Mark classes that only contain static members as static” now promotes avoiding static classes at all rather than just marking it as static.  &lt;li&gt;Added a reference to the Command Query Separation principle to AV1105 “Use a method instead of a property”.  &lt;li&gt;Added a reference to the new .NET 4.5 read-only collection interfaces to AV1130 “Return an IEnumerable&amp;lt;T&amp;gt; or ICollection&amp;lt;T&amp;gt; instead of a concrete collection class”. &lt;li&gt;Renamed AV1135 “String, list and collection properties should never return a null reference” to include methods and parameters in addition to properties  &lt;li&gt;Rephrased AV1140 “Consider replacing properties using primitive types to use rich value objects” to clarify that I was talking about domain-specific types. &lt;li&gt;Remove the incorrect examples from AV1515 “Don’t use "magic” numbers” &lt;li&gt;Renamed AV1521 “Initialize variables at the point of declaration” to make it clear we want variables to be declared and initialized as a late as possible. &lt;li&gt;Removed the 'method' part of AV1532 “Don’t use nested loops in a method” to say that nested loops should be avoid everywhere. &lt;li&gt;Renamed AV1535 “Add a block after all flow control keywords, even if it is empty” so that it includes concrete keywords rather than the vague 'flow control keywords'  &lt;li&gt;Added a reference to AV1553 “Only use optional parameters to replace overloads” about Eric Lippert’s post on &lt;a href="http://blogs.msdn.com/b/ericlippert/archive/2011/05/09/optional-argument-corner-cases-part-one.aspx"&gt;optional parameter corner cases&lt;/a&gt;. &lt;li&gt;Removed an example from AV1720 “Name methods using verb-object pair” because it conflicted with some of the LINQ extension methods introduced in .NET 3.0.  &lt;li&gt;Rewrote and renamed AV1725 “Name namespaces according a well-defined pattern” to clearly explain the valid aspects of a namespace rather than emphasizing a particular pattern. &lt;li&gt;Changed the example in AV1735 “Use a verb or verb phrase to name an event” to use a generic event handler delegate. &lt;li&gt;Added a reference to to the .NET 4.5 read-only collection classes to AV1800 “Consider using Any() to determine whether an IEnumerable&amp;lt;T&amp;gt; is empty”.&amp;nbsp; &lt;li&gt;Added a statement to AV2207 “Don’t hardcode strings that change based on the deployment” that deployment-specific settings should be in the application configuration files rather than hard-coded or in a custom configuration file.  &lt;li&gt;Added a remark to AV2400 “Use a common layout” not to interweave the &lt;em&gt;from&lt;/em&gt; expressions with &lt;em&gt;where conditions.&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;And what did I add?&lt;br&gt;&lt;/strong&gt;The following guidelines have been added, of which, for obviously reasons, most are related to C# 5.0.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Added AV1137 "Define parameters as specific as possible" to prevent people from passing in entire objects even though a method might only need a specific property’s value. &lt;li&gt;Added AV1215 "Properly handle exceptions in asynchronous code" to explain the differences between exceptions raised in Actions and await blocks. &lt;li&gt;Added AV1523 "Initialize each variable on a separate line" to prevent some ugly code. &lt;li&gt;Added AV1739 "Use an underscore for irrelevant lamba parameters" as suggested by &lt;a href="https://twitter.com/JamesLanng"&gt;James Lanng&lt;/a&gt;. &lt;li&gt;Added AV1755 "Postfix asynchronous methods with Async of TaskAsync"  &lt;li&gt;Added AV1820 "Only use async for low-impact long-running activities"  &lt;li&gt;Added AV1825 "Prefer Task.Run for CPU intensive activities"  &lt;li&gt;Added AV1830 "Beware of mixing up await/async with Task.Wait"  &lt;li&gt;Added AV1835 "Beware of async/await deadlocks in single-threaded environments"  &lt;ul&gt;&lt;!--EndFragment--&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;“But wait, didn’t you remove anything?”&lt;br&gt;&lt;/strong&gt;Of course I did! Why do you think the number of pages went from 31 to 27? Well, yes, reducing line-spacing was part of that, but I actually did remove some guidelines.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Removed AV1120 "Use a public static readonly field to define predefined value objects " since I think it is not that important and not used very often. &lt;li&gt;Removed AV1245 “Don’t add extension methods to the same namespace as the extended class” because I think it is pretty farfetched if you create a class in a .NET namespace. &lt;li&gt;Removed AV1526 “Use an enumeration instead of a list of strings if the list of values is finite” since enumerations are so common these days, I hope nobody thinks of an alternative solution. &lt;li&gt;Merged AV1546 “Prefer conditional statements instead of simple if-else constructs” into AV1545 “Don’t use selection statements instead of a simple assignment or initialization”. &lt;li&gt;Removed AV1580 “Consider abstracting an external dependency or 3rd party component” because its essence is already covered by other guidelines and the introduction discussing SOLID principles.&amp;nbsp;&amp;nbsp; &lt;li&gt;Removed AV2211 “Avoid suppressing specific compiler warnings” since I wonder how many developers even know how to suppress compiler warnings. &lt;li&gt;Removed AV2315 “Don’t use /* */ for comments” since we want to avoid inline comments anyhow.&lt;!--EndFragment--&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;You can download the PDFs of the document itself, the cheat sheet, the Visual Studio 2010/2012 Code Analysis rule sets, and the ReSharper 6/7 Code Analysis settings from the &lt;a href="http://csharpguidelines.codeplex.com/releases/view/98254"&gt;download page&lt;/a&gt; on the CodePlex landing page. &lt;/p&gt; &lt;p&gt;And don’t forget! If you have any feedback, additions or any remarks, contact me through &lt;a href="https://twitter.com/#!/ddoomen"&gt;Twitter&lt;/a&gt; or &lt;a href="mailto:dennis.doomen@avivasolutions.nl"&gt;email&lt;/a&gt;. &lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/2730014967211464293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=2730014967211464293&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/2730014967211464293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/2730014967211464293'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/11/the-all-new-coding-guidelines-for-c-30.html' title='The all new coding guidelines for C# 3.0, 4.0 and 5.0 have been published!'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-650870894638221887</id><published>2012-11-05T20:29:00.001+01:00</published><updated>2012-11-05T20:36:26.591+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows8'/><category scheme='http://www.blogger.com/atom/ns#' term='Events'/><category scheme='http://www.blogger.com/atom/ns#' term='dotnetmag'/><title type='text'>Looking back at Build 2012</title><content type='html'>&lt;p&gt;A question which was asked many times during the week was whether or not this trip to Build 2012 in Redmond was worth the time and money. &lt;a href="http://lh4.ggpht.com/-imZ2wLHsjBs/UJgTc5c8mHI/AAAAAAAAJis/4JXUgy2IdWQ/s1600-h/image7.png"&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="http://lh4.ggpht.com/-b0DmDmOlfqM/UJgTe87QSYI/AAAAAAAAJi0/WdwZBOp4w4w/image_thumb3.png?imgmax=800" width="364" height="175"&gt;&lt;/a&gt;  &lt;p&gt;Even after &lt;a href="http://www.dennisdoomen.net/search/label/Build%202012"&gt;four days&lt;/a&gt; of raw content, there is no short answer here. As Dennis Vroegop &lt;a href="http://geekswithblogs.net/dvroegop/archive/2012/11/02/build-2012-the-first-post.aspx"&gt;clearly illustrated&lt;/a&gt;, the organization was definitely not up to the task just yet. The big problem is that I was expecting to visit a conference in the style of the Professional Developers Conference (which it clearly wasn't). Since Build is organized by the Windows division I should have known that they would primarily focus on Windows 8 and Windows Phone 8. On the other, the session list wasn't disclosed until a day ahead, which fed my hope to learn a lot of really new stuff. Many attendees I spoke to had the exact same thing.  &lt;p&gt;On the other hand, we did receive 1200 USD worth of gadgets, and me being there give me a myriad of opportunities to network with other people in the community. The time in Redmond also kept me away from the daily challenges of my current project which allowed me the necessary peace to actually dig a bit deeper into the content. Granted, I won't go home with the mind-blowing ideas and insights such as those you get after visiting a &lt;a href="http://qconsf.com/"&gt;QCon&lt;/a&gt; or the &lt;a href="http://www.ndcoslo.com/"&gt;Norwegian Developers Conference&lt;/a&gt;. But at least Microsoft managed to motivate me to start the &lt;a href="http://www.dennisdoomen.net/2012/10/planning-windows-8-cookbook.html"&gt;Boiling Point RT&lt;/a&gt; project, a revival of the Silverlight Cookbook for Windows 8.  &lt;p&gt;Although Windows 8 is a major improvement over Windows 7 (just read the &lt;a href="http://blogs.msdn.com/b/b8/?Redirected=true"&gt;Building Windows 8&lt;/a&gt; blog post series if you don’t believe me), but I’ve always had some doubts about the added value of the new Windows Store on an ordinary desktop PC. But this all changed after a week of using my newly acquired Surface RT. Windows 8 on a tablet is absolutely awesome. Almost everybody who I showed the device to was genuinely impressed with the sleek design, the operating system and some of the better apps. The same can be said about the Lumia 920. I really liked my Lumia 800 and found Windows Phone 7 a major improvement over Android. But I’ve always felt that WP7 was a bit limited on the customization level and lacked some decent apps. For instance, WhatsApp and Facebook were painfully slow. But this all changed with the combination of Windows Phone 8 and the Lumia 920. And the fact of the matter is that I would never have know this if I hadn’t been there. &lt;p&gt;But the question remains if it was really worth the time and money? For me it did, but that's mainly because the content was not the most important aspect for me. There were so many opportunities for meeting new people, extending my social network, and having in-depth discussions with other experienced developers, that alone makes it worth the trouble. However, it is questionable whether I will visit another Build if I get the choice. I’ll probably choose a more advanced conference such as QCon. On the other hand, maybe Microsoft will improve on itself next year or reintroduce the PDC. You’ll never know….&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/650870894638221887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=650870894638221887&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/650870894638221887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/650870894638221887'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/11/looking-back-at-build-2012.html' title='Looking back at Build 2012'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/-b0DmDmOlfqM/UJgTe87QSYI/AAAAAAAAJi0/WdwZBOp4w4w/s72-c/image_thumb3.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-8532691364114806471</id><published>2012-11-04T14:19:00.001+01:00</published><updated>2012-11-05T20:34:41.620+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows8'/><category scheme='http://www.blogger.com/atom/ns#' term='Events'/><category scheme='http://www.blogger.com/atom/ns#' term='dotnetmag'/><category scheme='http://www.blogger.com/atom/ns#' term='Build 2012'/><title type='text'>Build Day 4: WP8, Line-of-Business, Web Essentials and lots of laughs</title><content type='html'>&lt;p&gt;Here we are at the fourth and last day of &lt;a href="http://www.buildwindows.com/"&gt;Microsoft Build 2012&lt;/a&gt;. That so many people showed up at the first session is quite surprising considering the attendee party that went on until midnight in downtown Seattle. It was a typical attendee party; free food and drinks and live music. Since being amongst 2000 dudes is not our something we enjoy a lot, after grabbing something to eat, Jonne and I bailed out and took a cab to Queen Anne's to enjoy a few drinks at &lt;a href="http://www.pesoskitchen.com/"&gt;Peso’s&lt;/a&gt;.  &lt;p&gt;&lt;img style="float: none; margin-left: auto; display: block; margin-right: auto" alt="" src="http://sphotos-b.ak.fbcdn.net/hphotos-ak-ash3/536535_10151341852703714_1065254745_n.jpg" width="640" height="360"&gt; &lt;p&gt;Anyway, this first session was supposed to be a &lt;a href="http://channel9.msdn.com/Events/Build/2012/3-005"&gt;deep-dive&lt;/a&gt; on Windows Phone 8 internals. Although we never actual submerged, it was interesting to learn what they did to significantly decrease the start-up time of apps. And it shows, even painstakingly slow apps like FaceBook and WhatsApp start within a fraction of a second on our Lumia 920. I particularly like the way they employ the cloud to create optimized assemblies from the ones we submit through the App store. And did you know WP8 is still largely build on top of Silverlight? In fact, this was probably the only reference to Silverlight at all.  &lt;p&gt;I have to mention one big issue with this conference though….Indian speakers. I would expect that Microsoft would at least make sure that all their speakers are experienced, trained and….understandable. I have nothing against Indian speakers, but guys, at least try to pronounce the things the way they should be. Looking at the Build &lt;a href="https://twitter.com/search?q=%23bldwin&amp;amp;src=typd"&gt;twitter stream&lt;/a&gt; proved that I was not the only one suffering from this.  &lt;p&gt;With another of those annoying bus trips done, we moved to a &lt;a href="http://channel9.msdn.com/Events/Build/2012/3-120"&gt;line-of-business talk&lt;/a&gt; with a huge line of people waiting to get in. Dennis Vroegop already shared &lt;a href="http://geekswithblogs.net/dvroegop/archive/2012/11/02/build-2012-the-first-post.aspx"&gt;his opinions&lt;/a&gt; about the transportation problem, so I won’t have to. Fortunately a majority of the Dutch community was part of this line, so that solved my problem a bit. The room was packed, even so that they decided to move the entire audience to another room just before the talk started. The talk was about building LOB apps, but spend the majority of its slot on synchronizing the app database (using a modified version of &lt;a href="http://www.infoq.com/news/2012/07/sqlite-metro-winmobile"&gt;SQLite&lt;/a&gt;) using a customized version of the now deprecated Sync framework. The tooling look quite impressive and will become available soon.  &lt;p&gt;&lt;img style="float: none; margin-left: auto; display: block; margin-right: auto" alt="" src="http://sphotos-h.ak.fbcdn.net/hphotos-ak-ash3/54248_10151340811053714_1700215919_o.jpg" width="640" height="480"&gt; &lt;p&gt;I then went to a small meet up organized by &lt;a href="https://twitter.com/ElizAyer"&gt;Elizabeth Ayer&lt;/a&gt; from RedGate to talk about open-source projects. To my surprise &lt;a href="http://haacked.com/"&gt;Phil Haack&lt;/a&gt;, the author of &lt;a href="https://nuget.org/"&gt;NuGet&lt;/a&gt; a big catalyst for my &lt;a href="https://nuget.org/packages/FluentAssertions"&gt;Fluent Assertions&lt;/a&gt; project, also showed up as well as fellow Developer Developer Developer speaker &lt;a href="https://twitter.com/DaveDev"&gt;Dave Evans&lt;/a&gt;. We had an interesting conversation on how companies can and should sponsor OSS developers. We didn't actually agree whether this should be done in the form of money or extra time. Money wouldn’t solve the problem of lack of time, so in my opinion, I would prefer some dedicated time. We also talked about the future of .NET, about Git and about Scott Guthrie's influence on getting a lot of Microsoft's products open-sourced. The hour passed by too quickly, because me and Elizabeth felt like we could have continued for hours.  &lt;p&gt;The &lt;a href="http://channel9.msdn.com/Events/Build/2012/3-032"&gt;third session&lt;/a&gt; I attended was led by &lt;a href="http://madskristensen.net/"&gt;Mads Kristensen&lt;/a&gt; of the ASP.NET development team and covered the new features of the &lt;a href="http://www.asp.net/vnext"&gt;Fall Update&lt;/a&gt; of ASP.NET introduced. I've heard and seen most of it already throughout the other sessions. Nevertheless, the most noticeable part of his talk was the demonstration of &lt;a href="http://visualstudiogallery.msdn.microsoft.com/07d54d12-7133-4e15-becb-6f451ea3bea6"&gt;Web Essentials 2012&lt;/a&gt;, a small add-on for Visual Studio 2012 that introduces a shipload of little HTML and JavaScript options. I'll most definitely going to install that little gem as soon as I get back to work.  &lt;p&gt;Fortunately, in all their wisdom, the conference organizers did manage to schedule the &lt;a href="http://channel9.msdn.com/Events/Build/2012/3-028"&gt;perfect session&lt;/a&gt; for concluding this conference. Scott Hanselman and John Galloway took stage and managed to give the most entertaining (and still interesting) session of the entire conference. We got to play an on-line space game hosted using SignalR and watched how Scott completely bypassed the session's script, thereby utterly confusing his co-host Josh. All in all a brilliant session that you should most definitely &lt;a href="http://channel9.msdn.com/Events/Build/2012/3-028"&gt;watch&lt;/a&gt;. &lt;/p&gt; &lt;p&gt;By the way, the party was next to the &lt;a href="http://www.spaceneedle.com/"&gt;Space Needle&lt;/a&gt;, so check out this night shot made with our new &lt;a href="http://www.nokia.com/global/products/phone/lumia920/"&gt;Lumia 920&lt;/a&gt;. Neat, isn't it?  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/-ciAebaXTVzI/UJZrcyIZrjI/AAAAAAAAJiI/xyMAsueIiFs/s1600-h/WP_20121101_017%25255B6%25255D.jpg"&gt;&lt;img title="WP_20121101_017" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="WP_20121101_017" src="http://lh3.ggpht.com/-fMmUQyTOoyI/UJZrd-jJM8I/AAAAAAAAJiM/1IfX2-0z0E8/WP_20121101_017_thumb%25255B2%25255D.jpg?imgmax=800" width="274" height="484"&gt;&lt;/a&gt;&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/8532691364114806471/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=8532691364114806471&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/8532691364114806471'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/8532691364114806471'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/11/build-day-4-wp8-line-of-business-web.html' title='Build Day 4: WP8, Line-of-Business, Web Essentials and lots of laughs'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/-fMmUQyTOoyI/UJZrd-jJM8I/AAAAAAAAJiM/1IfX2-0z0E8/s72-c/WP_20121101_017_thumb%25255B2%25255D.jpg?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-3190207121067232282</id><published>2012-11-02T08:37:00.001+01:00</published><updated>2012-11-05T20:34:41.616+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows8'/><category scheme='http://www.blogger.com/atom/ns#' term='Events'/><category scheme='http://www.blogger.com/atom/ns#' term='dotnetmag'/><category scheme='http://www.blogger.com/atom/ns#' term='Build 2012'/><title type='text'>Build Day 3: ASP.NET MVC, TypeScript, SignalR and Node.Js</title><content type='html'>&lt;p&gt;So at this 3rd day here at &lt;a href="http://www.buildwindows.com/"&gt;Microsoft Build 2012&lt;/a&gt;, I'm actually getting lucky. Three great sessions in a row is obviously not something I've seen before. Hey, maybe I'll get to see four great sessions tomorrow. Anyway, with some of the technical debt from last night's Beerfest and a Halloween party in Bellevue, I managed to attend most of Scott Hanselman's &lt;a href="http://channel9.msdn.com/Events/Build/2012/3-027"&gt;session&lt;/a&gt;. Regardless of whether the content was new or not, each of his sessions are pure entertainment. &lt;p&gt;&lt;img style="float: none; margin-left: auto; display: block; margin-right: auto" src="http://www.peoriagermans.com/Images/prost.jpg" width="421" height="480"&gt; &lt;p&gt;But the highlight of the day is most definitely the &lt;a href="http://channel9.msdn.com/Events/Build/2012/3-012"&gt;TypeScript talk&lt;/a&gt; by technical fellow Anders Hejlsberg. It's ironic to consider that the guy that is practically the embodiment of C# is now passionately selling JavaScript. But, all things equal, he managed to fully and utterly convince me. Those existing blog posts simply don't do justice to the power of TypeScript as was demonstrated in his (&lt;a href="http://channel9.msdn.com/Events/Build/2012/3-012"&gt;recorded&lt;/a&gt;) session. I think it's one of the best things since C#. &lt;p&gt;Apart from the content, a conference on this scale is an excellent opportunity to meet new people and enlarge your community network. As of today, my community even includes people from Romania. I also met &lt;a href="https://twitter.com/wynapse"&gt;the guy&lt;/a&gt; behind the &lt;a href="http://www.silverlightcream.com/"&gt;SilverlightCream&lt;/a&gt; and &lt;a href="http://www.silverlightcream.com/"&gt;WindowsDevNews&lt;/a&gt;. Since I don't blog about Silverlight anymore, he kindly reminded me of his renewed focus on anything Windows 8. Just in time to submit &lt;a href="http://www.dennisdoomen.net/2012/10/planning-windows-8-cookbook.html"&gt;my plans&lt;/a&gt; for a Windows Store Cookbook… &lt;p&gt;&lt;img style="float: none; margin-left: auto; display: block; margin-right: auto" src="http://blog.maartenballiauw.be/image.axd?picture=image_153.png" width="282" height="189"&gt; &lt;p&gt;I never really looked at &lt;a href="https://github.com/SignalR/SignalR"&gt;SignalR&lt;/a&gt; before, so a level 300 session is quite welcome, especially if it is performed by two dudes that manage to keep the talk light and humorous. SignalR is pretty cool if you want to add some simple asynchronous communication between multiple browser windows, even if you use different browsers. It feels much more elegant than using DOM navigation to hack yourself from one window to another. And the best of this all is the fact that SignalR is a Microsoft supported open-source product with a really bright future. &lt;p&gt;&lt;img style="float: none; margin-left: auto; display: block; margin-right: auto" src="http://upload.wikimedia.org/wikipedia/commons/9/9d/Commodore64.jpg" width="600" height="380"&gt; &lt;p&gt;In the remainder of the day I wandered from one session to the other, just to find something that interests me. One of them had a memorable intro that showed the Commodore 64 emulator running an infinite Basic loop. But that session was for the most part repeating the TypeScript introduction earlier that day. Looking at the large number of people leaving and entering the session, once again reinforced my suspicion that more people were looking for some decent content.  &lt;p&gt;Well, at least we had the attendee party in downtown Seattle to look forward to.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/3190207121067232282/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=3190207121067232282&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/3190207121067232282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/3190207121067232282'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/11/build-day-3-aspnet-mvc-typescript.html' title='Build Day 3: ASP.NET MVC, TypeScript, SignalR and Node.Js'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-4502107784929398067</id><published>2012-11-01T16:12:00.001+01:00</published><updated>2012-11-05T20:34:41.617+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows8'/><category scheme='http://www.blogger.com/atom/ns#' term='Events'/><category scheme='http://www.blogger.com/atom/ns#' term='dotnetmag'/><category scheme='http://www.blogger.com/atom/ns#' term='Build 2012'/><title type='text'>Build Day 2: Azure, JavaScript and even more XAML and Windows Phone</title><content type='html'>&lt;p&gt;Because day 2 of the Build conference wasn't any different, it seems that I must learn to accept that a maximum of two good sessions per day is going to be the standard. Fortunately the keynote was top notch with both &lt;a href="http://www.hanselman.com/blog/"&gt;Scott Hanselman&lt;/a&gt; and &lt;a href="http://weblogs.asp.net/scottgu/"&gt;Scott Guthrie&lt;/a&gt; taking stage. They showed some of the power the Windows Azure platform provides these days. It really feels like that every time I check the &lt;a href="https://account.windowsazure.com/Home/Index"&gt;Azure website&lt;/a&gt; they've added another shipload of features. Especially the integration between the services is something that really shines. And did I already mention how I love the look-and-feel of the Azure management portal? &lt;p&gt;&lt;img style="float: none; margin-left: auto; display: block; margin-right: auto" src="http://csgsitestorage.blob.core.windows.net/picture/12102416102.png" width="600" height="378"&gt; &lt;p&gt;One other cool thing that happened is that Microsoft announced that the &lt;a href="http://tfs.visualstudio.com/"&gt;Team Foundation Service&lt;/a&gt; is now in production. It will be a free service for teams up to 5 developers…forever. Since this is something our company has been looking forward to for a while now, I was a bit disappointed that the pricing is still to be announced. In fact, the landing page for this service states that this will not be announced until the &lt;a href="http://tfs.visualstudio.com/en-us/pricing/information/"&gt;beginning of 2013&lt;/a&gt;. Bummer…. &lt;p&gt;&lt;img style="float: none; margin-left: auto; display: block; margin-right: auto" src="http://venturebeat.files.wordpress.com/2012/10/screen-shot-2012-10-31-at-10-07-01-am.png" width="600" height="319"&gt; &lt;p&gt;After bailing out from an extremely boring XAML session I happened to run into a JavaScript session led by &lt;a href="http://phillydotnet.org/speakers/amanda-silver/"&gt;Amanda Silver&lt;/a&gt;, one of the rare female speakers at this conference. And boy, she knew what she was talking about. I'm not yet an JavaScript expert, but I was blown away hoe much one construct can make a difference compare to another performance wise. It's incredible to learn how Microsoft managed to optimize the way the IE10 JavaScript engine works internally. If you have ever attended an in-depth session on LINQ providers by Bart de Smet or a talk by Eric Meijer on the duality of IQuerable, you know what I mean. I'm in no way qualified for sharing some of her content here, so make sure you check out the &lt;a href="http://channel9.msdn.com/Events/Build/2012/4-000"&gt;slides&lt;/a&gt;. &lt;p&gt;&lt;img style="float: none; margin-left: auto; display: block; margin-right: auto" src="http://img159.imageshack.us/img159/46/molens1800mf5.jpg" width="600" height="400"&gt; &lt;p&gt;Regardless of where you are, you always run into Dutch people somewhere somehow. So during lunch we ran into some 'colleagues' from a competitor and ended up discussing &lt;a href="http://phillydotnet.org/speakers/amanda-silver/"&gt;Event Sourcing&lt;/a&gt; and synchronization challenges when building large scale systems. Similarly, I was also recognized by some people which I only know through Twitter. It definitely feels a bit awkward if you don't recognize somebody, at least, not until you get to know their Twitter IDs…. &lt;p&gt;The two others sessions were both about apps again. The &lt;a href="http://channel9.msdn.com/Events/Build/2012/3-116"&gt;one&lt;/a&gt; hosted by &lt;a href="http://channel9.msdn.com/Events/Speakers/Chris-Anderson"&gt;Chris Anderson&lt;/a&gt; clearly out-leveled most other sessions even though the content wasn't particularly new. As I said yesterday, it seems as if the primary audience is developers who haven't been paying a lot of attention the last year. Nonetheless, Chris once again illustrated how easy it is to integrate the search charm into your Windows Store app. I can highly recommend viewing the &lt;a href="http://channel9.msdn.com/Events/Build/2012/3-116"&gt;recording&lt;/a&gt;. The other one was hosted by a British chap and dealt mostly with the (powerful) combination of &lt;a href="http://www.windowsazure.com/en-us/develop/mobile/"&gt;Azure Mobile Services&lt;/a&gt; and WP8 devices. It’s &lt;a href="http://weblogs.asp.net/scottgu/archive/2012/10/16/windows-azure-mobile-services-new-support-for-ios-apps-facebook-twitter-google-identity-emails-sms-blobs-service-bus-and-more.aspx"&gt;ridiculously easy&lt;/a&gt; to connect a WP device with an Azure backend without the need to build your own server. Once gain proof Microsoft wants people to start building apps (hence the free Surface and Lumina 920). What did disturb me (and I did knew about this upfront) is the fact that you are supposed to tweak the Azure services &lt;a href="http://weblogs.asp.net/scottgu/archive/2012/10/16/windows-azure-mobile-services-new-support-for-ios-apps-facebook-twitter-google-identity-emails-sms-blobs-service-bus-and-more.aspx"&gt;using JavaScript&lt;/a&gt;. Definitely not something I'm looking forward to.  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/scottgu/image_4122B876.png"&gt;&lt;img title="image" style="float: none; margin-left: auto; display: block; margin-right: auto" border="0" alt="image" src="http://weblogs.asp.net/blogs/scottgu/image_thumb_452F96F9.png" width="600" height="273"&gt;&lt;/a&gt; &lt;p&gt;Talking about that Surface, it's a remarkable device that managed to completely replace my Acer Aspire that I've been bringing to conferences and events. In fact, I've written this blog post using &lt;a href="http://apps.microsoft.com/webpdp/en-us/app/onenote/f022389f-f3a6-417e-ad23-704fbdf57117"&gt;OneNote MX&lt;/a&gt;, the Windows Store equivalent for Microsoft OneNote but optimized for touch. The only thing I had to do on my laptop is posting the blog using Windows Live Writer. It will just be a matter of time before we'll get a decent blogging app…. and a Twitter app, and a Facebook app, and…but that's an other story…&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/4502107784929398067/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=4502107784929398067&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/4502107784929398067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/4502107784929398067'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/11/build-day-2-azure-javascript-and-even.html' title='Build Day 2: Azure, JavaScript and even more XAML and Windows Phone'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-2184909155316562485</id><published>2012-10-31T03:01:00.001+01:00</published><updated>2012-11-05T20:34:41.614+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows8'/><category scheme='http://www.blogger.com/atom/ns#' term='Events'/><category scheme='http://www.blogger.com/atom/ns#' term='dotnetmag'/><category scheme='http://www.blogger.com/atom/ns#' term='Build 2012'/><title type='text'>Build Day 1: Surface, WP8, TFS, Windows Design Guidelines</title><content type='html'>&lt;p&gt;Day 1 of Microsoft Build was in some way disappointing and at the same time exhilarating. To be honest, I was expecting to be updated on the new stuff Microsoft plans for the near future. The fact that the session list was not disclosed until a day ahead also helped reinforce that expectation. But instead, we got lots and lots of sessions on building apps for Windows 8 and Windows Phone 8. Maybe my expectations on Build are clouded with my experiences attending the Professional Developers Conference in 2008 and 2009. Maybe another problem is that Build is paid by the Windows Division whereas the PDC was mostly organized by the Development Division (and we all know how &lt;a href="http://www.riagenic.com/archives/960"&gt;Steven and Somas get along together&lt;/a&gt;). On the other hand, Build 2012 did deliver on the hardware side by giving each and every attendee a Surface RT as well as Nokia's flagship, the &lt;a href="http://www.nokia.com/us-en/products/phone/lumia920/"&gt;Lumia 920&lt;/a&gt;. That's not something anybody dared dreaming off. And yes, we all know we're going to be Microsoft's marketing tool for the next months, but it's still incredibly cool. &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-YPCc5D2XOug/UJCGZ-PhZqI/AAAAAAAAJhw/o7oHsECOZCg/s1600-h/clip_image001%25255B4%25255D.png"&gt;&lt;img title="clip_image001" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="clip_image001" src="http://lh3.ggpht.com/-C-hQSbpxxXs/UJCGcQURNUI/AAAAAAAAJh4/4NlI6GI67Ps/clip_image001_thumb%25255B1%25255D.png?imgmax=800" width="405" height="484"&gt;&lt;/a&gt; &lt;p&gt;Anyway, I started the day listening to &lt;a href="http://blogs.msdn.com/b/buckh/"&gt;Buck Hodges&lt;/a&gt;, product manager of the TFS suite, talking about &lt;a href="http://channel9.msdn.com/Events/Build/2012/2-004"&gt;how they employ Scrum&lt;/a&gt; within their department. I was happy to hear that they approach product development similarly to how my current client is doing it. Their cadence is to plan 3 week sprints concluded with a one week verification before they release to production. They rely heavily on automated testing, but at the same time balance 6 developers with 5 testers. Granted, their teams are a bit on the big side (5 + 6 + 1 or 2 product managers), it clearly shows how much they value quality. Buck also shared how they deal with branches. In general they try to avoid feature branches (which resonates well with Martin Fowler's &lt;a href="http://martinfowler.com/bliki/FeatureBranch.html"&gt;opinions&lt;/a&gt; on that), and most changes are directly committed to the main branch. The only exception to this is when commits are too disruptive. As an example of this, Buck mentioned the data access changes required to complete the transition from the relatively expensive SQL Azure to Azure Table Storage. &lt;p&gt;The other session that was worth my time was dealing with &lt;a href="http://channel9.msdn.com/Events/Build/2012/3-136"&gt;web standards&lt;/a&gt;. It was a good reminder of how standards compliance works, what browsers are being used currently, and how libraries like Modernizr can help you with that. The highlight of the session was the reference to &lt;a href="http://www.browserstack.com/"&gt;browserstack.com&lt;/a&gt;, a website dedicated to testing your website against a myriad of browsers. I also attended some sessions on the user interface and interaction design of Windows 8, but most of what was told is already common knowledge. Only people who have been living in a cage for the last year (one deep enough to not receive any Wi-Fi signals), may have heard something new. Let's hope the sessions planned for day 2 are a bit better.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/2184909155316562485/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=2184909155316562485&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/2184909155316562485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/2184909155316562485'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/10/build-day-1-surface-wp8-tfs-windows.html' title='Build Day 1: Surface, WP8, TFS, Windows Design Guidelines'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/-C-hQSbpxxXs/UJCGcQURNUI/AAAAAAAAJh4/4NlI6GI67Ps/s72-c/clip_image001_thumb%25255B1%25255D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-4679455165544888934</id><published>2012-10-31T00:39:00.001+01:00</published><updated>2012-10-31T16:12:41.792+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows8'/><category scheme='http://www.blogger.com/atom/ns#' term='Fluent Assertions'/><category scheme='http://www.blogger.com/atom/ns#' term='Architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='Cookbook'/><title type='text'>Planning the Windows 8 Cookbook</title><content type='html'>&lt;p&gt;I'm currently at Microsoft's &lt;a href="http://www.buildwindows.com/"&gt;Build&lt;/a&gt; conference and we're all receiving a &lt;a href="http://www.microsoft.com/Surface/en-US"&gt;Surface RT&lt;/a&gt; tablet. That means it's a great moment to talk about my plans for the Windows 8 Cookbook. I know, I know, it's a cheesy name so just be aware that I'm open to better suggestions. Since Silverlight is mostly &lt;a href="http://www.liveside.net/2012/08/22/is-this-what-really-happened-to-silverlight/"&gt;dead&lt;/a&gt;, I've decided to revive the &lt;a href="http://silverlightcookbook.codeplex.com/"&gt;Silverlight Cookbook&lt;/a&gt; by rebuilding it as a Windows Store app instead. This time I'm also going to get some help on the UI design so hopefully it will finally get a decent looking front-end.  &lt;p&gt;&lt;img style="float: none; margin-left: auto; display: block; margin-right: auto" src="http://goodereaderimages.goodereader.netdna-cdn.com/blog/uploads/images/win8storeconsumerpreview_large_verge_medium_landscape.jpg" width="600" height="338"&gt;  &lt;p&gt;Another thing I'm considering is to host the entire project on &lt;a href="https://github.com/"&gt;GitHub&lt;/a&gt;. I've already build up some experience with &lt;a href="http://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;frm=1&amp;amp;source=web&amp;amp;cd=1&amp;amp;cad=rja&amp;amp;ved=0CCMQFjAA&amp;amp;url=http%3A%2F%2Fcodeplex.codeplex.com%2Fwikipage%3Ftitle%3DUsing%2520Git%2520with%2520CodePlex&amp;amp;ei=rVyQUPKmBqnU4QSDu4BA&amp;amp;usg=AFQjCNGOA7JRFkdZlawOPMluBFE665sR4g"&gt;Git on CodePlex&lt;/a&gt; as the result of a recent conversion of my &lt;a href="http://fluentassertions.codeplex.com/"&gt;Fluent Assertions&lt;/a&gt; project, but I'd like to get to know how that compares to the GitHub experience. Whether or not it's going to be CodePlex or GitHub, I will be accepting pull requests. And if you are interested in contributing a bit more directly, I'm also looking forward to people who want to help me build the project.  &lt;p&gt;To give you some more context on the technical platform behind the cookbook, here are some of the things I'd like to use:  &lt;ul&gt; &lt;li&gt;&lt;a href="http://mikaelkoskinen.net/post/caliburn-micro-winrt-getting-started.aspx"&gt;Caliburn.Micro for WinRT&lt;/a&gt;  &lt;li&gt;&lt;a href="http://code.google.com/p/autofac/downloads/list"&gt;Autofac for Portable Libraries&lt;/a&gt;  &lt;li&gt;A domain model designed according to &lt;a href="http://dddcommunity.org/library/vernon_2011"&gt;Effective Aggregate Design&lt;/a&gt;  &lt;li&gt;Command Query Separation using Cutting Edge's &lt;a href="http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=92"&gt;Query&lt;/a&gt; and &lt;a href="http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=91"&gt;Command&lt;/a&gt; implementations  &lt;li&gt;&lt;a href="https://github.com/machine/machine.specifications"&gt;MSpec&lt;/a&gt; combined with Fluent Assertions and &lt;a href="https://github.com/FakeItEasy/FakeItEasy/wiki"&gt;FakeItEasy&lt;/a&gt;  &lt;li&gt;WCF to connect the Windows 8 C#/XAML client with the .NET 4.0 application server  &lt;li&gt;The &lt;a href="https://github.com/schambers/fluentmigrator"&gt;Fluent Migrator&lt;/a&gt; framework for maintaining a database scheme from code (if I'll go for a relational database)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The Cookbook is supposed to demonstrate how to build line-of-business applications based on the Windows Store platform. That means it's going to use some design decisions that are completely overkill for this particular example, but should be very relevant for real-life projects.  &lt;p&gt;One thing on which I'm still in doubt of is the data access strategy. I'm well aware that &lt;a href="http://cqrs.wordpress.com/documents/cqrs-and-event-sourcing-synergy/"&gt;Event Sourcing&lt;/a&gt; shouldn't be used without careful considering. But the fact of the matter is that I'm doing a project right now where we wanted to use &lt;a href="http://ravendb.net/"&gt;RavenDB&lt;/a&gt;, but decided to go for Event Sourcing using a traditional database instead. These are the four choices I have in mind.  &lt;p&gt;Aggregate storage with…&lt;/p&gt; &lt;ol&gt; &lt;li&gt;SQL Server using &lt;a href="http://nhforge.org/"&gt;NHibernate&lt;/a&gt;  &lt;li&gt;RavenDB for storing the aggregates and using its &lt;a href="http://blogs.apache.org/lucenenet/"&gt;Lucene&lt;/a&gt;-based indexing engine for querying&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;…or Event Sourcing using Jonathan Oliver's &lt;a href="http://blog.jonathanoliver.com/2011/09/cqrs-eventstore-v3-0/"&gt;EventStore&lt;/a&gt; combined with &lt;a href="http://lokad.github.com/lokad-cqrs/"&gt;Lokad.CQRS&lt;/a&gt;'s aggregate design &lt;/p&gt; &lt;ol&gt; &lt;li&gt;Using SQL Server as its backing store as well as a query store.  &lt;li&gt;Using RavenDB for storing both the events and the query models, optionally adding faceted search options provided by Lucene.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;I have to admit, this seems to be quite an ambitious project to be doing during free evenings. But I'll be reusing a lot of code from the Silverlight Cookbook, so that should save some time.  &lt;p&gt;Let me know what you think of the direction I plan go in. You can &lt;a href="mailto:dennis.doomen@avivasolutions.nl"&gt;email&lt;/a&gt; me, &lt;a href="https://twitter.com/ddoomen"&gt;tweet&lt;/a&gt; me, or spend a few minutes of your valuable to fill in &lt;a href="http://freeonlinesurveys.com/s.asp?sid=ewkwy1o6qaj1vxr139660"&gt;this&lt;/a&gt; survey.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/4679455165544888934/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=4679455165544888934&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/4679455165544888934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/4679455165544888934'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/10/planning-windows-8-cookbook.html' title='Planning the Windows 8 Cookbook'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-8678281069035092075</id><published>2012-10-31T00:28:00.001+01:00</published><updated>2012-10-31T00:28:21.482+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Events'/><title type='text'>A weekend in Emerald City</title><content type='html'>&lt;p&gt;This week is &lt;a href="http://www.buildwindows.com/"&gt;Microsoft Build 2012&lt;/a&gt;. For those who don’t know what that is, it’s Microsoft largest and most important annual event for sharing the future of the company’s plans around Windows, Windows Phone and their development platforms. Since with most trips to the US, it’s usually cheaper to take a flight on a Saturday than one on Monday, even if you consider the additional lodging costs. Since the area around Microsoft’s campus in Redmond isn't particularly exciting, me and colleague &lt;a href="https://twitter.com/jonnekats"&gt;Jonne Kats&lt;/a&gt; decided to spend the first few days of this week long trip in downtown Seattle.&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh3.ggpht.com/-fz6o0sJFcU0/UJBiOECK05I/AAAAAAAAJgI/YLB6R2iG2vs/s1600-h/WP_000017%25255B9%25255D.jpg"&gt;&lt;img title="WP_000017" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="WP_000017" src="http://lh3.ggpht.com/-p7ONedODD_8/UJBiQfaxciI/AAAAAAAAJgQ/dBSn6nyTCaQ/WP_000017_thumb%25255B7%25255D.jpg?imgmax=800" width="604" height="454"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;After a 2.5 hour delay caused by a allegedly flat tire (that ended up being a sensor error after all), we arrived at Seatac Airport at around 14:30 local. We then had to pick up our ride for the week, a &lt;a href="http://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;frm=1&amp;amp;source=web&amp;amp;cd=1&amp;amp;cad=rja&amp;amp;ved=0CCYQFjAA&amp;amp;url=http%3A%2F%2Fwww.chevrolet.com%2F2012-malibu-mid-size-sedan.html&amp;amp;ei=pi2QUPL0GYfysga6zIDADQ&amp;amp;usg=AFQjCNH5bnZvCD0LesShGlFzoAP7BRLvhQ"&gt;2012 Chevrolet Malibu LT&lt;/a&gt;. Not a particular nice car, but it’s considered a full-size sedan so that’s more than enough to carry our luggage. The car didn’t come with a GPS, but to our surprise &lt;a href="http://www.nokia.com/global/apps/nokia/drive/"&gt;Nokia Drive&lt;/a&gt; did its job better than expected. Just imagine how glad I was that I loaded the maps of state Washington prior to our trip. And since Nokia Drive 3.0 doesn’t require a live internet connection anymore, this didn’t cost us anything.&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-7yMmZ1wsLUo/UJBiSvDdsFI/AAAAAAAAJgY/mDBs5IGfVFs/s1600-h/WP_000030%25255B4%25255D.jpg"&gt;&lt;img title="WP_000030" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="WP_000030" src="http://lh3.ggpht.com/-JBF-9Kvgdlw/UJBiUU2149I/AAAAAAAAJgg/Z5xiND3gaQU/WP_000030_thumb%25255B1%25255D.jpg?imgmax=800" width="644" height="484"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;That first night we decided to visit &lt;a href="http://en.wikipedia.org/wiki/Capitol_Hill_(Seattle)"&gt;Capitol Hill&lt;/a&gt; to see what Halloween in Seattle is about. Having visited California a few times, I was surprised to see how few people were dressed up over here. It must have been the pouring rain, or the cold. We decided to take a quick bite at a Mexican restaurant we ran into because somebody noticed our indecisiveness. The fun part started when I ordered a Mojito to compensate for the lack of sleep. As you may know, in the US you cannot buy alcohol if you’re under 21. Now I’ve been called at for having a baby face….but… that was 20 years ago and I’m 39 now, Initially they refused to serve us that hard needed Mojito. It took us quite a lot of negotiation to finally get a single round. Anyway, after diner we tried to enter a small Halloween-styled bar. But again we were kept out because we didn’t bring our passport. This all feels a bit hypocrite which somebody pointy stated on Facebook: you get a free gun with a new bank account, but you cannot get a decent drink without a passport!&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-o484LTd0O3M/UJBiWdnkTyI/AAAAAAAAJgo/qPspkKserCg/s1600-h/WP_000020%25255B4%25255D.jpg"&gt;&lt;img title="WP_000020" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="WP_000020" src="http://lh6.ggpht.com/-kyh_TX-5NwY/UJBiXwRSb0I/AAAAAAAAJgw/66-hCAZh-I4/WP_000020_thumb%25255B1%25255D.jpg?imgmax=800" width="604" height="454"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The next morning, after a good night sleep, we were happily surprised with a clear blue sky. So after a quick breakfast at the local Starbucks, we planned a small road trip through the greater area of Seattle. Oh, and as a side note, where we thought to have seen Starbucks’ at virtually every corner just the night before, now we had to really search to find one. Anyway, we took the i90 to North Bend to visit one of those Seattle outlet factories and then to another one in Marysville just to enjoy the scenery of Washington in the Autumn. &lt;/p&gt; &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-4dxTn3ViPTI/UJBiZh4CbpI/AAAAAAAAJg4/S4GwfHk8ByQ/s1600-h/WP_000010%25255B5%25255D.jpg"&gt;&lt;img title="WP_000010" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="WP_000010" src="http://lh4.ggpht.com/-qj0m33YbiPo/UJBibVQWkkI/AAAAAAAAJhA/inX2kA4sCV8/WP_000010_thumb%25255B2%25255D.jpg?imgmax=800" width="604" height="454"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Obviously we grabbed a genuine home-made burger along the trip, thereby carefully avoiding any fast-food chains. And now that I mention it, the US is really a country of opposites. We regularly noticed billboards that stated that 1 of 6 US citizens is in hunger. But at the same time you’ll find these food centers with shops like McDonalds, Burger Kings, Denny’s, Taco Bells and Subways virtually after few miles. In fact, it is easier to get a burger than to find a gas station. How can anybody be hungry here? &lt;/p&gt; &lt;p&gt;After about 250 km of driving we went back to the hotel and prepared to get some dinner somewhere. With our passports in our back pockets we took a cab to the waterfront to see if there was anything to do. Fortunately our cab driver understood our intentions and proposed to bring us to Belltown, an area known for great restaurants, bars, etc. But…..it was mostly abandoned. We selected a random Sushi bar and actually enjoyed a great mixture of Japanese and Hawaiian cuisine. But when a group of large sized American geeks started up the Karaoke (granted, they could definitely sing), we left to visit a large bar across the street to grab a beer. The girl behind the bar explained to us that just the evening before, that bar was packed with 1300 people whereas now it contained about 15. Go figure….&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-A2sBKbk_EmI/UJBidMA5MSI/AAAAAAAAJhI/dJBhuoOqL5A/s1600-h/WP_000011%25255B4%25255D.jpg"&gt;&lt;img title="WP_000011" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="WP_000011" src="http://lh5.ggpht.com/-xBuV0EzCbh4/UJBif8y5QVI/AAAAAAAAJhQ/bWm5O6gAZqE/WP_000011_thumb%25255B1%25255D.jpg?imgmax=800" width="604" height="454"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;As suggested by the bartender, we took another cab to Queen Anne’s, presumably another place were you’ll find a lively crowd……..NOT. Nevertheless, we hooked up with a group of friends and spend the remainder of the evening discussing the economy, politics and the apparent uptightness of Seattle citizens. We had a lot of fun, regardless of the relative quietness of that evening. Bedtime was a lot later than planned. &lt;/p&gt; &lt;p&gt;The Monday concluded the free time prior to the event in which we visited Pike Place Market and then traveled to the north to explore the area of Mount Rainier. We did visit some shops but then decided to drive to Redmond to preregister for the conference.&amp;nbsp; To avoid traffic, we took an alternative road from Bellevue to Redmond and enjoyed the view. &lt;/p&gt; &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-Ue_7yqaJsBo/UJBiihmPruI/AAAAAAAAJhY/ceQNdhntkrA/s1600-h/WP_000031%25255B5%25255D.jpg"&gt;&lt;img title="WP_000031" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="WP_000031" src="http://lh3.ggpht.com/-jgCzLqyGsWE/UJBikhys6_I/AAAAAAAAJhg/woe9gl-sbVI/WP_000031_thumb%25255B2%25255D.jpg?imgmax=800" width="604" height="454"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Again, I can highly recommend renting a car when you are in the Seattle area, even if you need to stay downtown. You miss so much of the great environment if you rely on public transport only. All in all, not a bad start for this exciting week in the US.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/8678281069035092075/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=8678281069035092075&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/8678281069035092075'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/8678281069035092075'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/10/a-weekend-in-emerald-city.html' title='A weekend in Emerald City'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/-p7ONedODD_8/UJBiQfaxciI/AAAAAAAAJgQ/dBSn6nyTCaQ/s72-c/WP_000017_thumb%25255B7%25255D.jpg?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-8257787099439677357</id><published>2012-10-08T08:30:00.001+02:00</published><updated>2012-10-08T08:30:46.549+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Fluent Assertions'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><category scheme='http://www.blogger.com/atom/ns#' term='dotnetmag'/><title type='text'>Fluent Assertions 2.0 is out of the beta phase</title><content type='html'>&lt;p&gt;After six weeks of beta testing, it is time to remove the beta mark from Fluent Assertions 2.0. Since the beta was released, we fixed several little bugs that you won’t notice, but the original &lt;a href="http://www.dennisdoomen.net/2012/08/breaking-with-past-orfluent-assertions.html"&gt;release notes&lt;/a&gt; still apply. Release 2.0 adds a lot of new features and improvements, most noticeably the &lt;a href="http://www.dennisdoomen.net/2012/09/asserting-object-graph-equivalence.html"&gt;new syntax&lt;/a&gt; for comparing complex object graphs and support for .NET 4.5, Windows 8 Apps and Windows Phone 7.5 (Mango). You can get a copy of the zip through the CodePlex &lt;a href="http://fluentassertions.codeplex.com/releases/view/82423"&gt;download page&lt;/a&gt;, but I suspect most of you will use the &lt;a href="http://fluentassertions.codeplex.com/releases/view/82423"&gt;NuGet package&lt;/a&gt; instead. &lt;/p&gt; &lt;p&gt;For those who’d like to provide contributions, make note that we are now on a GIT repository, so we will accept your pull requests. And as usual, for questions, remarks or suggestions, you can use the &lt;a href="http://fluentassertions.codeplex.com/discussions"&gt;Discussions&lt;/a&gt; page, &lt;a href="http://stackoverflow.com/questions/tagged/fluent-assertions"&gt;StackOverflow&lt;/a&gt;, or you can contact me directly by &lt;a href="mailto:dennis.doomen@avivasolutions.nl"&gt;email&lt;/a&gt; or &lt;a href="http://twitter.com/ddoomen"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/8257787099439677357/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=8257787099439677357&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/8257787099439677357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/8257787099439677357'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/10/fluent-assertions-20-is-out-of-beta.html' title='Fluent Assertions 2.0 is out of the beta phase'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-2578348596433711939</id><published>2012-09-03T09:32:00.000+02:00</published><updated>2012-09-03T09:32:20.386+02:00</updated><title type='text'>Asserting object graph equivalence using Fluent Assertions 2.0</title><content type='html'>&lt;div&gt;As promised in the &lt;a href="http://www.dennisdoomen.net/2012/08/breaking-with-past-orfluent-assertions.html"&gt;announcement&lt;/a&gt; about version 2.0, I will&amp;nbsp;finally explain&amp;nbsp;the details behind the new extension methods for asserting that two object graphs are equivalent. For the record, these new extension methods are going to supersede the old &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;ShouldHave()&lt;/span&gt; method somewhere in a next major version. Internally the old methods are already using the new comparison engine, but new functionality will only be available through the new methods.&lt;br /&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;strong&gt;Selecting the right properties&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;Consider the class &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Order &lt;/span&gt;and its wire-transfer equivalent &lt;span style="font-family: Courier New, Courier, monospace;"&gt;OrderDto &lt;/span&gt;(a so-called &lt;a href="http://martinfowler.com/eaaCatalog/dataTransferObject.html"&gt;DTO&lt;/a&gt;). Suppose also that an order has one or more &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Products &lt;/span&gt;and an associated &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Customer&lt;/span&gt;. Coincidentally, the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;OrderDto &lt;/span&gt;will have one or more &lt;span style="font-family: Courier New, Courier, monospace;"&gt;ProductDtos&lt;/span&gt; and a corresponding &lt;span style="font-family: Courier New, Courier, monospace;"&gt;CustomerDto&lt;/span&gt;. Now if you want to make sure that all the properties of all the objects in the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;OrderDto &lt;/span&gt;object graph match the equally named properties of the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Order &lt;/span&gt;object graph, you can do this.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;orderDto.ShouldBeEquivalentTo(order);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;In contrast to the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;ShouldHave()&lt;/span&gt; extension method, the comparison is recursive by default and all properties of the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;OrderDto&lt;/span&gt; must be available on the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Order&lt;/span&gt;. If not, an exception is thrown. You can override this behavior in different ways. For instance, you may only want to include the properties both object graphs have:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;orderDto.ShouldBeEquivalentTo(order, options =&amp;gt; &lt;br /&gt;&amp;nbsp; &amp;nbsp; options.ExcludingMissingProperties());&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;You can also exclude certain (potentially deeply nested) properties using the&lt;span style="font-family: Courier New, Courier, monospace;"&gt; Excluding()&lt;/span&gt; method.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;orderDto.ShouldBeEquivalentTo(order, options =&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; options.Excluding(o =&amp;gt; o.Customer.Name));&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Obviously, &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Excluding()&lt;/span&gt; and &lt;span style="font-family: Courier New, Courier, monospace;"&gt;ExcludingMissingProperties()&lt;/span&gt; can be combined. Maybe farfetched, but you may even decide to exclude a property on a particular nested object by its index.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;orderDto.ShouldBeEquivalentTo(order, options =&amp;gt; &lt;br /&gt;&amp;nbsp; &amp;nbsp; options.Excluding(o =&amp;gt; o.Products[1].Status));&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;The &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Excluding()&lt;/span&gt; method on the options object also takes a lambda expression that offers a bit more flexibility for deciding what property to include.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;orderDto.ShouldBeEquivalentTo(order, options =&amp;gt; options&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; .Excluding(ctx =&amp;gt; ctx.PropertyPath == "Level.Level.Text"));&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;This expression has access to the property path, the property info and the subject’s run-time and compile-time type. You could also take a different approach and explicitly tell FA which properties to include.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;orderDto.ShouldBeEquivalentTo(order, options =&amp;gt; options&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; .Including(o =&amp;gt; o.OrderNumber)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; .Including(o =&amp;gt; o.Date));&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;strong&gt;Overriding and collections&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;In addition to influencing the properties that are including in the comparison, you can also override the actual assertion operation that is executed on a particular property. &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;orderDto.ShouldBeEquivalentTo(order, options =&amp;gt; options&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; .Using&amp;lt;DateTime&amp;gt;(ctx =&amp;gt; ctx.Date.Should().BeCloseTo(ctx.Date, 1000))&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; .When(info =&amp;gt; info.PropertyPath.EndsWith("Date")));&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;If you want to do this for all properties of a certain type, you can shorten the above call like this.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;orderDto.ShouldBeEquivalentTo(order, options =&amp;gt; options &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; .Using&amp;lt;DateTime&amp;gt;(ctx =&amp;gt; ctx.Date.Should().BeCloseTo(ctx.Date, 1000)) &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; .WhenTypeIs&amp;lt;DateTime&amp;gt;();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;The original &lt;span style="font-family: Courier New, Courier, monospace;"&gt;ShouldHave()&lt;/span&gt; extension method does support collections now, but it doesn’t allow you to influence the comparison based on the actual collection type. The new extension method &lt;span style="font-family: Courier New, Courier, monospace;"&gt;ShouldAllBeEquivalentTo()&lt;/span&gt; does support that so you can now take the 2nd example from the post and apply it on a collection of &lt;span style="font-family: Courier New, Courier, monospace;"&gt;OrderDto&lt;/span&gt;s.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;orderDtos.ShouldAllBeEquivalentTo(orders, options =&amp;gt; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; options.Excluding(o =&amp;gt; o.Customer.Name));&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;strong&gt;Extensibility&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;Internally the comparison process consists of three phases.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Select the properties of the subject object to include in the comparison.&lt;/li&gt;&lt;li&gt;Find a matching property on the expectation object and decide what to do if it can’t find any.&lt;/li&gt;&lt;li&gt;Select the appropriate assertion method for the property’s type and execute it.&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Each of these phases is executed by one or more implementations of &lt;span style="font-family: Courier New, Courier, monospace;"&gt;ISelectionRule&lt;/span&gt;, &lt;span style="font-family: Courier New, Courier, monospace;"&gt;IMatchingRule &lt;/span&gt;and &lt;span style="font-family: Courier New, Courier, monospace;"&gt;IAssertionRule &lt;/span&gt;that are maintained by the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;EquivalencyAssertionOptions&lt;/span&gt;. The &lt;span style="font-family: Courier New, Courier, monospace;"&gt;ExcludePropertyByPredicateSelectionRule &lt;/span&gt;for example, is added to the collection of selection rules when you use the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Excluding(property expression)&lt;/span&gt; method on the options parameter of &lt;span style="font-family: Courier New, Courier, monospace;"&gt;ShouldBeEquivalentTo()&lt;/span&gt;. Even the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Using().When()&lt;/span&gt; construct in the previous section is doing nothing more than inserting an &lt;span style="font-family: Courier New, Courier, monospace;"&gt;AssertionRule&amp;lt;TSubject&amp;gt;&lt;/span&gt; in to the list of assertion rules. Creating your own rule is quite straightforward.&amp;nbsp;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;Choose the appropriate phase that the rule should influence&lt;/li&gt;&lt;li&gt;Select the corresponding interface&lt;/li&gt;&lt;li&gt;Create a class that implements this interface&lt;/li&gt;&lt;li&gt;Add it to the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;ShouldBeEquivalentTo()&lt;/span&gt; call using the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Using()&lt;/span&gt; method on the options parameters.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;subject.ShouldBeEquivalentTo(expected, options =&amp;gt; options&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;.Using(new ExcludeForeignKeysSelectionRule()))&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;That’s it for now. As usual, for questions, remarks or suggestions, you can use the &lt;a href="http://fluentassertions.codeplex.com/discussions"&gt;Discussions&lt;/a&gt; page, &lt;a href="http://stackoverflow.com/questions/tagged/fluent-assertions"&gt;StackOverflow&lt;/a&gt;, or you can contact me directly by &lt;a href="mailto:dennis.doomen@avivasolutions.nl"&gt;email&lt;/a&gt; or &lt;a href="http://twitter.com/ddoomen"&gt;Twitter&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;strong&gt;Off topic&lt;/strong&gt;: Although we’re still on CodePlex, the source code of Fluent Assertions is now stored in a &lt;a href="http://git-scm.com/documentation"&gt;Git&lt;/a&gt; repository. That should make it a whole lot easier for contributors to fork the code, write a nice improvement, and send us a pull request. &lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/2578348596433711939/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=2578348596433711939&amp;isPopup=true' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/2578348596433711939'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/2578348596433711939'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/09/asserting-object-graph-equivalence.html' title='Asserting object graph equivalence using Fluent Assertions 2.0'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-4587377998115508678</id><published>2012-08-31T14:03:00.001+02:00</published><updated>2012-09-04T18:10:15.097+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Events'/><category scheme='http://www.blogger.com/atom/ns#' term='ALM'/><title type='text'>Slides and demo code for my SpecFlow/WaTiN talk</title><content type='html'>Yesterday I did a 2-hour talk on getting the most out of UI automation, particularly using SpecFlow and WaTiN. You can find the slides down here and the demo code at &lt;a href="https://github.com/dennisdoomen/specflowdemo"&gt;GitHub&lt;/a&gt;.&lt;br /&gt;&lt;iframe allowfullscreen="allowfullscreen" frameborder="0" height="470" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/dennisdoomen/slideshelf" style="border: currentColor;" width="490"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;br /&gt;Off Topic&lt;/strong&gt;: If you're looking for a change in your career, know that&amp;nbsp;we're still looking for Dutch-speaking new developers with all levels of experience. If that doesn't&amp;nbsp;suit you, my client (in The Hague) is also&amp;nbsp;looking for .NET developers for a permanent position. Let me know if you need more info.</content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/4587377998115508678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=4587377998115508678&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/4587377998115508678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/4587377998115508678'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/08/slides-en-demo-code-for-my.html' title='Slides and demo code for my SpecFlow/WaTiN talk'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-6350821080478790944</id><published>2012-08-28T13:38:00.001+02:00</published><updated>2012-08-28T13:38:26.813+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dotnetmag'/><title type='text'>The Best Articles and Blog Posts of August 2012</title><content type='html'>&lt;p&gt;Here are some of the highlights of the blog posts, articles and whitepapers I’ve read this month. &lt;/p&gt; &lt;ul&gt; &lt;li&gt;In two short blog posts, &lt;a href="https://twitter.com/jbogard"&gt;Jimmy Bogard&lt;/a&gt; explains &lt;a href="http://lostechies.com/jimmybogard/2012/08/22/busting-some-cqrs-myths"&gt;seven misconceptions&lt;/a&gt; of CQRS and Event Sourcing, and also warns us of the impact of eventual consistency on the &lt;a href="http://lostechies.com/jimmybogard/2012/08/23/cqrs-and-user-experience/"&gt;user experience&lt;/a&gt;.  &lt;li&gt;Read about the many improvements ReSharper 7 offers for &lt;a href="http://blogs.jetbrains.com/dotnet/2012/08/javascript-improvements-in-resharper-7/"&gt;JavaScript&lt;/a&gt;, &lt;a href="http://blogs.jetbrains.com/dotnet/2012/07/code-generation-improvements-in-resharper-7/"&gt;code generation&lt;/a&gt;, &lt;a href="http://blogs.jetbrains.com/dotnet/2012/07/unit-testing-improvements-in-resharper-7/"&gt;unit testing&lt;/a&gt; and &lt;a href="http://blogs.jetbrains.com/dotnet/2012/08/new-structural-refactorings-in-resharper-7/"&gt;new refactorings&lt;/a&gt;.  &lt;li&gt;In their article &lt;a href="http://martinfowler.com/articles/agileFluency.html"&gt;Your Path through Agile Fluency&lt;/a&gt; Diana Larsen and &lt;a href="https://twitter.com/jamesshore"&gt;James Shore&lt;/a&gt; (the author of &lt;a href="http://www.amazon.com/The-Agile-Development-James-Shore/dp/0596527675"&gt;The Art of Agile Development&lt;/a&gt;) define a different levels of agile using a system of stars. How many stars does your team have?  &lt;li&gt;&lt;a href="http://twitter.com/lunivore"&gt;Liz Koegh&lt;/a&gt;’s brilliantly illustrates the essence of BDD when compared to TDD in her blog post &lt;a href="http://lizkeogh.com/2012/05/30/showcasing-the-language-of-bdd/"&gt;Showcasing the language of BDD&lt;/a&gt;.  &lt;li&gt;InfoWorld published a slightly ironic article on &lt;a href="http://www.infoworld.com/d/application-development/10-practices-of-highly-ineffective-software-developers-199747"&gt;10 practices of highly ineffective software developers&lt;/a&gt;. Which of those practices do you still practice?  &lt;li&gt;I recently read this old, but IMHO still very relevant article on how to properly practice &lt;a href="http://gojko.net/2010/04/13/how-to-implement-ui-testing-without-shooting-yourself-in-the-foot-2/"&gt;UI testing without shooting yourself in the foot&lt;/a&gt;. It is written by &lt;a href="https://twitter.com/gojkoadzic"&gt;Gojko Adzic&lt;/a&gt; an authority on specification-by-example.  &lt;li&gt;The better you get, the worse you get. Controversial isn’t it? But if you read the article &lt;a href="http://simpleprogrammer.com/2012/07/23/when-being-good-is-bad/"&gt;When Being Good is Bad&lt;/a&gt; by &lt;a href="https://twitter.com/jsonmez"&gt;John Sonmez&lt;/a&gt; it will all make sense.  &lt;li&gt;How do you provide feedback to your colleagues? Is it as effective as you want? If not, consider reading &lt;a href="http://www.infoq.com/articles/continuous-feedback-teams"&gt;Continuous Feedback in Agile Teams&lt;/a&gt;.  &lt;li&gt;The August edition of MSDN Magazine included a &lt;a href="http://msdn.microsoft.com/en-us/vstudio/jj573641.aspx"&gt;nice in-depth&lt;/a&gt; explanation how the new &lt;em&gt;async&lt;/em&gt; keyword in C# 5.0 works.  &lt;li&gt;Don’t you ever have those days that you feel unproductive? Then check out &lt;a href="http://www.hanselman.com/blog/"&gt;Scott Hanselman&lt;/a&gt;’s &lt;a href="http://www.hanselman.com/blog/ProductivityVsGuiltAndSelfLoathing.aspx"&gt;tips for feeling better&lt;/a&gt;.  &lt;li&gt;I still believe that he or she exists, but apparently super programmers are a &lt;a href="http://simpleprogrammer.com/2012/08/12/the-myth-of-the-super-programmer/"&gt;myth&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/6350821080478790944/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=6350821080478790944&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/6350821080478790944'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/6350821080478790944'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/08/the-best-articles-and-blog-posts-of.html' title='The Best Articles and Blog Posts of August 2012'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-7878603056335979437</id><published>2012-08-26T19:45:00.000+02:00</published><updated>2012-09-03T18:32:46.297+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Fluent Assertions'/><title type='text'>Breaking with the past (or…Fluent Assertions 2.0 is in beta)</title><content type='html'>After many months of development, in particular during in evenings after work and in the weekends, we’re proud to present the first (and hopefully the only) beta of Fluent Assertions 2.0. Together with my good friend and coworker &lt;a href="http://www.codeplex.com/site/users/view/mopdam"&gt;Martin Opdam&lt;/a&gt;, and supported by noticeable contributors like &lt;a href="http://novotny.org/blog"&gt;Oren Novotny&lt;/a&gt; and &lt;a href="http://ianobermiller.com/"&gt;Ian Obermiller&lt;/a&gt;, we managed to introduce a shipload of new features. &lt;br /&gt;&lt;div&gt;&amp;nbsp;&lt;/div&gt;&lt;img height="195" src="http://images.androidworld.nl/wp-content/uploads/VLC-Beta-NEON-version_featured_logo.png" style="display: block; float: none; margin-left: auto; margin-right: auto;" width="195" /&gt;&lt;br /&gt;&lt;br /&gt;For instance, Oren worked on the foundations for supporting the new Windows 8 Metro-style apps, whereas Ian created the initial Windows Phone 7.5 version. Martin added support for .NET 4.5, added quite a few new variations and overloads to the existing assertions and also fixed a lot of the reported bugs. I myself introduced a completely new extensible API for comparing two objects graphs for equivalence. As the original founder of this project, I also took charge of safeguarding the overall quality and consistency.&lt;br /&gt;&lt;br /&gt;And now that I mention it, after a week of debugging I almost decided to drop Windows Phone support altogether. I was suffering from two really persistent &lt;span style="font-family: Consolas;"&gt;ReflectionTypeLoadException&lt;/span&gt;s and &lt;span style="font-family: Consolas;"&gt;MissingMethodException&lt;/span&gt;s. Since I’ve started developing on the .NET platform in 2001, I’ve run into some pretty weird issues, but this was a whole new league for me (read the &lt;a href="http://stackoverflow.com/questions/12067070/getexportedtypes-on-an-assembly-throws-notsupportedexception/12067971#comment16169864_12067971"&gt;StackOverflow&lt;/a&gt; discussion to learn a bit more about this issue). Fortunately &lt;a href="http://blog.catenalogic.com/"&gt;Geert van Horrik&lt;/a&gt; pointed me at a blog post he wrote a while back that explained Windows Phone’s &lt;a href="http://blog.catenalogic.com/post/2011/08/27/Windows-Phone-7-and-MissingMethodException.aspx"&gt;lack of support&lt;/a&gt; for co- and contravariance. And indeed, that was exactly the problem I was facing all the time. &lt;br /&gt;&lt;br /&gt;So in addition to support for the aforementioned .NET flavors and support for MBUnit and the Gallio Automation Platform, what else did we add?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What's new for collections&lt;/strong&gt;  &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Added (&lt;span style="font-family: Consolas;"&gt;Not&lt;/span&gt;)&lt;span style="font-family: Consolas;"&gt;BeInAscendingOrder()&lt;/span&gt;, (&lt;span style="font-family: Consolas;"&gt;Not&lt;/span&gt;)&lt;span style="font-family: Consolas;"&gt;BeInDescendingOrder&lt;/span&gt;(), &lt;span style="font-family: Consolas;"&gt;IntersectWith(otherCollection)&lt;/span&gt; and &lt;span style="font-family: Consolas;"&gt;NotIntersectWith(otherCollection)&lt;/span&gt;. &lt;li&gt;&lt;span style="font-family: Consolas;"&gt;ContainInOrder()&lt;/span&gt; got an overload that takes a &lt;span style="font-family: Consolas;"&gt;params object[]&lt;/span&gt; argument rather than an &lt;span style="font-family: Consolas;"&gt;IEnumerable&lt;/span&gt; in case you don't care about the reason. &lt;li&gt;Added &lt;span style="font-family: Consolas;"&gt;ContainSingle()&lt;/span&gt; that asserts there is only a single element in the collection that matches the specified lambda. &lt;li&gt;Added an overload to &lt;span style="font-family: Consolas;"&gt;Equal()&lt;/span&gt; that takes a lambda that is used for checking the equality of two collections without relying on the type’s Equals() method. Consider for instance two collections that contain some kind of domain entity persisted to a database and then reloaded. Since the actual object instance is different, if you want to make sure a particular property was properly persisted, you usually do something like this:&lt;pre class="csharpcode"&gt;persistedCustomers.Select(c =&amp;gt; c.Name).Should().Equal(customers.Select(c =&amp;gt; c.Name);&lt;/pre&gt;&lt;span style="font-family: Calibri;"&gt;&lt;/span&gt;&lt;div&gt;&lt;span style="font-family: Calibri;"&gt;With this new overload, you can rewrite it into:&lt;/span&gt;&lt;/div&gt;&lt;pre class="csharpcode"&gt;persistedCustomers.Should().Equal(customers, c =&amp;gt; c.Name);&lt;/pre&gt;&lt;li&gt;Fixed a bug that occurred when two collections are compared for equality but the collection contains &lt;span style="font-family: Consolas; font-size: x-small;"&gt;null&lt;/span&gt;s.&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;What's new for strings &lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;When strings differ in length, it will report the expected and actual lengths as part of the error messages.&lt;/div&gt;&lt;li&gt;&lt;div&gt;An &lt;span style="font-family: Consolas;"&gt;ArgumentOutOfRangeException&lt;/span&gt; was thrown when asserting that a string started with a specific string and the first string was shorter than the expected string.&lt;/div&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;What's new for numbers &lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Added support for using &lt;span style="font-family: Consolas;"&gt;Be()&lt;/span&gt; on nullable numeric types.&lt;/li&gt;&lt;li&gt;Added &lt;span style="font-family: Consolas;"&gt;BeOneOf()&lt;/span&gt; to assert that a value matches one of the provided values. &lt;/li&gt;&lt;li&gt;Added support for (nullable) decimals &lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Consolas;"&gt;BePositive()&lt;/span&gt; and &lt;span style="font-family: Consolas;"&gt;BeNegative()&lt;/span&gt; now also work for floats and doubles.&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;What's new for dates and times &lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;Added &lt;span style="font-family: Consolas;"&gt;NotBe()&lt;/span&gt;. Also added &lt;span style="font-family: Consolas;"&gt;BeOneOf()&lt;/span&gt; to verify that the value matches one of the provided values.&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;li&gt;&lt;div&gt;Added &lt;span style="font-family: Consolas;"&gt;BeCloseTo()&lt;/span&gt; to assert that a date/time is within a specified number of milliseconds from another date/time value. This can be particularly useful if your database truncates date/time values. &lt;/div&gt;&lt;li&gt;&lt;div&gt;If a date/time value has non-zero milliseconds then that will be displayed in the error messages .&lt;/div&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;What's new for comparing object graphs &lt;/strong&gt;&lt;br /&gt;I’ll dedicate a &lt;a href="http://www.dennisdoomen.net/2012/09/asserting-object-graph-equivalence.html"&gt;separate&lt;/a&gt; blog post on the new &lt;span style="font-family: Consolas;"&gt;object.ShouldBeEquivalentTo(object)&lt;/span&gt; and &lt;span style="font-family: Consolas;"&gt;collection.ShouldAllBeEquivalentTo(collection)&lt;/span&gt;, but the existing API based on the &lt;span style="font-family: Consolas;"&gt;object.ShouldHave()&lt;/span&gt; has benefited from the internal redesign as well. &lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;You can now apply the property equality comparisons to entire collections of objects. It doesn't matter what kind of collection type you use, as long as it contains the same number of objects, and the object’s properties match. &lt;/div&gt;&lt;li&gt;&lt;div&gt;The error message now includes the index of the mismatching object.&lt;/div&gt;&lt;li&gt;&lt;div&gt;An exception was thrown when comparing the properties of an object and one of them causes a cyclic reference. You can now alter that behavior by passing in a value from the &lt;span style="font-family: Consolas;"&gt;CyclicReferenceHandling&lt;/span&gt; enum into the &lt;span style="font-family: Consolas;"&gt;IncludingNestedObjects()&lt;/span&gt; method.&lt;/div&gt;&lt;li&gt;&lt;div&gt;Added support for references to an interface rather than concrete types. You can find an example of that at the corresponding &lt;a href="http://fluentassertions.codeplex.com/workitem/11840"&gt;feature request&lt;/a&gt; page. &lt;/div&gt;&lt;li&gt;&lt;div&gt;Added support for comparing two anonymous types using &lt;span style="font-family: Consolas;"&gt;SharedProperties()&lt;/span&gt;.&lt;/div&gt;&lt;li&gt;&lt;div&gt;Fixed a bug that caused an exception to be thrown for write-only properties. They are now ignored. &lt;/div&gt;&lt;li&gt;&lt;div&gt;Fixed a stack overflow exception when formatting an object graph that contains a static property with a cyclic reference. &lt;/div&gt;&lt;li&gt;&lt;div&gt;Fixed an exception that was thrown when formatting an object graph and one of the properties throws.&lt;/div&gt;&lt;li&gt;&lt;div&gt;The name of a date/time property was not included in the error message when &lt;span style="font-family: Consolas;"&gt;AllProperties()&lt;/span&gt; failed on that property&lt;/div&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;strong&gt;What's new for types &lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;Added the static &lt;span style="font-family: Consolas;"&gt;AllTypes&lt;/span&gt; class with a static method &lt;span style="font-family: Consolas;"&gt;From(Assembly assembly)&lt;/span&gt; as a wrapper around the &lt;span style="font-family: Consolas; font-size: x-small;"&gt;Types&lt;/span&gt; extension method on &lt;span style="font-family: Consolas; font-size: x-small;"&gt;Assembly&lt;/span&gt;. This allows for a more fluent syntax like &lt;/div&gt;&lt;div&gt;&lt;pre class="csharpcode"&gt;AllTypes.From(assembly)&lt;br /&gt;  .ThatAreDecoratedWith&amp;lt;SomeAttribute&amp;gt;()&lt;br /&gt;  .ThatImplement&amp;lt;ISomeInterface&amp;gt;()&lt;br /&gt;  .ThatAreInNamespace(&lt;span class="str"&gt;"Internal.Main.Test"&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Added support for asserting that the properties of an attribute have a specific value. For instance:&amp;nbsp;&lt;pre class="csharpcode"&gt;typeWithAttribute.Should()&lt;br /&gt;  .BeDecoratedWith&amp;lt;DummyClassAttribute&amp;gt;(a =&amp;gt; ((a.Name == &lt;span class="str"&gt;"Unexpected"&lt;/span&gt;) &amp;amp;&amp;amp; a.IsEnabled));&lt;/pre&gt;&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;What other improvements&amp;nbsp;did we&amp;nbsp;include&amp;nbsp;&lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;Fixed an exception when asserting the equality of dictionaries that contain &lt;span style="font-family: Consolas;"&gt;null&lt;/span&gt;s. &lt;/div&gt;&lt;li&gt;&lt;div&gt;The NuGet package will automatically add references to the &lt;span style="font-family: Consolas;"&gt;System.Xml&lt;/span&gt; and &lt;span style="font-family: Consolas;"&gt;System.Xml.Linq&lt;/span&gt; references. &lt;/div&gt;&lt;li&gt;&lt;div&gt;Added a &lt;span style="font-family: Consolas;"&gt;ShouldThrow&amp;lt;TException&amp;gt;()&lt;/span&gt; method for a &lt;span style="font-family: Consolas;"&gt;Func&amp;lt;Task&amp;gt;&lt;/span&gt; to support working with async methods like this:&lt;br /&gt;&lt;pre class="csharpcode"&gt;  Func&amp;lt;Task&amp;gt; slowFunction = async () =&amp;gt; { await slowObject.ThrowAsync&amp;lt;ArgumentException&amp;gt;(); };&lt;br /&gt;  slowFunction.ShouldThrow&amp;lt;InvalidOperationException&amp;gt;();&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;&lt;li&gt;&lt;div&gt;Improved several of the error messages related to assertions on &lt;span style="font-family: Consolas;"&gt;XDocument&lt;/span&gt; and &lt;span style="font-family: Consolas;"&gt;XElement&lt;/span&gt;.&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;li&gt;&lt;div&gt;All overloads that took the &lt;em&gt;reason&lt;/em&gt; and &lt;em&gt;reasonargs&lt;/em&gt; parameters have been removed and replaced with optional parameters &lt;/div&gt;&lt;li&gt;&lt;div&gt;Allowed &lt;span style="font-family: Consolas; font-size: x-small;"&gt;ShouldRaisePropertyChangeFor(null)&lt;/span&gt; to assert that an object implemented &lt;span style="font-family: Consolas; font-size: x-small;"&gt;INotifyPropertyChanged&lt;/span&gt; raised the changed event for all properties.&lt;/div&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;strong&gt;What’s new for extensibility&lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;The list of &lt;span style="font-family: Consolas;"&gt;IValueFormatter&lt;/span&gt; objects on the &lt;span style="font-family: Consolas; font-size: x-small;"&gt;Formatter&lt;/span&gt; class can be altered to insert a custom formatter. &lt;/div&gt;&lt;li&gt;&lt;div&gt;Introduced a mechanism to override the way Fluent Assertions formats objects in an error message by annotating a static method with the &lt;span style="font-family: Consolas;"&gt;[ValueFormatter]&lt;/span&gt; attribute. If a class doesn’t override ToString(), the built-in DefaultValueFormatter will render an object graph of that object. But you can now override that using a construct like this:&lt;/div&gt;&lt;div&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CustomFormatter&lt;br /&gt;{&lt;br /&gt;    [ValueFormatter]&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Foo(SomeClassvalue)&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;"Property = "&lt;/span&gt; + &lt;span class="kwrd"&gt;value&lt;/span&gt;.Property;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;li&gt;&lt;div&gt;We introduced a mechanism so that the error message of custom assertion extensions can specify the {context} tag that is used to inject the property path in object graph comparisons. For instance, in the date/time assertions, this is used to display &lt;em&gt;date and time. &lt;/em&gt;But when this assertion is used as part of a recursive object graph comparison, it will display the property path instead.&lt;/div&gt;&lt;div&gt;&lt;pre class="csharpcode"&gt;Execute.Verification&lt;br /&gt;    .ForCondition(Subject.Value == expected)&lt;br /&gt;    .BecauseOf(reason, reasonArgs)&lt;br /&gt;    .FailWith(&lt;span class="str"&gt;"Expected {context:date and time} to be {0}{reason}, but found {1}."&lt;/span&gt;, expected, subject.Value);&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;The NuGet package is now based on NuGet 2.0.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;strong&gt;Breaking changes&lt;/strong&gt;&lt;br /&gt;Since we decided to bump up the version from 1.7.1 to 2.0 and we’ve already told you that we comply to &lt;a href="http://semver.org/"&gt;Semantic Versioning&lt;/a&gt;, you can expect some breaking changes in this release. &lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;In order to ensure that all extension methods are always available through the &lt;span style="font-family: Consolas;"&gt;FluentAssertions&lt;/span&gt; namespace, we had to get rid of the &lt;span style="font-family: Consolas;"&gt;FluentAssertions.Assertions&lt;/span&gt; namespace. Just use a global search-replace to remove all those usage statements.&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;li&gt;&lt;div&gt;Many of the assertion classes have moved into dedicated namespaces. You might have to fix any code that inherits from those classes. &lt;/div&gt;&lt;li&gt;&lt;div&gt;Remove the obsolete &lt;span style="font-family: Consolas;"&gt;Verify()&lt;/span&gt; methods from the &lt;span style="font-family: Consolas;"&gt;Verification&lt;/span&gt; class&lt;/div&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;So what’s next&lt;/strong&gt;&lt;br /&gt;To get started, get the &lt;a href="https://nuget.org/packages/FluentAssertions"&gt;NuGet&lt;/a&gt; package from inside Visual Studio (just make sure you include pre-release versions), or get the ZIP through the &lt;a href="http://fluentassertions.codeplex.com/releases/view/82423"&gt;CodePlex&lt;/a&gt; download page. If you run into issues, I would prefer that you ping me directly on &lt;a href="http://twitter.com/ddoomen"&gt;Twitter&lt;/a&gt; before you file an issue on CodePlex’s &lt;a href="http://fluentassertions.codeplex.com/workitem/list/advanced"&gt;Issue Tracker&lt;/a&gt;. By the way, we use the &lt;a href="http://twitter.com/#!/search/realtime/%23fluentassertions"&gt;#fluentassertions&lt;/a&gt; tag on Twitter. For questions, remarks or suggestions, you can use the &lt;a href="http://fluentassertions.codeplex.com/discussions"&gt;Discussions&lt;/a&gt; page, &lt;a href="http://stackoverflow.com/questions/tagged/fluent-assertions"&gt;StackOverflow&lt;/a&gt;, or you can contact me directly by &lt;a href="mailto:dennis.doomen@avivasolutions.nl"&gt;email&lt;/a&gt; or &lt;a href="http://twitter.com/ddoomen"&gt;Twitter&lt;/a&gt;.&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Off topic&lt;/strong&gt;: Although we’re still on CodePlex, the source code  of Fluent Assertions is now stored in a &lt;a href="http://git-scm.com/documentation"&gt;&lt;span style="color: #992211;"&gt;Git&lt;/span&gt;&lt;/a&gt; repository. That&amp;nbsp;should make it  a whole lot easier for contributors to fork the code,&amp;nbsp;write&amp;nbsp;a nice  improvement,&amp;nbsp;and send us a pull request. </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/7878603056335979437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=7878603056335979437&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/7878603056335979437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/7878603056335979437'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/08/breaking-with-past-orfluent-assertions.html' title='Breaking with the past (or…Fluent Assertions 2.0 is in beta)'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-9000784357213155161</id><published>2012-07-30T09:39:00.001+02:00</published><updated>2012-07-30T09:40:50.885+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ALM'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><category scheme='http://www.blogger.com/atom/ns#' term='Quality'/><category scheme='http://www.blogger.com/atom/ns#' term='Book'/><category scheme='http://www.blogger.com/atom/ns#' term='dotnetmag'/><title type='text'>Quick Review of The Cucumber Book from a SpecFlow perspective</title><content type='html'>This week I completed reading a new book titled &lt;a href="http://www.amazon.com/The-Cucumber-Book-Behaviour-Driven-Development/dp/1934356808/ref=sr_1_3?ie=UTF8&amp;amp;qid=1343541975&amp;amp;sr=8-3&amp;amp;keywords=the+cucumber+book"&gt;The Cucumber Book: Behaviour-Driven Development for Testers and Developers&lt;/a&gt; by &lt;a href="http://blog.mattwynne.net/"&gt;Matt Wynne&lt;/a&gt; and &lt;a href="http://aslakhellesoy.com/"&gt;Aslak Hellesoy&lt;/a&gt;. Aslak is the founder of the &lt;a href="http://cukes.info/"&gt;Cucumber&lt;/a&gt; project (which is what &lt;a href="http://www.specflow.org/"&gt;SpecFlow&lt;/a&gt; for .NET is based on), and Matt is one of its most active developers. The 328-page book is only 20 USD if you get it through &lt;a href="http://pragprog.com/book/hwcuc/the-cucumber-book"&gt;The Pragmatic Bookshelf&lt;/a&gt; and worth the money, even if you're an experienced SpecFlow developer/tester. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/images/1934356808/ref=dp_image_0?ie=UTF8&amp;amp;n=283155&amp;amp;s=books"&gt;&lt;img alt="clip_image001" height="314" src="http://lh6.ggpht.com/-hKoFm6sf084/UBTkUqX74JI/AAAAAAAAJao/OxkKkaHwPiM/clip_image001%25255B6%25255D.jpg?imgmax=800" style="display: block; float: none; margin-left: auto; margin-right: auto;" title="clip_image001" width="314" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;The code examples are written in Ruby, but even without any prior knowledge of Ruby, I managed to get through them quite easily. (Off-topic: It's not a language I see myself coding in anytime soon, so I must be a C-language addict).  &lt;br /&gt;&lt;br /&gt;Anyway, the first 6 chapters (Part I) are awesome. Not only do they provide a decent introduction to the concepts behind Cucumber and a detailed break down of the Gherkin language, it also provides numerous tips and tricks that should prevent you from making your efforts gone bad. Just as you can go bad with practices like TDD, there's a whole lot you can do wrong when dealing with automation scenarios based on the Gherkin language. Even after reading the &lt;a href="http://cuke4ninja.com/"&gt;Secret Ninja Cucumber Scrolls&lt;/a&gt; and everything there is to read on &lt;a href="https://github.com/techtalk/SpecFlow/wiki/_pages"&gt;SpecFlow&lt;/a&gt;, I learned some valuable new lessons that sure are going to improve the work I'm doing right now. &lt;br /&gt;&lt;br /&gt;Chapters 7-10 (Part II) are taking a deep-dive in implementing the Step Definitions using Ruby. Since I don't care about the Ruby details, I mostly browsed through these pages looking for hidden tips and tricks. If you are a .NET developer like me, I would do the same. But just make sure you read all the side-notes (the ones with a bluish background). They contain some valuable best practices.  &lt;br /&gt;&lt;br /&gt;Again, if you're a .NET developers, you can skip chapters 11, 14 to 16 and the appendixes since they are too specific to the Cucumber tool and the Ruby language. But do try to read chapters 12 (Testing a REST Service) and 13 (Adding Tests to a Legacy Application).&lt;br /&gt;&lt;br /&gt;You might wonder why I still believe the 20 dollars are worth the money after I told you to skip so much of the book's contents. It just that those first 100 pages plus the many best practices in the remainder of it really make up for the rest of the book. Since I'll be talking about SpecFlow and WaTiN at the Dutch .NET User Group meeting on &lt;a href="http://dotned.nl/register/47/dennis-doomen-over-automated-ui-testing-bij-ict-automatisering.aspx"&gt;August 30st&lt;/a&gt;, I have been looking for some decent advice on writing proper Features and Scenarios for a while. The book delivered. Period. &lt;br /&gt;For completeness, here’s the table of the contents. &lt;br /&gt;&lt;ol&gt;&lt;li&gt;Why Cucumber?&lt;/li&gt;&lt;li&gt;First Taste &lt;/li&gt;&lt;li&gt;Gherkin Basics &lt;/li&gt;&lt;li&gt;Step Definitions: From the Outside  &lt;/li&gt;&lt;li&gt;Expressive Scenarios &lt;/li&gt;&lt;li&gt;When Cucumbers Go Bad&lt;/li&gt;&lt;li&gt;Step Definitions: On the Inside&lt;/li&gt;&lt;li&gt;Support Code &lt;/li&gt;&lt;li&gt;Dealing with Message Queues and Asynchronous Components &lt;/li&gt;&lt;li&gt;Databases&lt;/li&gt;&lt;li&gt;The Cucumber Command-Line Interface&lt;/li&gt;&lt;li&gt;Testing a REST Web Service &lt;/li&gt;&lt;li&gt;Adding Tests to a Legacy Application &lt;/li&gt;&lt;li&gt;Bootstrapping Rails &lt;/li&gt;&lt;li&gt;Using Capybara to Test Ajax Web Applications &lt;/li&gt;&lt;li&gt;Testing Command Line Applications with Aruba&lt;/li&gt;&lt;/ol&gt;PS. Did you know that SpecFlow 1.9 is eminent? Check out the &lt;a href="https://github.com/techtalk/SpecFlow/blob/master/changelog.txt"&gt;preliminary release notes&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/9000784357213155161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=9000784357213155161&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/9000784357213155161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/9000784357213155161'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/07/quick-review-of-cucumber-book-from.html' title='Quick Review of The Cucumber Book from a SpecFlow perspective'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/-hKoFm6sf084/UBTkUqX74JI/AAAAAAAAJao/OxkKkaHwPiM/s72-c/clip_image001%25255B6%25255D.jpg?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-2791166776584760728</id><published>2012-07-26T20:29:00.001+02:00</published><updated>2012-07-27T09:21:49.946+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Events'/><category scheme='http://www.blogger.com/atom/ns#' term='dotnetmag'/><title type='text'>Noticeable quotes from QCon New York</title><content type='html'>&lt;h5&gt;&lt;font style="font-weight: normal"&gt;Just to be clear, I didn’t actually attend &lt;a href="http://qconnewyork.com/"&gt;QCon New York&lt;/a&gt; this year. But after the experience of attending QCon San Francisco in 2010, I never forget the many great quotes you’ll find on Twitter. This time was no different.&lt;/font&gt;&lt;/h5&gt; &lt;ul&gt; &lt;li&gt; &lt;h5&gt;&lt;font style="font-weight: normal"&gt;&lt;em&gt;"Distributed objects failed; for very good reasons. Values rule on the wire"&lt;/em&gt; by &lt;/font&gt;&lt;a href="http://qconnewyork.com/qcon-nyc-2012/speaker/Rich+Hickey"&gt;&lt;font style="font-weight: normal"&gt;Rich Hickey&lt;/font&gt;&lt;/a&gt;&lt;font style="font-weight: normal"&gt; in his session on &lt;/font&gt;&lt;a href="http://qconnewyork.com/qcon-nyc-2012/presentation/Keynote%3A+The+Value+of+Values"&gt;&lt;font style="font-weight: normal"&gt;The Value of Values&lt;/font&gt;&lt;/a&gt;.&lt;/h5&gt;&lt;/li&gt; &lt;li&gt; &lt;h5&gt;&lt;font style="font-weight: normal"&gt;&lt;em&gt;“People don't change, they don't want to be accountable whether agile or not”&lt;/em&gt; by &lt;a href="http://qconnewyork.com/qcon-nyc-2012/speaker/Jeff+Patton"&gt;Jeff Pattond&lt;/a&gt; in his talk on &lt;a href="http://qconnewyork.com/qcon-nyc-2012/presentation/Co-making+great+products"&gt;Co-Making Great Products&lt;/a&gt;.&lt;/font&gt;&lt;/h5&gt;&lt;/li&gt; &lt;li&gt; &lt;h5&gt;&lt;font style="font-weight: normal"&gt;&lt;em&gt;“If you think writing code is hard, try making product decisions”&lt;/em&gt; also by Jeff Pattond.&lt;/font&gt;&lt;/h5&gt;&lt;/li&gt; &lt;li&gt; &lt;h5&gt;&lt;font style="font-weight: normal"&gt;&lt;em&gt;"You only hire the Best and the Brightest? Really? Who is then hiring the Worst and the Dimmest?", &lt;/em&gt;something that was said during a panel discussion.&lt;/font&gt;&lt;/h5&gt;&lt;/li&gt; &lt;li&gt; &lt;h5&gt;&lt;em&gt;&lt;font style="font-weight: normal"&gt;“Mud takes away our ability to do good design”, &lt;/font&gt;&lt;/em&gt;&lt;font style="font-weight: normal"&gt;by &lt;a href="http://qconnewyork.com/qcon-nyc-2012/speaker/Eric+Evans"&gt;Eric Evans&lt;/a&gt; in his talk &lt;/font&gt;&lt;a href="http://qconnewyork.com/qcon-nyc-2012/presentation/Four+Strategies+for+Recovering+the+Ability+to+Design+When+Surrounded+by+Messy+Legacy"&gt;&lt;font style="font-weight: normal"&gt;Four Strategies for Recovering the Ability to Design When Surrounded by Messy Legacy&lt;/font&gt;&lt;/a&gt;&lt;font style="font-weight: normal"&gt;.&lt;/font&gt;&lt;/h5&gt;&lt;/li&gt; &lt;li&gt; &lt;h5&gt;&lt;font style="font-weight: normal"&gt;&lt;em&gt;"Refactoring is good at changing order, not fundamentals. You can't convert a hotel into a stadium”&lt;/em&gt;, also by Eric Evans&lt;/font&gt;&lt;/h5&gt;&lt;/li&gt; &lt;li&gt; &lt;h5&gt;&lt;font style="font-weight: normal"&gt;“&lt;em&gt;Empowering is a middle management word that means pretending to let people do things, and then preventing that&lt;/em&gt;”, by &lt;a href="http://qconnewyork.com/qcon-nyc-2012/speaker/Mike+Hill"&gt;Mike Hill&lt;/a&gt; in his talk on &lt;a href="http://qconnewyork.com/qcon-nyc-2012/presentation/How+Individuals+Help+Teams+Become+Excellent"&gt;How Individuals Help Teams Become Excellent&lt;/a&gt;.&lt;/font&gt;&lt;/h5&gt;&lt;/li&gt; &lt;li&gt; &lt;h5&gt;&lt;font style="font-weight: normal"&gt;“&lt;em&gt;Watching someone do work is not pairing&lt;/em&gt;”, also by Mike Hill&lt;/font&gt;&lt;/h5&gt;&lt;/li&gt;&lt;/ul&gt; &lt;h5&gt;&lt;font style="font-weight: normal"&gt;As you can expect from somebody like &lt;a href="http://qconnewyork.com/qcon-nyc-2012/speaker/Michael+Feathers"&gt;Michael Feathers&lt;/a&gt;, he made some great quotes in his talk on &lt;/font&gt;&lt;a href="http://qconnewyork.com/qcon-nyc-2012/presentation/Patterns+of+Software+Change"&gt;&lt;font style="font-weight: normal"&gt;Patterns of Software Change&lt;/font&gt;&lt;/a&gt;&lt;font style="font-weight: normal"&gt;.&lt;/font&gt;&lt;/h5&gt; &lt;ul&gt; &lt;li&gt; &lt;h5&gt;“&lt;font style="font-weight: normal"&gt;&lt;em&gt;Architecture - the part of the system that you can not replace without having a different system&lt;/em&gt;”&lt;/font&gt;&lt;/h5&gt;&lt;/li&gt; &lt;li&gt; &lt;h5&gt;&lt;font style="font-weight: normal"&gt;"&lt;em&gt;Over-engineering = weighting a possible future too highly in design.&lt;/em&gt;"&lt;/font&gt;&lt;/h5&gt;&lt;/li&gt; &lt;li&gt; &lt;h5&gt;&lt;font style="font-weight: normal"&gt;&lt;em&gt;“Code Turbulance”, &lt;/em&gt;a name for frequently changed code&lt;/font&gt;&lt;/h5&gt;&lt;/li&gt; &lt;li&gt; &lt;h5&gt;&lt;font style="font-weight: normal"&gt;“&lt;em&gt;Anytime you manage by the numbers, instead of actually (God forbid) looking at the code a way will be found to game the numbers&lt;/em&gt;”, in a discussion on the uselessness of using only code metrics for judging the quality of your code base.&lt;/font&gt;&lt;/h5&gt;&lt;/li&gt;&lt;/ul&gt; &lt;h5&gt;&lt;font style="font-weight: normal"&gt;Looking forward to QCon San Francisco in November…&lt;/font&gt;&lt;/h5&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/2791166776584760728/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=2791166776584760728&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/2791166776584760728'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/2791166776584760728'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/07/noticeable-quotes-from-qcon-new-york.html' title='Noticeable quotes from QCon New York'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-418973506547188210</id><published>2012-07-20T16:31:00.001+02:00</published><updated>2012-07-20T17:29:22.041+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>Required Reading Material for July 2012</title><content type='html'>&lt;p&gt;Since I was already collecting the better articles that I read during the month for sharing with my colleagues and client’s coworkers, I might just as well share them here. Have fun reading them.  &lt;p&gt;&lt;a href="http://www.infoq.com/articles/virtual-panel-tdd-bdd"&gt;Virtual Panel: Code-to-Test Ratios, TDD and BDD&lt;/a&gt;&amp;nbsp;&lt;br&gt;A great discussion by &lt;i&gt;the&lt;/i&gt; authorities on TDD, BDD and Specification By Example.  &lt;p&gt;&lt;a href="http://www.nomad8.com/page0/files/agile_undercover.php"&gt;Agile Undercover: When Customers don’t Collaborate&lt;/a&gt;&amp;nbsp;&lt;br&gt;Contains best practices for dealing with the reality issues of a Scrum project.  &lt;p&gt;&lt;a href="http://www.infoq.com/news/2012/07/jquery-1.8-1.9-2.0"&gt;What's Upcoming in jQuery 1.8, 1.9 and 2.0, and the Removal of IE6/7/8 Support&lt;/a&gt;. &lt;br&gt;A summary of important changes in the next versions of jQuery.  &lt;p&gt;&lt;a href="http://blogs.jetbrains.com/dotnet/2012/07/resharper-7-whats-inside/"&gt;ReSharper 7: What’s Inside&lt;/a&gt;. &lt;br&gt;Even if you are already running the beta, it’s still worth a read.  &lt;p&gt;&lt;a href="http://lostechies.com/jimmybogard/2012/06/26/eventual-consistency-cqrs-and-interaction-design/"&gt;Eventual consistency, CQRS and interaction design&lt;/a&gt; &lt;br&gt;An important aspect of using Event Sourcing is the Eventual Consistency aspect. This article explains that in more detail and how it affects the perception of the end-user.  &lt;p&gt;&lt;a href="http://haacked.com/archive/2012/07/05/turkish-i-problem-and-why-you-should-care.aspx"&gt;The Turkish İ Problem and Why You Should Care&lt;/a&gt;&lt;br&gt;Illustrates the difficulties of not properly preparing an application for supporting multiple languages.  &lt;p&gt;&lt;a href="http://dannorth.net/the-art-of-misdirection/"&gt;The Art of Misdirection&lt;/a&gt;&lt;br&gt;As can be expected from one of the best speakers in our profession, a deep insight in the hidden cost of software developments. Incidentally covers TDD as well.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/418973506547188210/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=418973506547188210&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/418973506547188210'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/418973506547188210'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/07/required-reading-material-for-july-2012.html' title='Required Reading Material for July 2012'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-1309246870639584421</id><published>2012-07-19T21:48:00.001+02:00</published><updated>2012-07-21T09:23:34.233+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='dotnetmag'/><title type='text'>If you write an article about TDD, make sure it is correct</title><content type='html'>&lt;p&gt;I spend a majority of my private time reading articles and blog posts, having discussions on &lt;a href="https://twitter.com/ddoomen/"&gt;Twitter&lt;/a&gt;, or engaging in conversations on conferences and community events. I'm realistic enough to understand that my opinions are not necessarily the truth, so I use those opportunities to challenge my own ideas and learn about solutions I would never think of myself.  &lt;p&gt;&lt;img style="float: none; margin-left: auto; display: block; margin-right: auto" src="http://blog.architexa.com/wp-content/uploads/2010/04/vilcus-plug-it-in.jpg" width="201" height="289"&gt;  &lt;p&gt;I recently read an article titled &lt;a href="http://msdn.microsoft.com/en-us/magazine/jj190803.aspx"&gt;Test-Driven ASP.NET MVC&lt;/a&gt; that, although I respect what the author is trying to convey, implies some things that I strongly believe are incorrect or are malpractices. Normally I wouldn't bother to blog about this, but because his article is published at the online &lt;a href="http://msdn.microsoft.com/en-us/magazine/jj190796.aspx"&gt;MSDN Magazine&lt;/a&gt;, I couldn’t resist the urge to correct some things. &lt;br&gt; &lt;ul&gt; &lt;li&gt; &lt;div align="left"&gt;&lt;strong&gt;Thoroughly understand the MVC pattern&lt;/strong&gt;. As Martin Fowler has clearly explained in his post on &lt;a href="http://martinfowler.com/eaaDev/uiArchs.html"&gt;GUI patterns&lt;/a&gt;, the view doesn't manage the presentation of models, nor does it handle interactions with the users. Both are the responsibility of the controllers. They react to keyboard, mouse (and touch) input, use that information to interact with the (domain) model and then decide what view should be used to render the result. In that sense, ASP.NET MVC is reasonably faithful to the original pattern. The only big difference is that in the original MVC pattern, the controllers were directly handling user input whereas in ASP.NET MVC the controllers merely handle HTTP POSTs, GETs and PUTs. &lt;br&gt;&lt;/div&gt; &lt;li&gt;&lt;strong&gt;Tiers are not layers&lt;/strong&gt;. Tiers are used to represent a physical separation whereas layers represent a logical separation. You can have all layers (e.g. presentation, service, domain and data access) hosted on a single tier if you want, or you can assign them to multiple tiers. An example of that is an ASP.NET web site (the presentation layer) hosted on a front-end web server, the service, domain and data access layers hosted on a Intranet application server, and the database hosted on a dedicated database server. The other way around doesn't work like that though. If you didn't account for layering in your architecture, it might be very difficult to deploy your system in a distributed environment. &lt;br&gt;&lt;/li&gt;&lt;/ul&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Keep your Visual Studio projects to a minimum&lt;/strong&gt;. Having many projects such as the project-per-layer suggested in the article considerably slows down compiling, but also causes the startup time of the corresponding application to increase. Loading 10 small assemblies is much slower than loading one big assembly. Jeremy D. Miller mentioned this already in this &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2008/10/10/183438.aspx"&gt;post&lt;/a&gt;, but Patrick Smacchia, the author of NDepend, delivered some proof of if it &lt;a href="http://codebetter.com/blogs/patricksmacchia/archive/2008/12/08/advices-on-partitioning-code-through-net-assemblies.aspx"&gt;here&lt;/a&gt;. Read my original &lt;a href="http://www.dennisdoomen.net/2010/02/how-to-split-solution-into-projects.html"&gt;post&lt;/a&gt; for more guidance on splitting up projects.&lt;br&gt;&lt;/li&gt;&lt;/ul&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Separate test code from production code&lt;/strong&gt;. The author recommends separating test code from production code, a good thing obviously. In fact, I would not even dare to think of polluting the production code base with test code. It might double the size of the assemblies and considerably increase the memory footprint of the application. But as usual, it is not always possible to avoid this. We sometimes have to make a method internal and allow the test projects to access those members using an [InternalsVisibleTo] assembly-level attribute. But that's an exception. What we do more often is make certain methods protected so that we can apply the &lt;a href="http://xunitpatterns.com/Test-Specific%20Subclass.html"&gt;Test-Specific Subclass&lt;/a&gt; pattern. &lt;br&gt;&lt;/li&gt;&lt;/ul&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;TDD is about test-first development&lt;/strong&gt;. The article refers to the Test-Driven Development practice a few times but never explains its essential concepts such as writing tests before writing the production code, the red-green-refactor mantra and the many benefits it offers from a design and maintenance perspective. And neither does it explain what the exact meaning of a unit in unit testing is. In fact, not a single code example shows what a unit test would look like when practicing TDD in an ASP.NET MVC application. Why then call the article Test-Driven ASP.NET MVC. This is even more surprising considering that the author is using &lt;a href="http://codebetter.com/jeremymiller/"&gt;Jeremy D. Miller&lt;/a&gt;'s StructureMap, somebody who has been one of the most noticeable TDD advocates in the community. I wonder whether the author really understands TDD at all. &lt;br&gt; &lt;li&gt;&lt;strong&gt;Use Fakes with caution&lt;/strong&gt;. This is also amplified by his apparent nonchalant use of Visual Studio 2012's &lt;a href="http://www.slideshare.net/gaines/testing-the-untestable-with-visual-studio-2011-fakes"&gt;support&lt;/a&gt; for generating fakes from any class. If you're practicing TDD, you’ll explicitly design the interface of your API or type and think about its dependencies. IMHO, this is an essential part of the thought process involved in TDD. Using a brute-force tool like Fakes or TypeMock Isolator allows you to ignore that part of the process and just generate whatever is needed for your test. I'm not saying Fakes or TypeMock are bad products, but because of their unique capabilities compared to popular mocking frameworks like Moq, Nsubstitue or my own favorite, &lt;a href="https://github.com/FakeItEasy/FakeItEasy/"&gt;FakeItEasy&lt;/a&gt;, I'm afraid many people will follow the author's example. &lt;br&gt; &lt;li&gt;&lt;strong&gt;Dependency injection is not the same as the inversion of control principle&lt;/strong&gt;. I hate it when developers use the terms Dependency Injection and Inversion-of-Control interchangeably. They are two different things and if you don't understand that, make sure you thoroughly read the chapter on the Dependency Inversion Principle in &lt;a href="http://lostechies.com/wp-content/uploads/2011/03/pablos_solid_ebook.pdf"&gt;Pablo's SOLID guidelines&lt;/a&gt;. Although subtlety different, Inversion-of-control is essentially about removing the direct dependencies of one class to another out of that class and providing an abstraction that that class relies on. The inversion in this principle is about moving the responsibility for hooking up the original class with a concrete implementation of that abstraction to a 3rd party, typically an IoC framework. This will improve your chances for loose coupling, better testability, and increased maintainability on the long run. Obviously you don't have to use a DI framework, but if you do it correctly you can gain a lot of benefits from it. I myself heavily rely on Autofac after having used Microsoft Unity &lt;a href="http://www.dennisdoomen.net/2011/09/silverlight-cookbook-switching-to.html"&gt;for a few years&lt;/a&gt;. And remember, just like any principle or tool, use it with caution. Overusing IoC can result in systems were it is difficult to understand what happens. &lt;br&gt; &lt;li&gt;&lt;strong&gt;Resolving dependencies from inside a class completely defies the ideas behind DI&lt;/strong&gt;. Why in the world would you suggest people to use an DI framework like StructureMap and then use a static class to resolve dependencies from within the dependent class? That vaporizes the entire purpose of a DI framework. It's not for nothing that Jeremy D. Miller wrote a post on &lt;a href="http://codebetter.com/jeremymiller/2006/03/09/jeremys-second-law-of-tdd-push-dont-pull/"&gt;Push, Don't Pull&lt;/a&gt;. Even better, that's why the word injection is in Dependency Injection! That is also why the author suggest registering a fake object in his IoC container. This is clearly a design smell resulting from his apparent incorrect understanding of the IoC principle. &lt;br&gt;&lt;/li&gt;&lt;/ul&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;One more issue&lt;/strong&gt;. In the discussion on namespaces and test code, the author suggested to use the name Test (singular) in the project name. Since the namespaces in projects should use the project name as their base, you end-up with the name of something that could be the name of a class. That has been a violation of the Microsoft Design Guidelines and FxCop naming rules since the inception of the .NET Framework. I usually use the name Tests, Testing or Specs for the project that holds the unit and integration tests. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Anyway, the morale of this post is that you should get your facts straight before you write an article that is going to reach so many people. And now that I think of it, why didn't somebody from the MSDN Magazine's staff check this article in the first place? I might be wrong as well, so if disagree let me know by commenting on this post or by pinging me through my twitter handle at &lt;a href="https://twitter.com/ddoomen/"&gt;ddoomen&lt;/a&gt;.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/1309246870639584421/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=1309246870639584421&amp;isPopup=true' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/1309246870639584421'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/1309246870639584421'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/07/if-you-write-article-about-tdd-make.html' title='If you write an article about TDD, make sure it is correct'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-4034953327047601571</id><published>2012-03-23T07:10:00.001+01:00</published><updated>2012-03-23T07:10:20.972+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Fluent Assertions'/><category scheme='http://www.blogger.com/atom/ns#' term='dotnetmag'/><title type='text'>Fluent Assertions gets a bug fix release</title><content type='html'>&lt;p&gt;While we are working on the next major version of Fluent Assertions, we received several smaller bug reports that we bundled in release 1.7.1. &lt;/p&gt; &lt;ul&gt; &lt;li&gt;Fixed a bug that occurs when two collections are compared for equality but the collection contains null.&lt;/li&gt; &lt;li&gt;Fixed a stack overflow while formatting an object graph containing static cyclic references.&lt;/li&gt; &lt;li&gt;Fixed the issue where an exception was thrown when building a failure message by dumping the values of all properties, and one of the properties throws an exception.&lt;/li&gt; &lt;li&gt;Made the handling of cyclic references when validating equality of nested properties configurable (ignore / throw exception)&lt;/li&gt; &lt;li&gt;Fixed some incorrect failure messages when comparing XML elements and attributes&lt;/li&gt; &lt;li&gt;Fixed a NullReferenceException when comparing objects that have a write-only properties&lt;/li&gt; &lt;li&gt;Fixed a potential NullReferenceException while comparing the properties of a complex graph and when a deep property contains a null object.&lt;/li&gt;&lt;/ul&gt; &lt;p align="left"&gt;These days, our preferred delivery mechanism is &lt;a href="https://nuget.org/packages/FluentAssertions"&gt;NuGet&lt;/a&gt;, but you can still get a ZIP from the CodePlex &lt;a href="http://fluentassertions.codeplex.com/releases/view/84640"&gt;landing page&lt;/a&gt;. Issues can be dropped on the &lt;a href="http://fluentassertions.codeplex.com/workitem/list/basic"&gt;Issue Tracker&lt;/a&gt; page, but we also monitor any StackOverflow tagged with &lt;a href="http://stackoverflow.com/questions/tagged/fluent-assertions"&gt;fluent-assertions&lt;/a&gt;.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/4034953327047601571/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=4034953327047601571&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/4034953327047601571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/4034953327047601571'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/03/fluent-assertions-gets-bug-fix-release.html' title='Fluent Assertions gets a bug fix release'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-8958918919807881262</id><published>2012-03-13T12:23:00.001+01:00</published><updated>2012-03-13T12:23:10.933+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Metro'/><category scheme='http://www.blogger.com/atom/ns#' term='Architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='Cookbook'/><title type='text'>About the future of the Silverlight Cookbook</title><content type='html'>&lt;p&gt;Since my &lt;a href="http://www.dennisdoomen.net/2010/09/some-thoughts-on-wcf-data-services-and.html"&gt;first blog post&lt;/a&gt; on the &lt;a href="http://silverlightcookbook.codeplex.com/"&gt;Silverlight Cookbook&lt;/a&gt; in September 2010, I’ve invested a lot of private time in sharing my best practices on building line-of-business application in Silverlight. I &lt;a href="http://silverlightcookbook.codeplex.com/SourceControl/list/changesets"&gt;shared&lt;/a&gt; my code on CodePlex, wrote an entire &lt;a href="http://www.dennisdoomen.net/search/label/Cookbook"&gt;series of blog posts&lt;/a&gt;, and &lt;a href="http://www.slideshare.net/dennisdoomen/introducing-the-silverlight-cookbook"&gt;talked&lt;/a&gt; about the Cookbook at several events.&lt;/p&gt; &lt;p&gt;Times change, and although &lt;a href="http://www.dennisdoomen.net/2011/05/choosing-right-web-technology-for.html"&gt;I’ve always believed&lt;/a&gt; (and still do) that Silverlight is a great technology for building interactive line-of-business applications, the lack of a roadmap for Silverlight is making even my clients hesitate. And yes, I did explain them about Microsoft officially supporting Silverlight 5 until 2021.&lt;/p&gt; &lt;p&gt;To help me make a decision about the direction of the Cookbook, I’ve started a &lt;a href="http://www.dennisdoomen.net/"&gt;poll&lt;/a&gt; in the side-bar of my blog. The important question I ask is whether I should continue with Silverlight, move towards Windows 8 Apps (in XAML/C# of course), or finally make the jump to HTML5/JavaScript. The few votes I’ve received so far tend to lean towards the latter, but I’m not willing to make that jump until more people have voted. &lt;/p&gt; &lt;p&gt;So let know!&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/8958918919807881262/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=8958918919807881262&amp;isPopup=true' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/8958918919807881262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/8958918919807881262'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/03/about-future-of-silverlight-cookbook.html' title='About the future of the Silverlight Cookbook'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-4948875023692045918</id><published>2012-01-13T20:22:00.002+01:00</published><updated>2012-01-14T09:22:14.555+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Fluent Assertions'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Fluent Assertions 1.7.0 has been released</title><content type='html'>&lt;p&gt;It has barely been more than two months ago, but the number of downloads through CodePlex and Nuget combined has exceeded 2000. Me and co-author &lt;a href="https://twitter.com/#!/mpopdam"&gt;Martin Opdam&lt;/a&gt; thought that to be a nice reason for releasing a new version of Fluent Assertions. This isn't a big release, but since we are following &lt;a href="http://semver.org/"&gt;semantic versioning&lt;/a&gt; and we added new functionality as well as some bug fixes, an increment in the minor number is in order. Since we prefer NuGet ourselves, get the latest version through its &lt;a href="https://nuget.org/packages/FluentAssertions"&gt;NuGet&lt;/a&gt; landing page. If you prefer the old-fashioned way, get it through &lt;a href="http://fluentassertions.codeplex.com/"&gt;CodePlex&lt;/a&gt;. Here are the release notes. &lt;br&gt;&lt;br&gt;&lt;strong&gt;What's New&lt;/strong&gt; &lt;/p&gt; &lt;ul&gt; &lt;li&gt;Added methods for asserting that a collection of types matching a predicate have specific methods that are virtual or marked with a specific attribute.&lt;/li&gt;&lt;/ul&gt; &lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(MyController).Methods()&lt;br&gt;.ThatReturn&amp;lt;ActionResult&amp;gt;()&lt;br&gt;.ThatAreDecoratedWith&amp;lt;HttpPostAttribute&amp;gt;()&lt;br&gt;.Should()&lt;br&gt;.BeDecoratedWith&amp;lt;ValidateAntiForgeryTokenAttribute&amp;gt;(&lt;br&gt;&lt;span class="str"&gt;"because all Actions with HttpPost require ValidateAntiForgeryToken"&lt;/span&gt;);&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Added methods for asserting XElements and Xattributes&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;xDocument.Should().HaveRoot(&lt;span class="str"&gt;"configuration"&lt;/span&gt;);&lt;br&gt;xDocument.Should().HaveElement(&lt;span class="str"&gt;"settings"&lt;/span&gt;);&lt;br&gt;&lt;br&gt;xElement.Should().HaveAttribute(&lt;span class="str"&gt;"age"&lt;/span&gt;, &lt;span class="str"&gt;"36"&lt;/span&gt;);&lt;br&gt;xElement.Should().HaveElement(&lt;span class="str"&gt;"address"&lt;/span&gt;);&lt;br&gt;&lt;br&gt;xAttribute.Should().HaveValue(&lt;span class="str"&gt;"Amsterdam"&lt;/span&gt;);&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Added support for recursively comparing the properties of nested (collection of objects ). By default it will compare all properties of the expected object graph, unless SharedProperties is used.&lt;br /&gt;&lt;li&gt;Added a fallback mechanism so that if FA cannot find any of the supported frameworks, it will fall back to using a custom AssertFailedException exception class rather than crashing.&lt;br /&gt;&lt;li&gt;Added support for ComparisonMode.StartWith and ComparisonMode.StartWithEquivalent when asserting the message of an exception.&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;Bug Fixes &amp;amp; Improvements&lt;/strong&gt; &lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;For assertions that verify against a Type, the failure message will use the AssemblyQualifiedName rather than just the name of the type.&lt;br /&gt;&lt;li&gt;Fixed a bug so that collection.Should().OnlyContain(lamba) now throws if the collection is empty. See &lt;a href="http://fluentassertions.codeplex.com/discussions/278868"&gt;this discussion&lt;/a&gt; for more details.&lt;br /&gt;&lt;li&gt;Minor fix that ignores trailing blank characters when looking for the 'because' text in the reason of an assertion. &lt;br /&gt;&lt;li&gt;Added better and deeper detection of cyclic references when recursively comparing properties or generating a string representation of a complex object graph.&lt;br /&gt;&lt;li&gt;For long strings, the error message for string.Should().StartWith() places the actual and expected strings on seperate lines. This makes it easier to find the differences. &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;By the way, we’ve also spent some time updating the &lt;a href="http://fluentassertions.codeplex.com/documentation"&gt;documentation&lt;/a&gt;. &lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/4948875023692045918/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=4948875023692045918&amp;isPopup=true' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/4948875023692045918'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/4948875023692045918'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/01/fluent-assertions-170-has-been-released.html' title='Fluent Assertions 1.7.0 has been released'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-6504668812534501996</id><published>2012-01-11T07:47:00.001+01:00</published><updated>2012-01-13T20:25:13.507+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ALM'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><category scheme='http://www.blogger.com/atom/ns#' term='InRetrospect'/><title type='text'>In Retrospect: About getting through your Sprint</title><content type='html'>&lt;p&gt;This is the fourth of &lt;a href="http://www.dennisdoomen.net/search/label/InRetrospect"&gt;several post&lt;/a&gt;s in which I’d like to share some of the things we learned throughout more than a year of Agile development using Scrum. Some of them might appear as open doors, but I wish I knew or thought about those before I started that project. Just by looking back at the mistakes two teams of about 8 developers made in a period of 12 months, they apparently aren’t that obvious. So after having discussed our ideas about &lt;a href="http://www.dennisdoomen.net/2011/11/in-retrospect-about-bugs.html"&gt;dealing with bugs&lt;/a&gt;, let’s talk about what you can do to get yourself through the sprint as efficient as possible.  &lt;p&gt;&lt;strong&gt;&lt;font color="#992211"&gt;About Stories&lt;/font&gt;&lt;/strong&gt;  &lt;p&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" src="http://3.bp.blogspot.com/_56a0f0cVhQk/S_iBTaq0FdI/AAAAAAAAANQ/sSWXwnaFFsI/s1600/BOOK.jpg" width="407" height="253"&gt;&lt;strong&gt;Be pragmatic&lt;/strong&gt;  &lt;p&gt;If, during the sprint, some story causes a lot of discussion and the product owner (PO) is not available to take a decision, cut off the discussion as quickly as possible. If it is a decision with a high reversibility – e.g. you can revert the decision without noticeable impact - just go on. But if the PO is really needed, put the story on hold. Obviously this is a waste of the team’s time, but the PO has to accept that his availability is quintessential.  &lt;p&gt;&lt;b&gt;Always discuss a story with the product owner&lt;/b&gt;  &lt;p&gt;I’ve already said it before, and I’ll do it again; a user story is a placeholder for a discussion with the PO at the time you pick up the story. So before you start doing a more detailed breakdown with your pairing partner, consult the PO for the most recent information. It happened more than once that the PO attended a business review the other day that affected the details of a particular story.  &lt;p&gt;&lt;b&gt;Don’t talk about a story as ‘that 3-story point story’ &lt;/b&gt; &lt;p&gt;At some point in time, we noticed that the team started to talk about a bigger story (that seemed to drag on and on) as ‘that 5-point story’. This continued for a few days until we discovered that nobody knew exactly anymore what the story was about, and more importantly, what its scope was. Worse, we already added functionality that wasn’t part of the scope at all. We then agreed to force ourselves to refer to a story by its title or purpose.  &lt;p&gt;&lt;b&gt;Try to start the sprint with the blocking story&lt;/b&gt;  &lt;p&gt;Obviously you should start with the story that is going to be blocking for other stories, even if it is not the one with the highest business priority. Although this may seem obvious, it is quite common to lose track of any dependencies between many stories during the sprint planning. This is why we introduced a separate sanity check meeting to particularly look for technical risks or dependencies between stories.  &lt;p&gt;&lt;b&gt;&lt;font color="#992211"&gt;About the Product Owner&lt;/font&gt;&lt;/b&gt;  &lt;p&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" src="http://www.assistantplus.be/uploads/2/default/2536.jpg" width="282" height="296"&gt;  &lt;p&gt;&lt;b&gt;The product owner must sit with the team at all times&lt;/b&gt;  &lt;p&gt;You’ll be surprised to see how many product owners fail to understand how important their role is and refuse to sit with the team physically. In fact, some of them think that being a PO is a part-time job that can easily be combined with other responsibilities. We’ve learned firsthand that they are wrong.  &lt;p&gt;Because our PO sat with us, he managed to detect conflicting business rules in discussions between developers more than once. And since written text can never prevent ambiguity, having him around all the time has saved us a tremendous amount of time already. At first, we thought that regular meetings should have been sufficient. But small questions about details or choices happen throughout the entire day. If that question is not answered right away, then the developer is either forced to make a (potentially wrong) assumption, or to put the story on hold. That may not seem a big problem, but just consider the &lt;a href="http://www.joelonsoftware.com/articles/fog0000000022.html"&gt;theory&lt;/a&gt; that on average a person needs about 15 minutes to compensate for a context switch.  &lt;p&gt;&lt;b&gt;The product owner should proactively participate in the development process&lt;/b&gt;  &lt;p&gt;Not only should the product owner sit with the team, he or she should proactively participate in the development process. If you don’t, you risk the chance that the team is building something different than what the PO intended. This happened to us when the PO provided a mockup to some team members. He then went off and didn’t look at the end-result until the end of the sprint. Only then he discovered that the developer misinterpreted the UI behavior of a particular part of the application. As a PO, don’t be afraid to sit with a team member that is working on some new functionality without being asked to. Also regularly join the stand-up meeting if you want to get a heads-up on what the team is doing that day.  &lt;p&gt;&lt;font color="#992211"&gt;&lt;b&gt;About Making Progress&lt;/b&gt; &lt;/font&gt; &lt;p&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" src="http://www.muehlemann.com/wp-content/uploads/2009/02/dsc02646.jpg" width="419" height="314"&gt;  &lt;p&gt;&lt;b&gt;Don’t change the members of the team throughout the sprint&lt;/b&gt;  &lt;p&gt;The velocity that was calculated during the sprint planning is based on the average focus factor of the team and the available working days. You may think that removing a team member simply reduces the number of working days, but it will affect the focus factor as well. So removing a team member will not necessarily have a negative impact.  &lt;p&gt;Adding a new team member is a completely different thing. Firstly, you don’t have any historical figures to estimate the impact of the addition to the team. Secondly, that new developer wasn’t part of the sprint planning and missed some important discussions, even if he is very experienced. And third, he’ll need a whole lot of time from the rest of the team to get up to speed.  &lt;p&gt;We knew of this when we were offered a new very senior team member, but we seriously underestimated the time it took to understand the functionality, to get used to the team’s development practices, and to really grasp the complexity of our architecture.  &lt;p&gt;&lt;b&gt;Focus on moving stuff to done-done&lt;/b&gt;&lt;br&gt;I keep reminding everybody that the entire team is responsible for getting stories to done-done. However, developers seem to have the natural tendency to ignore stories in any state following ‘review’. But never allow team member to pick up a new story until all the other ones are done. In worst case, let them do pair programming, pair reviewing or pair testing, or whatever is necessary to get to those stories to done.  &lt;p&gt;&lt;b&gt;Take special precautions when you are out-of-the-office the next day&lt;/b&gt;  &lt;p&gt;If you know you’ll be out of the office the next day, consider the importance of the task you’re working on. If suspending it for a day isn’t a real issue (see next practice), just make sure you carefully write down where you left. If the work is important, finish the day by pair programming with a developer who can continue the next day.  &lt;p&gt;&lt;b&gt;Hand over work in the last week of the sprint&lt;/b&gt;  &lt;p&gt;As a team, you don’t want to lose any time in the last week of the sprint. So if you’re out of the office the next day, and it’s the last week of the sprint, be very thorough in transferring the work to another team member. If you fail to do so, don’t look surprised when you’re being called by a team member for some answers. They have all the rights to do so if you jeopardize progress in such a way.  &lt;p&gt;&lt;b&gt;Don’t ignore the burn-down chart&lt;/b&gt;  &lt;p&gt;I remember a particular day when the burn-down chart made a sudden dive down and we all assumed that the team just happened to be very productive that day before. Unfortunately somebody accidentally closed two very important tasks, but we didn’t discover that until the third week of the sprint. Imagine us struggling to explain that to our product owner. So, always investigate unexpected variations in your burn-down chart.  &lt;p&gt;&lt;b&gt;Track your progress carefully&lt;/b&gt;  &lt;p&gt;One of the most recurring problems in our project was our failure to keep track of all the little details involved in completing a story. Stories are broken down in tasks, whereas tasks are broken down in lots of small OneNote items with a checkmark. The biggest problem was that not all developers were doing this at the same level of detail. Usually there was a correlation between that level of detail and the size of individual code check-ins. That’s why I’d advise you to rigorously use OneNote to keep track of anything that still needs to be done to complete the task. When you working on some code changes, and you discover or remember something else not directly related to those lines, add a check marked line in OneNote and continue as usual. A nice side-effect of this approach is that your check-ins tend to be much smaller and less susceptible to merge conflicts.  &lt;p&gt;&lt;b&gt;Switch pairs after two days of working on the same story.&lt;/b&gt;  &lt;p&gt;We’ve noticed that working too long on the same story causes some developer to miss important details or lose track of the global picture. And not only that, we’ve seen that developers that were pairing for more than a few days started to include tasks that were never part of the original scope. That’s why we try to switch one of the developers every one or two days.  &lt;p&gt;&lt;font color="#992211"&gt;&lt;b&gt;About Stand-up Meetings&lt;/b&gt; &lt;/font&gt; &lt;p&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" src="http://www.psychologicalscience.org/onlyhuman/uploaded_images/lineup-717775.jpg" width="459" height="297"&gt;  &lt;p&gt;&lt;b&gt;Organize the stand-up at a fixed time of day&lt;/b&gt;&lt;b&gt;&lt;/b&gt;  &lt;p&gt;We’ve always scheduled the stand-up meeting at 9:30 in the morning, primarily because a few team members were accustomed to come in between 9:15-10:00. However, over time, some of those same members started to come in later and later, and we simply waited until all were in.  &lt;p&gt;&lt;b&gt;Keep them short&lt;/b&gt;  &lt;p&gt;Our stand-up meetings tended to last too long too often. This was mostly caused by discussions that should have been taken off-line. We’ve improved on that, but as the architect of the team, I often use the stand-up to get everybody up-to-date on important decision decisions. In particular because some members start at 7:00 in the morning, while others don’t come in before 9:30.  &lt;p&gt;&lt;b&gt;Focus on the stories and not on the team members&lt;/b&gt;  &lt;p&gt;We’ve learned that traditional stand-up meetings where the ‘microphone’ moves from one team member to another don’t give enough insight in the risks and progress of the stories on the board. That’s why we tried using the board as the centerpiece by discussing stories one by one, starting with the one that is closest to done. This has significantly improved understanding the status of each story, and gives team members more room to work on stories together.  &lt;p&gt;&lt;b&gt;Pay attention to the remaining hours&lt;/b&gt;  &lt;p&gt;We had no trouble discussing the status and the challenges of a particular story during the stand-up meeting. But somehow we often forgot to query for the remaining hours of the tasks associated with that story. Being aware of those hours makes it more natural to mentally compare the work that still needs to be done against the hours still left and whether or not that is feasible.  &lt;p&gt;&lt;b&gt;Stand-up, don’t lean&lt;/b&gt;  &lt;p&gt;Many developers don’t seem to understand why standing is so important in a stand-up meeting. Why can’t you lean against a shelf, on a chair, or against the wall? Because that makes that position to convenient! The whole purpose of the stand-up meeting is to keep it as short as possible. So the simple requirement to stand up motivates them to spend as little time as possible on conveying their status.  &lt;p&gt;Remember that these are the experiences of me and my team, so they might not work as well for you as they did for us. Nevertheless, I’m really interested in learning about your own experiences, so let me know by commenting on this post or tweeting me at &lt;a href="http://twitter.com/ddoomen"&gt;ddoomen&lt;/a&gt;. Next time, I’ll be sharing my opinions on some of the practices from Extreme Programming. &lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/6504668812534501996/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=6504668812534501996&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/6504668812534501996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/6504668812534501996'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2012/01/in-retrospect-about-getting-through.html' title='In Retrospect: About getting through your Sprint'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_56a0f0cVhQk/S_iBTaq0FdI/AAAAAAAAANQ/sSWXwnaFFsI/s72-c/BOOK.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-3465801355493624643</id><published>2011-11-30T19:50:00.001+01:00</published><updated>2011-11-30T19:50:19.743+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Coding Guidelines'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='dotnetmag'/><title type='text'>Feedback Requested: Is there any valid usage for the ‘new’ keyword?</title><content type='html'>&lt;p&gt;Yesterday I ended up being part of a discussion about using the ‘new’ keyword to hide base-class members. A colleague of mine used it to alter a base-class property in a derived class with the purpose of making it more strongly typed. &lt;/p&gt; &lt;p&gt;I’ve always rationalized guideline AV1010 (&lt;em&gt;Don’t hide inherited members with the new keyword&lt;/em&gt;) by referring to the &lt;a href="http://www.objectmentor.com/resources/articles/lsp.pdf"&gt;Liskov Substitution Principle&lt;/a&gt; and claiming that if you need it, then you’re probably facing a design smell. In this particular case that was indeed the issue, so after fixing it, the keyword wasn’t necessary at all. &lt;/p&gt; &lt;p&gt;But, his arguments did make sense. In fact, he was so convinced about it that he sent me a proposal for an exception to the &lt;a href="http://csharpguidelines.codeplex.com/"&gt;C# Coding Guidelines&lt;/a&gt;. As part of the discussion, he also sent me some &lt;a href="http://blogs.msdn.com/b/ericlippert/archive/2008/05/21/method-hiding-apologia.aspx"&gt;background info&lt;/a&gt; on the keyword’s origin by C# co-author &lt;a href="http://blogs.msdn.com/b/ericlippert/"&gt;Eric Lippert&lt;/a&gt;. &lt;/p&gt; &lt;p&gt;This is the example he claims is a valid and useful exception to the guideline. The purpose was to ensure that a manager always has a smart phone rather than any other type of phone.&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Phone&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SmartPhone : Phone&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Employee&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Employee(Phone phone)&lt;br /&gt;        {&lt;br /&gt;            Phone = phone;&lt;br /&gt;        }&lt;br /&gt; &lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; Phone Phone { get; }&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Manager : Employee&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Manager(SmartPhone phone) : &lt;span class="kwrd"&gt;base&lt;/span&gt;(phone)&lt;br /&gt;        {&lt;br /&gt;        }&lt;br /&gt; &lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; SmartPhone Phone&lt;br /&gt;        {&lt;br /&gt;            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; (SmartPhone)&lt;span class="kwrd"&gt;base&lt;/span&gt;.Phone; }&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;As far as I see it, the Manager class is violating the contract defined by the Employee class, and thus violates the LSP. If an employee can have any type of phone, and a Manager cannot, than clearly, a Manager is &lt;strong&gt;not&lt;/strong&gt; an Employee. They may share some characteristics, but that might be solved by a common base-class. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" title="Small Liskov Substitution Principle poster" border="0" alt="Small Liskov Substitution Principle poster" src="http://www.globalnerdy.com/wordpress/wp-content/uploads/2009/07/liskov_substitution_principle_small.jpg" width="450" height="338"&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I don’t easily loosen guidelines unless there’s a really sensible exception, but I do like to give any suggestion serious consideration. So please provide me your feedback. Is there any valid reason for using the ‘new’ keyword other than for legacy purposes (where you can’t change some base-class code) and which is not a design smell? &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Let me know by commenting on this post, by sending me &lt;a href="mailto:dennis.doomen@avivasolutions.nl"&gt;email&lt;/a&gt; or &lt;a href="http://twitter.com/#!/ddoomen"&gt;tweeting&lt;/a&gt; me at @ddoomen.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/3465801355493624643/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=3465801355493624643&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/3465801355493624643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/3465801355493624643'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2011/11/feedback-requested-is-there-any-valid.html' title='Feedback Requested: Is there any valid usage for the ‘new’ keyword?'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15137028.post-1359719171013592516</id><published>2011-11-04T12:43:00.000+01:00</published><updated>2011-11-17T13:09:19.413+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dotnetmag'/><title type='text'>Almost five years at Aviva Solutions and still enjoying it every minute</title><content type='html'>&lt;p&gt;I know, I know, I’m still 3 months away from it. But without doubt, on the 1st of February, I will be celebrating my first 5-year anniversary in the 15 years of my professional career. That might sound silly, but I’ve always had a problem of getting restless after a few years . It never was a problem with the people around me, and in fact, from a employee point of view I’ve never had anything to complain at all. It has just been my desire to move along at some point and discover a fresh new environment. &lt;/p&gt; &lt;p&gt;Strangely enough I don’t have that problem at all currently. Some may claim its my age and the corresponding desire for finding a final settlement, but I’m quite sure it’s the uniqueness of my current employer, &lt;a href="http://www.avivasolutions.nl/"&gt;Aviva Solutions&lt;/a&gt;. I think this is well illustrated by this photo collage (click for a bigger picture).&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-_ItkpCOqByQ/TrPJOhwQ11I/AAAAAAAAIlA/SQ-aZm4JTSY/s1600-h/Collage%252520Summer%252520Event%252520XL%2525202011%25255B6%25255D.jpg" target="_blank"&gt;&lt;img style="display: inline" title="Collage Summer Event XL 2011" alt="Collage Summer Event XL 2011" src="http://lh6.ggpht.com/-Pyiq9PThfy8/TrPJPqMcdOI/AAAAAAAAIlE/wJ8qfpt7HZQ/Collage%252520Summer%252520Event%252520XL%2525202011_thumb%25255B4%25255D.jpg?imgmax=800" width="582" height="296"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Obviously our annual social trip to a warm place close to the beach is only barely sufficient to keep me happy (pun intended). But the fact that we have practically no hierarchy, that I enjoy the company of some very experienced colleagues, and that our two CEOs value each and every employee by heavily facilitating in their personal and technical knowledge and skills might be more important.&lt;/p&gt; &lt;p&gt;To clarify my added value to the company, I try to lead the themes &lt;em&gt;Custom Solutions &amp;amp; ALM&lt;/em&gt; and &lt;em&gt;Cloud Solutions&lt;/em&gt;. That means that I spend four days a week on (long-term) consultancy jobs and one day in making sure we as a company invest enough in current and new Microsoft technologies, practices and software development methodologies. &lt;/p&gt; &lt;p&gt;BTW, the other themes include &lt;em&gt;Application Integration&lt;/em&gt;, &lt;em&gt;E-Commerce &amp;amp; CMS&lt;/em&gt;, &lt;em&gt;Business Intelligence &lt;/em&gt;and &lt;em&gt;Portals &amp;amp; Collaboration&lt;/em&gt;. This doesn’t mean anybody is fixed to a particular theme for life. Its just to allow them to focus a bit and prevent them from drowning in the elaborate world of Microsoft. In fact, everybody is expected to have thorough knowledge of the .NET Framework and a clear understanding with the practices from Extreme Programming and Agile methodologies such as Scrum or Kanban.&lt;/p&gt; &lt;p&gt;We’re only with 40 professionals right now, and we’re still looking for new colleagues that match the following characteristics:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Are passionate about the software development profession  &lt;li&gt;Like to share their opinions  &lt;li&gt;Are capable of conveying that opinion to the lesser gods (read: managers)  &lt;li&gt;Are not afraid to propose alternate or better solutions to a problem  &lt;li&gt;Have a natural tendency of trying to improve themselves and the people around them  &lt;li&gt;Speak Dutch fluently &lt;li&gt;Who don’t have anything against an annual weekend at a warm sunny beach and a drink here and there&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;If you think you fit that description in any way, let me know by tweeting me at &lt;a href="http://twitter.com/#!/ddoomen"&gt;@ddoomen&lt;/a&gt; or emailing me at &lt;a href="mailto:dennis.doomen@avivasolutions.nl"&gt;dennis.doomen@avivasolutions.nl&lt;/a&gt;. We might be drinking a beer at next year’s annual event.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://www.dennisdoomen.net/feeds/1359719171013592516/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15137028&amp;postID=1359719171013592516&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/1359719171013592516'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15137028/posts/default/1359719171013592516'/><link rel='alternate' type='text/html' href='http://www.dennisdoomen.net/2011/11/almost-five-years-at-aviva-solutions.html' title='Almost five years at Aviva Solutions and still enjoying it every minute'/><author><name>Dennis Doomen</name><uri>http://www.blogger.com/profile/04363006875303293621</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://bp1.blogger.com/_sv2gnsft17w/R75sgsYv9gI/AAAAAAAABHY/ezDFaHgAteA/S220/Dennis.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/-Pyiq9PThfy8/TrPJPqMcdOI/AAAAAAAAIlE/wJ8qfpt7HZQ/s72-c/Collage%252520Summer%252520Event%252520XL%2525202011_thumb%25255B4%25255D.jpg?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry></feed>