<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="https://blog.aabech.no/rss/xslt"?>
<rss xmlns:a10="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title>Lars-Erik's blog</title>
    <link>https://blog.aabech.no/</link>
    <description>Ramblings about Umbraco, .net and JavaScript development. With a sprinkle of other stuff.</description>
    <generator>Articulate, blogging built on Umbraco</generator>
    <item>
      <guid isPermaLink="false">1163</guid>
      <link>https://blog.aabech.no/archive/our-umbraco-community-contentlist-10-beta-released/</link>
      <category>Umbraco</category>
      <title>Our Umbraco Community ContentList 1.0 (beta) released</title>
      <description>&lt;p&gt;ContentList is a grid editor we've used internally at MarkedsPartner since 2016. It helps editors and designers insert lists of content in the grid without having to worry about queries, paging or building new templates.&lt;br /&gt;
I've finally been able to upgrade it to Umbraco 8 and polished it a bit. It's still slightly in beta, but there's nothing special but a bit of CSS polish lacking, so it should be fairly safe to use in production. 👼&lt;/p&gt;
&lt;p&gt;There's a whole documentation piece in the readme &lt;a href="https://github.com/lars-erik/Our.Umbraco.ContentList"&gt;over on github&lt;/a&gt;, so I won't bother with a whole lot of prose in this blogpost, but I recorded a half an hour demo (below) showing all the aspects of implementing its use in an Umbraco site.&lt;/p&gt;
&lt;p&gt;There's really not much to do once you get the hang of it, and our editors and staff have been enjoying using it for five years, so I hope you will too.&lt;/p&gt;
&lt;p&gt;Here's the demo, and I really hope to get your feedback here, on github or on youtube.
The first 3-4 minutes show the gist of it, so no need to sit through the full half hour if you're just curious. 👍&lt;/p&gt;
&lt;iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/7O6Es1SNf9s" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;</description>
      <pubDate>Wed, 01 Apr 2020 21:57:27 Z</pubDate>
      <a10:updated>2020-04-01T21:57:27Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1127</guid>
      <link>https://blog.aabech.no/archive/umbracosupport-got-typed-content/</link>
      <category>unit testing</category>
      <category>umbraco</category>
      <title>UmbracoSupport got typed content</title>
      <description>&lt;h2&gt;What's UmbracoSupport?&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;UmbracoSupport&lt;/code&gt; is a class I've been introducing to my unit tests over the last year or so.
It allows me to have my own hierarchy for tests, as well as re-using all of Umbraco's own
stubbing code. I've written about it in a post called &lt;a href="/archive/the-basics-of-unit-testing-umbraco-just-got-simpler"&gt;Unit testing Umbraco just got simpler&lt;/a&gt;,
and its gut's code is described in details in &lt;a href="/archive/the-basics-of-unit-testing-umbraco"&gt;The basics of unit testing Umbraco&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;A quick primer on what's already available&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;BaseDatabaseFactoryTest&lt;/code&gt; in &lt;code&gt;Umbraco.Tests&lt;/code&gt; has a method called &lt;code&gt;GetXmlContent&lt;/code&gt;.
It replaces the &lt;code&gt;umbraco.config&lt;/code&gt; file that acts as the cache at runtime.
It makes &lt;code&gt;UmbracoContext.Current.ContentCache&lt;/code&gt; tick in unit tests.
The base tests out of the box has a small flaw though. They can't &amp;quot;popuplate&amp;quot; properties.
All you get is the hierarchy.&lt;/p&gt;
&lt;p&gt;Usually I've injected an &lt;code&gt;IPublishedContentCache&lt;/code&gt; to my controllers. When testing them,
I've created a mock instance of the &lt;code&gt;IPublishedContentCache&lt;/code&gt;. However, all my code has to use
the non-context aware overloads. For instance &lt;code&gt;cache.GetById(umbracoContext, false, id)&lt;/code&gt;.
There's also a whole lot of ugly mocking code going on to set up queries and stubbed content.
How to stub properties on stubbed content is described in &lt;a href="/archive/slides-from-cg16-and-testing-ipublishedcontent-properties/"&gt;Slides from CG 2016 and testing IPublishedContent properties&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;So what's new?&lt;/h2&gt;
&lt;p&gt;As mentioned, I've been throwing around all kinds of ugly stubbing code for content and I've also been tampering with &lt;code&gt;Umbraco.Tests&lt;/code&gt;'s &lt;code&gt;GetXmlContent()&lt;/code&gt; to use the &amp;quot;built-in&amp;quot; content stubs.
It's all been done before in misc. tests in Umbraco. I finally got my s**t together and refactored all my setup spaghetti into a few small helpers on the &lt;code&gt;UmbracoSupport&lt;/code&gt; class.&lt;/p&gt;
&lt;p&gt;Let's go over them in increasing &amp;quot;integrationness&amp;quot;.&lt;/p&gt;
&lt;h2&gt;Pure hierarchy&lt;/h2&gt;
&lt;p&gt;Your basic hierarchy structure can be set up by simply returning a string from an overload of &lt;code&gt;BaseDatabaseFactoryTest.GetXmlContent&lt;/code&gt;. &lt;code&gt;UmbracoSupport&lt;/code&gt; overloads this method and returns whatever you've set on the &lt;code&gt;UmbracoSupport.ContentCacheXml&lt;/code&gt; property. I recommend using the technique described in &lt;a href="/archive/automating-creation-of-source-data-for-tests"&gt;Automating creating of source data for tests&lt;/a&gt; with this. You can even extend that code to have fixture specific content caches.&lt;/p&gt;
&lt;p&gt;In any case, to make this work, you just need to set the XML in the setup method.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: I've got some probs with the markdown parsing here, imagine the CDATA parts of the XML is correctly written.&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[SetUp]
public void Setup()
{
    umbracoSupport = new UmbracoSupport();
    umbracoSupport.SetupUmbraco();

    // This XML is what the ContentCache will represent
    umbracoSupport.ContentCacheXml = @&amp;quot;
        &amp;lt;?xml version=&amp;quot;&amp;quot;1.0&amp;quot;&amp;quot; encoding=&amp;quot;&amp;quot;utf-8&amp;quot;&amp;quot;?&amp;gt;
        &amp;lt;!DOCTYPE root [
          &amp;lt;!ELEMENT contentBase ANY&amp;gt;
          &amp;lt;!ELEMENT home ANY&amp;gt;
          &amp;lt;!ATTLIST home id ID #REQUIRED&amp;gt;
          &amp;lt;!ELEMENT page ANY&amp;gt;
          &amp;lt;!ATTLIST page id ID #REQUIRED&amp;gt;
        ]&amp;gt;
        &amp;lt;root id=&amp;quot;&amp;quot;-1=&amp;quot;&amp;quot;&amp;quot;&amp;quot;&amp;gt;
          &amp;lt;home id=&amp;quot;&amp;quot;1103=&amp;quot;&amp;quot;&amp;quot;&amp;quot; key=&amp;quot;&amp;quot;156f1933-e327-4dce-b665-110d62720d03=&amp;quot;&amp;quot;&amp;quot;&amp;quot; parentID=&amp;quot;&amp;quot;-1=&amp;quot;&amp;quot;&amp;quot;&amp;quot; level=&amp;quot;&amp;quot;1=&amp;quot;&amp;quot;&amp;quot;&amp;quot; creatorID=&amp;quot;&amp;quot;0=&amp;quot;&amp;quot;&amp;quot;&amp;quot; sortOrder=&amp;quot;&amp;quot;0=&amp;quot;&amp;quot;&amp;quot;&amp;quot; createDate=&amp;quot;&amp;quot;2017-10-17T20:25:12=&amp;quot;&amp;quot;&amp;quot;&amp;quot; updateDate=&amp;quot;&amp;quot;2017-10-17T20:25:17=&amp;quot;&amp;quot;&amp;quot;&amp;quot; nodeName=&amp;quot;&amp;quot;Home=&amp;quot;&amp;quot;&amp;quot;&amp;quot; urlName=&amp;quot;&amp;quot;home=&amp;quot;&amp;quot;&amp;quot;&amp;quot; path=&amp;quot;&amp;quot;-1,1103=&amp;quot;&amp;quot;&amp;quot;&amp;quot; isDoc=&amp;quot;&amp;quot;&amp;quot;&amp;quot; nodeType=&amp;quot;&amp;quot;1093=&amp;quot;&amp;quot;&amp;quot;&amp;quot; creatorName=&amp;quot;&amp;quot;Admin=&amp;quot;&amp;quot;&amp;quot;&amp;quot; writerName=&amp;quot;&amp;quot;Admin=&amp;quot;&amp;quot;&amp;quot;&amp;quot; writerID=&amp;quot;&amp;quot;0=&amp;quot;&amp;quot;&amp;quot;&amp;quot; template=&amp;quot;&amp;quot;1064=&amp;quot;&amp;quot;&amp;quot;&amp;quot; nodeTypeAlias=&amp;quot;&amp;quot;home=&amp;quot;&amp;quot;&amp;quot;&amp;quot;&amp;gt;
            &amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;
            &amp;lt;excerptCount&amp;gt;4&amp;lt;/excerptCount&amp;gt;
            &amp;lt;page id=&amp;quot;&amp;quot;1122=&amp;quot;&amp;quot;&amp;quot;&amp;quot; key=&amp;quot;&amp;quot;1cb33e0a-400a-4938-9547-b05a35739b8b=&amp;quot;&amp;quot;&amp;quot;&amp;quot; parentID=&amp;quot;&amp;quot;1103=&amp;quot;&amp;quot;&amp;quot;&amp;quot; level=&amp;quot;&amp;quot;2=&amp;quot;&amp;quot;&amp;quot;&amp;quot; creatorID=&amp;quot;&amp;quot;0=&amp;quot;&amp;quot;&amp;quot;&amp;quot; sortOrder=&amp;quot;&amp;quot;0=&amp;quot;&amp;quot;&amp;quot;&amp;quot; createDate=&amp;quot;&amp;quot;2017-10-17T20:25:12=&amp;quot;&amp;quot;&amp;quot;&amp;quot; updateDate=&amp;quot;&amp;quot;2017-10-17T20:25:17=&amp;quot;&amp;quot;&amp;quot;&amp;quot; nodeName=&amp;quot;&amp;quot;Page=&amp;quot;&amp;quot; 1=&amp;quot;&amp;quot;&amp;quot;&amp;quot; urlName=&amp;quot;&amp;quot;page1=&amp;quot;&amp;quot;&amp;quot;&amp;quot; path=&amp;quot;&amp;quot;-1,1103,1122=&amp;quot;&amp;quot;&amp;quot;&amp;quot; isDoc=&amp;quot;&amp;quot;&amp;quot;&amp;quot; nodeType=&amp;quot;&amp;quot;1095=&amp;quot;&amp;quot;&amp;quot;&amp;quot; creatorName=&amp;quot;&amp;quot;Admin=&amp;quot;&amp;quot;&amp;quot;&amp;quot; writerName=&amp;quot;&amp;quot;Admin=&amp;quot;&amp;quot;&amp;quot;&amp;quot; writerID=&amp;quot;&amp;quot;0=&amp;quot;&amp;quot;&amp;quot;&amp;quot; template=&amp;quot;&amp;quot;1060=&amp;quot;&amp;quot;&amp;quot;&amp;quot; nodeTypeAlias=&amp;quot;&amp;quot;page=&amp;quot;&amp;quot;&amp;quot;&amp;quot;&amp;gt;
              &amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;
              &amp;lt;excerpt&amp;gt;[CDATA[Lorem ipsum dolor...]]&amp;lt;/excerpt&amp;gt;
              &amp;lt;body&amp;gt;
                [CDATA[&amp;lt;p&amp;gt;Lorem ipsum dolor...&amp;lt;/p&amp;gt;]]
              &amp;lt;/body&amp;gt;
              &amp;lt;image&amp;gt;123&amp;lt;/image&amp;gt;
            &amp;lt;/page&amp;gt;
            &amp;lt;page id=&amp;quot;&amp;quot;1123=&amp;quot;&amp;quot;&amp;quot;&amp;quot; key=&amp;quot;&amp;quot;242928f6-a1cf-4cd3-ac34-f3ddf3526b2e=&amp;quot;&amp;quot;&amp;quot;&amp;quot; parentID=&amp;quot;&amp;quot;1103=&amp;quot;&amp;quot;&amp;quot;&amp;quot; level=&amp;quot;&amp;quot;2=&amp;quot;&amp;quot;&amp;quot;&amp;quot; creatorID=&amp;quot;&amp;quot;0=&amp;quot;&amp;quot;&amp;quot;&amp;quot; sortOrder=&amp;quot;&amp;quot;1=&amp;quot;&amp;quot;&amp;quot;&amp;quot; createDate=&amp;quot;&amp;quot;2017-10-17T20:25:12=&amp;quot;&amp;quot;&amp;quot;&amp;quot; updateDate=&amp;quot;&amp;quot;2017-10-17T20:25:17=&amp;quot;&amp;quot;&amp;quot;&amp;quot; nodeName=&amp;quot;&amp;quot;Page=&amp;quot;&amp;quot; 2=&amp;quot;&amp;quot;&amp;quot;&amp;quot; urlName=&amp;quot;&amp;quot;page2=&amp;quot;&amp;quot;&amp;quot;&amp;quot; path=&amp;quot;&amp;quot;-1,1103,1123=&amp;quot;&amp;quot;&amp;quot;&amp;quot; isDoc=&amp;quot;&amp;quot;&amp;quot;&amp;quot; nodeType=&amp;quot;&amp;quot;1095=&amp;quot;&amp;quot;&amp;quot;&amp;quot; creatorName=&amp;quot;&amp;quot;Admin=&amp;quot;&amp;quot;&amp;quot;&amp;quot; writerName=&amp;quot;&amp;quot;Admin=&amp;quot;&amp;quot;&amp;quot;&amp;quot; writerID=&amp;quot;&amp;quot;0=&amp;quot;&amp;quot;&amp;quot;&amp;quot; template=&amp;quot;&amp;quot;1060=&amp;quot;&amp;quot;&amp;quot;&amp;quot; nodeTypeAlias=&amp;quot;&amp;quot;page=&amp;quot;&amp;quot;&amp;quot;&amp;quot;&amp;gt;
              &amp;lt;title&amp;gt;More welcome!&amp;lt;/title&amp;gt;
              &amp;lt;excerpt&amp;gt;[CDATA[More lorem ipsum dolor...]]&amp;lt;/excerpt&amp;gt;
              &amp;lt;body&amp;gt;[CDATA[Even more lorem ipsum dolor...]]&amp;lt;/body&amp;gt;
              &amp;lt;image&amp;gt;234&amp;lt;/image&amp;gt;
            &amp;lt;/page&amp;gt;
          &amp;lt;/home&amp;gt;
        &amp;lt;/root&amp;gt;
    &amp;quot;.Trim();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In our tests, we can now query by anything. The returned content has the hierarchy and everything, so we can traverse it with &lt;code&gt;Children()&lt;/code&gt;, &lt;code&gt;Parent()&lt;/code&gt; and whatnot.
The only missing piece is the properties. Here's a test showing that we have everything but the title property of Page 1:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const int Page1Id = 1122;

[Test]
public void Returns_Empty_Documents()
{
    var contentCache = umbracoSupport.UmbracoContext.ContentCache;
    var page1 = contentCache.GetById(Page1Id);

    Assert.That(page1, Is
        .Not.Null
        .And
        .InstanceOf&amp;lt;PublishedContentWithKeyBase&amp;gt;()
        .And
        .Property(&amp;quot;Name&amp;quot;).EqualTo(&amp;quot;Page 1&amp;quot;)
        .And
        .Matches&amp;lt;IPublishedContent&amp;gt;(c =&amp;gt; c[&amp;quot;title&amp;quot;] == null)
        .And
        .Property(&amp;quot;Parent&amp;quot;)
            .Property(&amp;quot;Children&amp;quot;)
                .With.Count.EqualTo(2)
    );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Don't be discouraged though. This method is excellent for testing URL providers, ContentFinders, Menus, Sitemaps. You name it. I know I've written my fair share of hierarchy traversing code or fancy XPath queries. Unless of course, you need property values.&lt;/p&gt;
&lt;p&gt;Instead of pulling your leg about it, here's how we fix that.&lt;/p&gt;
&lt;h2&gt;Put some meat on the content&lt;/h2&gt;
&lt;p&gt;The reason the properties are not there isn't because they weren't read. It's because the &lt;code&gt;XmlPublishedContent&lt;/code&gt; that we get out ultimately relies on the &lt;code&gt;PublishedContentType&lt;/code&gt; for it's respective document type. Luckily, all Umbraco's services are already stubbed up for us, so we can give it what it needs.&lt;/p&gt;
&lt;p&gt;The gory guts of it is that it needs an &lt;code&gt;IContentType&lt;/code&gt; from the &lt;code&gt;ContentTypeService&lt;/code&gt;. We can easily stub one up with Moq: &lt;code&gt;var contentType = Mock.Of&amp;lt;IContentType&amp;gt;()&lt;/code&gt;. Further, it uses the &lt;code&gt;IContentType.CompositionPropertyTypes&lt;/code&gt; collection to iterate the properties. These &lt;code&gt;PropertyType&lt;/code&gt; instances are actually completely dependency-less, so we can just create some:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Mock.Get(contentType)
    .Setup(t =&amp;gt; t.CompositionPropertyTypes)
    .Returns(new[] {
        new PropertyType(&amp;quot;Umbraco.TinyMCEv3&amp;quot;, DataTypeDatabaseType.Nvarchar, &amp;quot;body&amp;quot;)
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, we set it up on the &lt;code&gt;ContentTypeService&lt;/code&gt; stub:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Mock.Get(umbracoSupport.ServiceContext.ContentTypeService)
    .Setup(s =&amp;gt; s.GetContentType(alias))
    .Returns(contentType);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If only it were so easy. We depend on the &lt;code&gt;BaseWebTest&lt;/code&gt; class from &lt;code&gt;Umbraco.Tests&lt;/code&gt;. It sets up a content type factory that's being used somewhere in the hierarchy. It feeds &lt;code&gt;AutoPublishedContent&lt;/code&gt; instances instead of what we've stubbed up. We need to turn that off. There's a trick here. &lt;code&gt;UmbracoSupport&lt;/code&gt; should now live in an assembly called &lt;code&gt;Umbraco.UnitTests.Adapter&lt;/code&gt;. If you're pre 7.6.4 you need to go with &lt;code&gt;Umbraco.VisualStudio&lt;/code&gt;. This is because the factory we need to reset is internal to Umbraco. By having &lt;code&gt;UmbracoSupport&lt;/code&gt; in an assembly with one of these two names, we're able to do it. (Otherwise, you use reflection.) &lt;em&gt;By no means do this with production code. Just... forget it!&lt;/em&gt;&lt;br /&gt;
This paragraph should also get it's own blog post. :)&lt;/p&gt;
&lt;p&gt;But I digress. Here's the line you need to have the content use the &lt;code&gt;ContentTypeService&lt;/code&gt; to fetch its type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PublishedContentType.GetPublishedContentTypeCallback = null;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It's tempting to leave setup code like this lying around in all our &lt;code&gt;SetUp&lt;/code&gt; methods or even in our &amp;quot;Arrange&amp;quot; sections. I've sinned too much, so those few lines are now part of &lt;code&gt;UmbracoSupport&lt;/code&gt; and can be used to set up multiple types for your fixture or test.&lt;/p&gt;
&lt;p&gt;Here's a test that fetches the same document as before, but can now read properties:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Test]
public void With_DocumentTypes_Setup_Returns_Full_Blown_Documents()
{
    umbracoSupport.SetupContentType(&amp;quot;page&amp;quot;, new[]
    {
        new PropertyType(&amp;quot;textstring&amp;quot;, DataTypeDatabaseType.Nvarchar, &amp;quot;title&amp;quot;),
        new PropertyType(&amp;quot;textarea&amp;quot;, DataTypeDatabaseType.Nvarchar, &amp;quot;excerpt&amp;quot;),
        new PropertyType(&amp;quot;Umbraco.TinyMCEv3&amp;quot;, DataTypeDatabaseType.Nvarchar, &amp;quot;body&amp;quot;),
        new PropertyType(&amp;quot;media&amp;quot;, DataTypeDatabaseType.Integer, &amp;quot;image&amp;quot;)
    });

    var page1 = contentCache.GetById(Page1Id);

    Assert.Multiple(() =&amp;gt;
    {
        Assert.That(page1[&amp;quot;title&amp;quot;], Is.EqualTo(&amp;quot;Welcome!&amp;quot;));
        Assert.That(page1[&amp;quot;excerpt&amp;quot;], Is.EqualTo(&amp;quot;Lorem ipsum dolor...&amp;quot;));
        Assert.That(page1[&amp;quot;body&amp;quot;].ToString(), Is.EqualTo(&amp;quot;&amp;lt;p&amp;gt;Lorem ipsum dolor...&amp;lt;/p&amp;gt;&amp;quot;));
        Assert.That(page1[&amp;quot;image&amp;quot;], Is.EqualTo(123));
    });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Notice the .ToString() on the body. It's actually not a string, but some weird dynamic Umbraco thingy. I never saw that type before, but I didn't pursue it in time for this post. I don't want anything to do with it though, so let's storm on to the grand finale.&lt;/p&gt;
&lt;h2&gt;Let's make them strong already!&lt;/h2&gt;
&lt;p&gt;We're finally there. The last piece of the puzzle. Strongly typed content!&lt;/p&gt;
&lt;p&gt;It's managed by two resolvers: &lt;code&gt;PublishedContentModelFactoryResolver&lt;/code&gt; and &lt;code&gt;PropertyValueConvertersResolver&lt;/code&gt;. I won't go into details about those now, but suffice to say all resolvers have to be initialized before &lt;code&gt;BaseWebTest.Initialize&lt;/code&gt; and its ancestors.
I've added an &lt;code&gt;InitializeResolvers&lt;/code&gt; method to the &lt;code&gt;UmbracoSupport&lt;/code&gt; class where these two are initialized. The &lt;code&gt;PublishedContentModelFactoryResolver&lt;/code&gt; is set to a &lt;code&gt;FakeModelFactoryResolver&lt;/code&gt; that lets you register constructors for document type aliases. &lt;a href="https://github.com/lars-erik/umbraco-unit-testing-samples/blob/master/Umbraco.UnitTesting.Adapter/Support/FakeTypedModelFactory.cs"&gt;The code for this is available in my &amp;quot;Umbraco unit testing samples&amp;quot; repo on github&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;To set up property value converters, we also need to do that before registering the resolver. The resolver takes all the converters as constructor arguments. I've added a list of those types as a property on &lt;code&gt;UmbracoSupport&lt;/code&gt;, so we can add &lt;code&gt;IPropertyValueConverter&lt;/code&gt; implementing types before calling &lt;code&gt;UmbracoSupport.SetupUmbraco&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[SetUp]
public void Setup()
{
    umbracoSupport = new UmbracoSupport();

    // Converter types need to be added before setup
    umbracoSupport.ConverterTypes.Add(typeof(TinyMceValueConverter));

    umbracoSupport.SetupUmbraco();

    //...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To register the typed model, there's just one line you can do in your setup, or even in your tests. Here I've refactored out the setup for the content type from earlier, and I register a model type for the document type alias:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private void SetupContentType()
{
    umbracoSupport.SetupContentType(&amp;quot;page&amp;quot;, new[]
    {
        new PropertyType(&amp;quot;textstring&amp;quot;, DataTypeDatabaseType.Nvarchar, &amp;quot;title&amp;quot;),
        new PropertyType(&amp;quot;textarea&amp;quot;, DataTypeDatabaseType.Nvarchar, &amp;quot;excerpt&amp;quot;),
        new PropertyType(&amp;quot;Umbraco.TinyMCEv3&amp;quot;, DataTypeDatabaseType.Nvarchar, &amp;quot;body&amp;quot;),
        new PropertyType(&amp;quot;media&amp;quot;, DataTypeDatabaseType.Integer, &amp;quot;image&amp;quot;)
    });
}

[Test]
public void With_DocumentTypes_And_Models_Setup_Returns_Fully_Functional_Typed_Content()
{
    SetupContentType();

    // Register strongly typed models with the ModelFactory
    umbracoSupport.ModelFactory.Register(&amp;quot;page&amp;quot;, c =&amp;gt; new Page(c));

    var page1 = contentCache.GetById(Page1Id);

    Assert.That(page1, Is
        .InstanceOf&amp;lt;Page&amp;gt;()
        .And.Property(&amp;quot;Body&amp;quot;)
            .Matches&amp;lt;IHtmlString&amp;gt;(s =&amp;gt; 
                s.ToString() == &amp;quot;&amp;lt;p&amp;gt;Lorem ipsum dolor...&amp;lt;/p&amp;gt;&amp;quot;
            )
    );
}

public class Page : PublishedContentModel
{
    public Page(IPublishedContent content) : base((IPublishedContentWithKey)content)
    {
    }

    public string Title =&amp;gt; Content.GetPropertyValue&amp;lt;string&amp;gt;(&amp;quot;title&amp;quot;);
    public string Excerpt =&amp;gt; Content.GetPropertyValue&amp;lt;string&amp;gt;(&amp;quot;excerpt&amp;quot;);
    public IHtmlString Body =&amp;gt; Content.GetPropertyValue&amp;lt;IHtmlString&amp;gt;(&amp;quot;body&amp;quot;);
    public int Image =&amp;gt; Content.GetPropertyValue&amp;lt;int&amp;gt;(&amp;quot;image&amp;quot;);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There you go! There's nothing more to it. Well, there is...&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Page&lt;/code&gt; class here is bundled with the test. If we use a common interface both for our runtime model and our test model, we're safe. But we should really use the runtime models. This means you shouldn't use &lt;em&gt;runtime generated&lt;/em&gt; models. &lt;a href="https://github.com/zpqrtbnk/Zbu.ModelsBuilder/wiki/Install-And-Configure"&gt;Go through the instructions for ModelsBuilder&lt;/a&gt; to have your models compiled and accessible from the tests.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;And although the XML is pretty ugly, you can flush it out into files bundled with your tests. You can also exploit the umbraco.config file and just copy segments from there into your test source files. That way, you spend no time writing the stubs, and the content is cleanly separated from your tests.&lt;/p&gt;
&lt;p&gt;That's &lt;em&gt;really&lt;/em&gt; all there is to it! It is. Now go test a bit, or a byte, or a string, or even a &lt;a href="/archive/testing-views-with-razorgenerator/"&gt;view&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/lars-erik/umbraco-unit-testing-samples/tree/master/Umbraco.UnitTesting.Adapter/Support"&gt;The new version of UmbracoSupport including the fake model factory is available here.&lt;/a&gt;&lt;/p&gt;
</description>
      <pubDate>Tue, 17 Oct 2017 21:18:06 Z</pubDate>
      <a10:updated>2017-10-17T21:18:06Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1097</guid>
      <link>https://blog.aabech.no/archive/marrying-ditto-with-modelsbuilder/</link>
      <title>Marrying Ditto with ModelsBuilder</title>
      <description>&lt;p&gt;I was happy to be allowed to speak at this years Umbraco UK Festival.&lt;br /&gt;
The topic was based on my &lt;a href="//blog.aabech.no/archive/comparing-modelsbuilder-and-ditto/"&gt;previous post where I compare Ditto and ModelsBuilder&lt;/a&gt;. 
While preparing for that talk, I couldn't help but notice that the tools and techniques 
aren't mutually exclusive at all. On the contrary, they can compliment each other in a really nice way.&lt;br /&gt;
&lt;em&gt;&lt;a href="#further-info"&gt;Slides and video from presentation linked further down&lt;/a&gt;.&lt;/em&gt;  
&lt;/p&gt;
&lt;p&gt;I won't dive into too many details in this article, I recommend you &lt;a href="//blog.aabech.no/archive/comparing-modelsbuilder-and-ditto/"&gt;read the previous article&lt;/a&gt;,
and take a swim through the code at &lt;a href="https://github.com/lars-erik/DittoDemoModelsBuilderified"&gt;the github repository&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Cleaning up the processors&lt;/h3&gt;
&lt;p&gt;In the Dittoified TXT site Matt Brailsford made, we saw a bunch of processors querying the hierarchy.
In my Modelsbuilderified version, we do nice and clean domain oriented queries.&lt;/p&gt;
&lt;p&gt;Take for instance the top navigation on the site, where we look up all the visible children of the home page.
The Ditto processor looks as such:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class MainNavAttribute : DittoProcessorAttribute
{
    public override object ProcessValue()
    {
        var content = Value as IPublishedContent;
        if (content == null) return Enumerable.Empty&amp;lt;NavLink&amp;gt;();

        var homePage = content.AncestorsOrSelf(1).First();
        return new[] { homePage }.Union(homePage.Children.Where(x =&amp;gt; x.IsVisible()));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With ModelsBuilder, we point to the homepage from the base document type,
and implemented the navigation items query on the homepage:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public partial class UmbHomePage
{
    IEnumerable&amp;lt;INavigationContent&amp;gt; INavigation.MenuItems
    {
        get
        {
            return new[] { this }
                .Union(
                    Children
                    .OfType&amp;lt;INavigationContent&amp;gt;()
                    .Where(c =&amp;gt; c.IsVisible)
                );
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What we keep forgetting though, is that the ModelsBuilder models are created before the content leaves the cache.
If we install Ditto in the ModelsBuilderified version, or vice versa, we can actually use that MB query in the processor.
Whether we'd like to keep the query and interface segregation on our ModelsBuilder classes, 
or we'd like to put most logic in the Ditto processors is still a matter of taste.&lt;/p&gt;
&lt;p&gt;However, by just letting MB generate its models in the Dittoified project, not writing one single interface, 
we can refactor the &lt;code&gt;MainNavAttribute&lt;/code&gt; as such:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class MainNavAttribute : DittoProcessorAttribute
{
    public override object ProcessValue()
    {
        var content = Value as IPublishedContent;
        if (content == null) return Enumerable.Empty&amp;lt;NavLink&amp;gt;();

        var homePage = content.AncestorOrSelf&amp;lt;UmbHomePage&amp;gt;();
        return new[] { homePage }.Union(homePage.Children.Where(x =&amp;gt; x.IsVisible()));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The same can be done to the &lt;code&gt;BaseNewsProcessorAttribute&lt;/code&gt; with even more &amp;quot;domain language&amp;quot;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public abstract class BaseNewsAttribute : DittoProcessorAttribute
{
    protected IEnumerable&amp;lt;UmbNewsItem&amp;gt; GetNews()
    {
        var content = Value as UmbMaster;
        if (content == null) return Enumerable.Empty&amp;lt;UmbNewsItem&amp;gt;();

        var newsArchive = content.Home.FirstChild&amp;lt;UmbNewsOverview&amp;gt;();
        if (newsArchive == null) return Enumerable.Empty&amp;lt;UmbNewsItem&amp;gt;();

        return newsArchive.Children&amp;lt;UmbNewsItem&amp;gt;()
            .OrderByDescending(x =&amp;gt; x.DisplayDate);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You'll notice I've added the &lt;code&gt;DisplayDate&lt;/code&gt; implementation to &lt;code&gt;UmbNewsItem&lt;/code&gt; so we don't need to
think about the &lt;code&gt;PublishDate&lt;/code&gt; and &lt;code&gt;CreateDate&lt;/code&gt; properties every time we do ordering.&lt;/p&gt;
&lt;h3&gt;Where to start&lt;/h3&gt;
&lt;p&gt;I'd recommend that if you don't use either tool today, you should really just start using ModelsBuilder.
It will improve your code immensly over using magic strings, level-based queries and all that comes
with the basic IPublishedContent implementation. When you start to see that you want more
separation of concerns and interfaces don't do that for you, look into adding Ditto on top.&lt;/p&gt;
&lt;h3&gt;Serialization&lt;/h3&gt;
&lt;p&gt;The main pain point of using ModelsBuilder today is that &lt;code&gt;IPublishedContent&lt;/code&gt; implementations
lend themselves badly to serialization. Serializing it without care will lead to cyclic references
and/or super big graphs of parents and children.&lt;/p&gt;
&lt;p&gt;By mapping the content to POCOs with Ditto, you don't have to care about this.&lt;/p&gt;
&lt;h3&gt;Strike a balance&lt;/h3&gt;
&lt;p&gt;In my opinion, one can go way too far with the processors in Ditto.
Separation of concerns is good, but not at the cost of having to wade through 10-20 classes for
one coherent piece of functionality.&lt;/p&gt;
&lt;p&gt;The same can be said about ModelsBuilder. Creating too many compositions, adding to many interfaces,
creating too many extensions can be just as overwhelming.&lt;/p&gt;
&lt;p&gt;It basically boils down to the &lt;a href="https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it"&gt;good old YAGNI principle&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Further exploration&lt;/h3&gt;
&lt;p&gt;&lt;a id="further-info"&gt;&lt;/a&gt;
The examples in this article is &lt;a href="https://github.com/lars-erik/DittoDemoModelsBuilderified/tree/can-i-haz-both"&gt;avaiable in a branch on GitHub&lt;/a&gt;.&lt;br /&gt;
I also did a presentation comparing the two tools, and marrying them at last at this years Umbraco UK Festival.&lt;br /&gt;
&lt;a href="https://www.youtube.com/watch?v=dNZG4DOk6Vk"&gt;The presentation can be seen on YouTube&lt;/a&gt;.&lt;br /&gt;
&lt;a href="https://1drv.ms/p/s!AnYHs3nuLdwBjo1k2EJOTJ4IYrOwLA"&gt;The slides from the presentation are available here&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Sat, 05 Nov 2016 17:00:29 Z</pubDate>
      <a10:updated>2016-11-05T17:00:29Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1096</guid>
      <link>https://blog.aabech.no/archive/comparing-modelsbuilder-and-ditto/</link>
      <title>Comparing ModelsBuilder and Ditto</title>
      <description>&lt;p&gt;If you've been reading &lt;a href="http://blog.aabech.no/archive/getting-real-business-value-from-strongly-typed-models-in-umbraco/"&gt;my articles about typed models in Umbraco&lt;/a&gt;, you'll know I'm fairly biased towards ModelsBuilder. However, I never actually tried &lt;a href="https://our.umbraco.org/projects/developer-tools/ditto/"&gt;Ditto&lt;/a&gt;. I'll admit I didn't know exactly what I was telling you not to do in &amp;quot;&lt;a href="http://skrift.io/articles/archive/stop-mapping-start-adapting/"&gt;stop mapping, start adapting&lt;/a&gt;&amp;quot;. But I decided it was time to get dirty and do a comparison between the two. I'm still biased, but I'll do my best to stay objective.&lt;/p&gt;
&lt;p&gt;This comparison is based on &lt;a href="https://our.umbraco.org/member/5518"&gt;Matt Brailsford&lt;/a&gt;'s Ditto demo. He's &amp;quot;Dittoified&amp;quot; the TXT starter kit in Umbraco, and I've tried my best to &amp;quot;ModelsBuilderify&amp;quot; the same.&lt;/p&gt;
&lt;p&gt;There's only so much I could do in between my other projects, so it's fairly naïve. It misses some of the strong parts of what you can do with each approach in Umbraco. However, I hope I've been able to outline the main differences and their respective pros and cons.&lt;/p&gt;
&lt;p&gt;All of the code for this post is &lt;a href="https://github.com/lars-erik/DittoDemoModelsBuilderified"&gt;available on github&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;The project setup&lt;/h2&gt;
&lt;p&gt;The demo is built as a &amp;quot;website&amp;quot; in Visual Studio. This means we don't build, the binary files are included in source control, code lives in &lt;code&gt;App_Code&lt;/code&gt; and whatnot. I'm not comfortable with that setup, but I'll live with it for the purpose of this post.&lt;/p&gt;
&lt;h2&gt;Handwritten code or not&lt;/h2&gt;
&lt;p&gt;I could argue that you'd hand write everything for Ditto and get everything for free with ModelsBuilder. It has a big fallacy though. To get the most out of ModelsBuilder, you'll write a lot of property value types, converters and not least interfaces. However, you'll get a slight increase in efficiency by using the &amp;quot;extract interface&amp;quot; refactoring of any refactoring tool for the latter. Property value types and converters goes for Ditto too. There's no big win or loss here.&lt;/p&gt;
&lt;h2&gt;Getting started&lt;/h2&gt;
&lt;p&gt;ModelsBuilder is bundled with Umbraco. Ditto can be installed from nuget. Both tools depend on &lt;a href="https://our.umbraco.org/documentation/extending/property-editors/value-converters"&gt;property value converters&lt;/a&gt; in Umbraco. Which means they both also basically rely on &lt;a href="https://our.umbraco.org/projects/developer-tools/umbraco-core-property-value-converters"&gt;Jeavon Leopold's Umbraco Core Property Value Converters&lt;/a&gt;, which is also about to be bundled, but can be installed from nuget for now. &lt;/p&gt;
&lt;p&gt;As far as I can gather, there's no configuration needed for Ditto.&lt;/p&gt;
&lt;p&gt;For ModelsBuilder, you'll have to enable it in web.config. It's a matter of flipping &lt;code&gt;false&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; in an app setting. But to make it truly useful, I set it to &lt;code&gt;AppData&lt;/code&gt; mode and point the models to a sensible location.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;add key=&amp;quot;Umbraco.ModelsBuilder.Enable&amp;quot; value=&amp;quot;true&amp;quot; /&amp;gt;
&amp;lt;add key=&amp;quot;Umbraco.ModelsBuilder.ModelsMode&amp;quot; value=&amp;quot;AppData&amp;quot; /&amp;gt;
&amp;lt;add key=&amp;quot;Umbraco.ModelsBuilder.ModelsDirectory&amp;quot; value=&amp;quot;~/App_Code/Models&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;If this wasn't a website project, I'd put the models in &lt;code&gt;~/Models&lt;/code&gt;. There's also options to put them in an entirely different assembly. I'd also set a better namespace for the models.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If you're getting content in a controller or such and wonder how you get it typed, don't worry. You just have to cast it. For some reason people fail to understand this. When ModelsBuilder is active, you can't not get typed models. The content is decorated (typed) before it leaves the content cache.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;Views&lt;/h2&gt;
&lt;p&gt;Both approaches uses generic view types instead of &lt;code&gt;UmbracoTemplatePage&lt;/code&gt; as the base class.
For Ditto you'll use &lt;code&gt;DittoView&amp;lt;TModel&amp;gt;&lt;/code&gt; or a class derived from it.
For ModelsBuilder, it's &lt;code&gt;UmbracoTemplatePage&amp;lt;TModel&amp;gt;&lt;/code&gt; or a derived class.
The top of your views now require:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@inherits OneOrTheOther&amp;lt;TypedModel&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;Model&lt;/code&gt; property of our views will then look like this for each tool:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
    &lt;tr&gt;&lt;th&gt;Ditto&lt;/th&gt;&lt;th&gt;ModelsBuilder&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
    &lt;tr&gt;&lt;td&gt;Culture (&lt;code&gt;CultureInfo&lt;/code&gt;)&lt;/td&gt;&lt;td&gt;Culture (&lt;code&gt;CultureInfo&lt;/code&gt;)&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;Content (&lt;code&gt;IPublishedContent&lt;/code&gt;)&lt;/td&gt;&lt;td&gt;Content (&lt;code&gt;TModel&lt;/code&gt;)&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;View (&lt;code&gt;TModel&lt;/code&gt;)&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;One important distinction is that the ModelsBuilder &lt;code&gt;TModel&lt;/code&gt; implements &lt;code&gt;IPublishedContent&lt;/code&gt;, while Ditto has the typed model in a separate POCO (plain old C# object). I guess it's a matter of taste whether you like one or the other.&lt;/p&gt;
&lt;p&gt;I compared them using &lt;code&gt;UmbracoTemplatePage&amp;lt;TModel&amp;gt;&lt;/code&gt; here for similarity's sake. However, with ModelsBuilder you can actually make it simpler by inheriting &lt;code&gt;UmbracoViewPage&amp;lt;TModel&amp;gt;&lt;/code&gt;. This will make the model the actual &lt;code&gt;TModel&lt;/code&gt; instead of a &lt;code&gt;RenderModel&amp;lt;TModel&amp;gt;&lt;/code&gt;. For the rest of the comparison, that's what I'll do. (I don't really care about the &lt;code&gt;Culture&lt;/code&gt; since it's already in &lt;code&gt;this.Culture&lt;/code&gt;. No need to add it to a model and get an extra train cart when referencing properties.)&lt;/p&gt;
&lt;p&gt;There's one obvious quirk with anything that goes into an &lt;code&gt;UmbracoViewPage&lt;/code&gt;: It has to be &lt;code&gt;IPublishedContent&lt;/code&gt;. By creating another Razor base class, that can easily be avoided.&lt;/p&gt;
&lt;p&gt;The one less train cart is a slight win in my opinion.&lt;/p&gt;
&lt;p&gt;You'll either go &lt;code&gt;Model.View.Property&lt;/code&gt; or &lt;code&gt;Model.Property&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;UmbTextPage&lt;/h2&gt;
&lt;p&gt;Let's dive in and look at how the different document types in TXT looks with both. UmbTextPage is the bread and butter of the site. We'll look at the Master view and UmbHome type a bit later since there's more complex things going on there.&lt;/p&gt;
&lt;p&gt;Ditto uses the slim hand-written model &lt;code&gt;TextPageViewModel&lt;/code&gt;. ModelsBuilder uses the more verbose generated &lt;code&gt;UmbTextPage&lt;/code&gt;. They look like this:&lt;/p&gt;
&lt;h3&gt;Ditto&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;public class TextPageViewModel
{
    [Title]
    public string Title { get; set; }
    public string Image { get; set; }
    public HtmlString BodyText { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;ModelsBuilder&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;//------------------------------------------------------------------------------
// &amp;lt;auto-generated&amp;gt;
//   This code was generated by a tool.
//
//    Umbraco.ModelsBuilder v3.0.4.0
//
//   Changes to this file will be lost if the code is regenerated.
// &amp;lt;/auto-generated&amp;gt;
//------------------------------------------------------------------------------
[PublishedContentModel(&amp;quot;umbTextPage&amp;quot;)]
public partial class UmbTextPage : UmbMaster
{
    // omitted ctors

    ///&amp;lt;summary&amp;gt;
    /// Content
    ///&amp;lt;/summary&amp;gt;
    [ImplementPropertyType(&amp;quot;bodyText&amp;quot;)]
    public IHtmlString BodyText
    {
        get { return this.GetPropertyValue&amp;lt;IHtmlString&amp;gt;(&amp;quot;bodyText&amp;quot;); }
    }

    ///&amp;lt;summary&amp;gt;
    /// Featured Page?: Is this a page that should be featured on the home page?
    ///&amp;lt;/summary&amp;gt;
    [ImplementPropertyType(&amp;quot;featuredPage&amp;quot;)]
    public bool FeaturedPage
    {
        get { return this.GetPropertyValue&amp;lt;bool&amp;gt;(&amp;quot;featuredPage&amp;quot;); }
    }

    ///&amp;lt;summary&amp;gt;
    /// Image
    ///&amp;lt;/summary&amp;gt;
    [ImplementPropertyType(&amp;quot;image&amp;quot;)]
    public object Image
    {
        get { return this.GetPropertyValue(&amp;quot;image&amp;quot;); }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;On first glance, the ModelsBuilder class has a lot of stuff in it compared to the Ditto class. Remember that the ModelsBuilder one is autogenerated. You'll never poke around within that file. Notice that it's partial, so you can add to it in your own clean file. One other nice feature in it is that it adds the description of each property as an XmlDoc comment. You'll get the description of each property as IntelliSense when you go &lt;code&gt;Model.[ctrl+space]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You probably noticed that they differ in which properties they contain. The Ditto model leaves the &lt;code&gt;FeaturedPage&lt;/code&gt; property out, and the ModelsBuilder one leaves out the &lt;code&gt;Title&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The Ditto model is meant to be a clean view model for the UmbTextPage template, where &lt;code&gt;FeaturePage&lt;/code&gt; is completely irrelevant. So you've only got what you need to display the details of a text page in that model. &lt;/p&gt;
&lt;p&gt;The ModelsBuilder model is an exact typed replica of the document type. It inherits &lt;code&gt;UmbMaster&lt;/code&gt;, so naturally it also inherits the &lt;code&gt;Title&lt;/code&gt; property from it. We can get a clean model based on this class too, but we'll get to that later.&lt;/p&gt;
&lt;p&gt;Now what about that &lt;code&gt;[Title]&lt;/code&gt; attribute on the &lt;code&gt;Title&lt;/code&gt; property in the Ditto model? Seems a bit verbose doesn't it? It actually has a really useful purpose, which we'll look at when we get to &lt;code&gt;UmbMaster&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;For now, let's do a quick comparison of the property references in the views. You'll notice I've called the ModelsBuilder Title &lt;code&gt;DisplayTitle&lt;/code&gt;. We'll get to that soon. There's also the issue of a missing value converter for the Upload property type. I'm lazy, so it's an &lt;code&gt;object&lt;/code&gt;, hence the extra clutter.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
    &lt;tr&gt;&lt;th&gt;Ditto&lt;/th&gt;&lt;th&gt;ModelsBuilder&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
    &lt;tr&gt;&lt;td&gt;Model.View.Title&lt;/td&gt;&lt;td&gt;Model.DisplayTitle&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;
if (!Model.View.Image.IsNullOrWhiteSpace())  
{  
    &amp;lt;img src="@Model.View.Image"&amp;gt;  
}  
&lt;/td&gt;&lt;td&gt;
if (!(Model.Image ?? "").ToString().IsNullOrWhiteSpace())  
{  
    &amp;lt;img src="@Model.Image"&amp;gt;  
}  
&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;@Model.View.BodyText&lt;/td&gt;&lt;td&gt;Model.BodyText&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Not much to complain about here. They both have their merits, although with a string for the Image property, I'd vote for one less train cart.&lt;/p&gt;
&lt;h2&gt;[Title] Title or DisplayTitle&lt;/h2&gt;
&lt;p&gt;Let's dive a bit deeper into the common parts of all pages. We'll start with the title. It's quirky with both due to the fact that we'd like it to fall back to the name of a document if title isn't filled out.&lt;/p&gt;
&lt;h3&gt;Ditto&lt;/h3&gt;
&lt;p&gt;Ditto uses something called &amp;quot;processors&amp;quot; which is hooked up using attributes. The attribute classes contains logic for how a value should be transformed when mapped to a POCO. The title attribute looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class TitleAttribute : DittoMultiProcessorAttribute
{
    public string TitleAttr { get; set; }

    public TitleAttribute()
        : base(Enumerable.Empty&amp;lt;DittoProcessorAttribute&amp;gt;())
    {
        base.Attributes.AddRange(new[] {
            new UmbracoPropertyAttribute(TitleAttr),
            new AltUmbracoPropertyAttribute(&amp;quot;Name&amp;quot;)
        });
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It re-uses two more attributes that specify which properties to use in order. I find this class a bit hard to get at first glance, but I'm sure I'd get it immediately if I used Ditto daily. A cool thing about it is that it's re-usable across POCOs and will always set the property to Title, or Name if Title is empty. It's also there in the demo to show how one can add a chain of fallbacks. The same functionality could have been added to the DTO with this slightly less contextful attribute instead:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[UmbracoProperty(&amp;quot;title&amp;quot;, &amp;quot;name&amp;quot;)]
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;ModelsBuilder&lt;/h3&gt;
&lt;p&gt;With ModelsBuilder I added a new property called &lt;code&gt;DisplayTitle&lt;/code&gt; to &lt;code&gt;UmbMaster&lt;/code&gt;, and thereby all document types inheriting it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public string DisplayTitle
{
    get { return Title.IfNullOrWhiteSpace(Name); }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Thus far, I dub the latter a clear winner in obviousness, but maybe not in naming. That can be solved, but in the interest of time and length of this post, I'll leave it for now. They're also equally re-usable as such.&lt;/p&gt;
&lt;h2&gt;The master: umbLayout&lt;/h2&gt;
&lt;p&gt;Now that we've seen a few differences, let's have a look at the bigger picture. We'll start at the top of umbLayout. Ditto of course has an individual view model, &lt;code&gt;LayoutViewModel&lt;/code&gt; for the layout. With ModelsBuilder, I've extracted an interface from &lt;code&gt;UmbMaster&lt;/code&gt; and called it &lt;code&gt;ISiteContent&lt;/code&gt;. There's another processor for Ditto's model, and there's some more stuff in the ModelsBuilder partial:&lt;/p&gt;
&lt;h3&gt;Ditto&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// LayoutViewModel.cs
[UmbracoProperties(Recursive = true)]
public class LayoutViewModel
{
    public string SiteName { get; set; }
    public string Byline { get; set; }
    public string Copyright { get; set; }
    [HomeLink]
    public Link HomeLink { get; set; }
}

// HomeLinkAttribute.cs
public class HomeLinkAttribute : DittoProcessorAttribute
{
    public override object ProcessValue()
    {
        var content = Value as IPublishedContent;
        if (content == null) return null;

        return content.AncestorOrSelf(1);
    }
}

// Link.cs
public class Link
{
    [UmbracoProperty(&amp;quot;Name&amp;quot;, Order = 0)]
    public string Title { get; set; }
    public string Url { get; set; }
    [UrlTarget]
    public string UrlTarget { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;ModelsBuilder&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// ISiteContent.cs
public interface ISiteContent : IPublishedContent
{
    UmbHomePage Home { get; }
    string DisplayTitle { get; }
}

// UmbMaster.cs
public partial class UmbMaster : ISiteContent, ...
{
    private UmbHomePage home = null;
    public UmbHomePage Home
    {
        get
        {
            if (home == null)
                home = this.AncestorOrSelf&amp;lt;UmbHomePage&amp;gt;();
            return home;
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;LayoutViewModel&lt;/code&gt; uses a built-in attribute in Ditto that says it should recurse up the tree for all the properties on the view model. It also has a hand-written processor that locates the Home node and maps it to a Link POCO. The Link POCO goes on and does some more processing and mapping. I'll not follow it further, but it's pretty magic and cool. Whenever whatever document is shown, Ditto can create a layout model for it based on its Home ancestor.&lt;/p&gt;
&lt;p&gt;With &lt;code&gt;UmbMaster&lt;/code&gt; I've cached up the Home ancestor whenever you access it. It'll be available as a train cart on all pages. &lt;code&gt;ISiteContent&lt;/code&gt; acts as a slimmer view model if you want, for all types. Hence it can be used in umbLayout. The difference from Ditto is that it also IS your actual content.&lt;/p&gt;
&lt;p&gt;Let's look at how they're used in the view.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
    &lt;tr&gt;&lt;th&gt;Use case&lt;/th&gt;&lt;th&gt;Ditto&lt;/th&gt;&lt;th&gt;ModelsBuilder&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
    &lt;tr&gt;&lt;td&gt;Title tag&lt;/td&gt;&lt;td&gt;Model.CurrentPage.Name | Model.View.SiteName&lt;/td&gt;&lt;td&gt;Model.DisplayTitle | Model.Home.SiteName&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;Home URL&lt;/td&gt;&lt;td&gt;Model.View.HomeLink.Url&lt;/td&gt;&lt;td&gt;Model.Home.Url&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;Logo&lt;/td&gt;&lt;td&gt;Model.View.SiteName&lt;/td&gt;&lt;td&gt;Model.Home.SiteName&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;Byline&lt;/td&gt;&lt;td&gt;Model.View.Byline&lt;/td&gt;&lt;td&gt;Model.Home.Byline&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;Copyright&lt;/td&gt;&lt;td&gt;Model.View.Copyright&lt;/td&gt;&lt;td&gt;Model.Home.Copyright&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;It's a pretty darn close race. I think Matt just forgot to add the [Title]Title to the view model, 'cause he's missing out on the fallback there. Might be I'm too eager and the original TXT just showed the name though. In any case, it's just a matter of one more or one less train cart again.&lt;/p&gt;
&lt;p&gt;I'm slightly biased towards the reference to Home. It makes it more obvious where the value comes from. We also just traverse the hierarchy once, instead of for all properties.&lt;/p&gt;
&lt;p&gt;But we're also starting to see a growth in code amount on the Ditto side. There's more processors, more POCOs and more logic to follow if we want to figure out what happens. That's a slight win for ModelsBuilder in my opinion. Weight should be given the magic coolness of Ditto's processors though.&lt;/p&gt;
&lt;h2&gt;The partials&lt;/h2&gt;
&lt;p&gt;There's a lot more going on in umbLayout. For starters, there's the navigation. You can probably guess by now that Ditto's got a &lt;code&gt;TopNavigationViewModel&lt;/code&gt;. On the ModelsBuilder side, we've got an &lt;code&gt;INavigation&lt;/code&gt; interface. I've added &lt;code&gt;INavigation&lt;/code&gt; to &lt;code&gt;UmbMaster&lt;/code&gt; so all documents implements navigation. We could've stuck it on home only, but there's something to demonstrate here. We'll see the other option next.&lt;/p&gt;
&lt;p&gt;Let's look at the implementations first:&lt;/p&gt;
&lt;h3&gt;Ditto&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// TopNavigationViewModel.cs
public class TopNavigationViewModel
{
    [MainNav]
    public IEnumerable&amp;lt;NavLink&amp;gt; MenuItems { get; set; }
}

// MainNavAttribute.cs
public class MainNavAttribute : DittoProcessorAttribute
{
    public override object ProcessValue()
    {
        var content = Value as IPublishedContent;
        if (content == null) return Enumerable.Empty&amp;lt;NavLink&amp;gt;();

        var homePage = content.AncestorsOrSelf(1).First();
        return new[] { homePage }
            .Union(
                homePage.Children
                .Where(x =&amp;gt; x.IsVisible())
            );
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;ModelsBuilder&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// INavigation.cs
public interface INavigation : IPublishedContent
{
    IEnumerable&amp;lt;ISiteContent&amp;gt; MenuItems { get; }
}

// UmbMaster.cs
public partial class UmbMaster : ISiteContent, INavigation
{
    // Home &amp;amp; DisplayTitle omitted...

    IEnumerable&amp;lt;ISiteContent&amp;gt; INavigation.MenuItems
    {
        get { return home.MenuItems; }
    }
}

// UmbHome.cs
public class UmbHome : INavigation, ...
{
    // Quite a lot omitted...

    public IEnumerable&amp;lt;ISiteContent&amp;gt; MenuItems
    {
        get
        {
            return new[] {this}
                .Union(
                    Children
                    .OfType&amp;lt;ISiteContent&amp;gt;()
                    .Where(c =&amp;gt; c.IsVisible())
                );
        }
    } 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see, Ditto keeps processing and separating concerns. That's a really good feature with Ditto - it really makes you adhere to the &lt;a href="https://en.wikipedia.org/wiki/Single_responsibility_principle"&gt;Single Responsibility Principle&lt;/a&gt;. I like that as much as I like the &lt;a href="https://en.wikipedia.org/wiki/Interface_segregation_principle"&gt;Interface Segregation Principle&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;On the ModelsBuilder side, I've done a little dispatch from &lt;code&gt;UmbMaster&lt;/code&gt; to &lt;code&gt;UmbHome&lt;/code&gt;. Since &lt;code&gt;UmbHome&lt;/code&gt; derives from &lt;code&gt;UmbMaster&lt;/code&gt;, it'll go through both properties, but end up the same. All others will get the menu items from Home.&lt;/p&gt;
&lt;p&gt;The views are completely equal, except for the extra train cart with Ditto.&lt;/p&gt;
&lt;p&gt;Further, we've got the featured and about parts near the bottom of the page. I've only added those to &lt;code&gt;UmbHome&lt;/code&gt; with ModelsBuilder. This means that we can't just call the partials from layout any more. We need to pass in &lt;code&gt;Model.Home&lt;/code&gt;. That's more or less the only difference. The implementation follows the same patterns as before. There's individual POCOs with Ditto, and segregated interfaces with ModelsBuilder. No big wins or losses there. I'll skip the code, &lt;a href="https://github.com/lars-erik/DittoDemoModelsBuilderified"&gt;you can see it on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One thing to notice if you didn't already, is that when we create segregated interfaces as view models with other property names, we implement them explicitly. By doing that, we avoid cluttering up the main model with more properties. We can also use the same name for different actual properties. Here's the &lt;code&gt;IAbout&lt;/code&gt; implementation on &lt;code&gt;UmbHomePage&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;string IAbout.Title { get { return AboutTitle; } }
IHtmlString IAbout.Text { get { return AboutText; } }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;See how it can be named &lt;code&gt;Title&lt;/code&gt; without messing with the actual &lt;code&gt;Title&lt;/code&gt; from &lt;code&gt;UmbMaster&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;It's passed from layout to the view like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Html.RenderPartial(&amp;quot;umbAbout&amp;quot;, Model.Home);
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Functionality and behavior&lt;/h2&gt;
&lt;p&gt;There's a lot of cool things you can do with Ditto processors. Matt's added paging to the news overview. I didn't get around to implement any paging for the news using a ModelsBuilder approach. That's mainly because there aren't any ModelsBuilder approach for it. I'd implement it using a controller for the paging and possibly a html helper for the pager. I might even be so lazy that I'd do it in the view. With Ditto it's done with an attribute, and it's also cached using another attribute. Thing is, it amounts to some 50 lines plus to make it nicely separated and modelified. I'm willing to bet it could be done with a lot less code using traditional techniques. We can argue for a while which method has the best separation of concerns.&lt;/p&gt;
&lt;p&gt;As far as I could find, there's only the paging that is extra functionality in the Dittoified version.&lt;/p&gt;
&lt;h2&gt;What about Nested Content?&lt;/h2&gt;
&lt;p&gt;Of course Nested Content works OOTB with Ditto. Everything does. With ModelsBuilder, you'd have to decorate the IPublishedContent yourself since the current property value converters doesn't. I can't imagine that's far off into the future though. If we had a nested content type of some type implementing banners, we could go as such with ModelsBuilder:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var banners = Model.Banners.Select(b =&amp;gt; new Banner(b));
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Where &lt;code&gt;Banner&lt;/code&gt; is generated due to the doctype. A converter could go through the factory like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PublishedContentModelFactoryResolver.Current.Factory.CreateModel(content);
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Architecture and re-use&lt;/h2&gt;
&lt;p&gt;Both the POCOs and the interfaces can be put in separate assemblies and re-used across solutions. The interfaces can be pretty dependencyless, while the Ditto POCOs will depend on Ditto. By changing the implementation from properties on the partials to extensions for the interfaces, you can also re-use most of the logic with the ModelsBuilder approach. This will make them adhere better to the &lt;a href="https://en.wikipedia.org/wiki/Single_responsibility_principle"&gt;single responsibility principle&lt;/a&gt;. All in all, there's no obvious big winner here either. It's up to the implementor to keep it clear and simple.&lt;/p&gt;
&lt;p&gt;Ditto isn't limited to Umbraco types. It can be used for anything that can be reflected. This means you can use it for your third-party e-commerce package for instance.&lt;/p&gt;
&lt;p&gt;Using well structured and SOLID object oriented programming you can achieve the same without depending on any tool.&lt;/p&gt;
&lt;h2&gt;Amount of code&lt;/h2&gt;
&lt;p&gt;Counting all classes in the Dittoified version, I get to 18 hand crafted view models. There's 14 processors and a news context of some sort. There's also 6 more classes including controllers and extensions. Totaling 38 different classes to know and build. I didn't count the lines, but there's several hundred.&lt;/p&gt;
&lt;p&gt;On the ModelsBuilder side, I got 5 classes generated for free. I extracted 7 interfaces and modified them a little bit. I wrote 4 partial implementations for the generated models. Mostly the same queries as in the 14 processors for Ditto. Totaling ~10 semi hand crafted classes of ~200 lines.&lt;/p&gt;
&lt;h2&gt;Conclusions&lt;/h2&gt;
&lt;p&gt;I've only identified a few small wins for ModelsBuilder, and I'm sure that's because I'm biased. Ultimately it boils down to preference. My biggest issues are dependencies, attributes, learning curve and amount of code. There's also a risk of scattering logic too much, making it difficult to find out what's going on. Putting everything in processors seems like an unnecessary shift away from traditional MVC and OOP. Still, Ditto radiates an intriguing magic aura, and I look forward to following its progress.&lt;/p&gt;
&lt;p&gt;I've only been able to scratch the surface of both tools and approaches without having to write an entire book. So I encourage you to &lt;a href="https://github.com/lars-erik/DittoDemoModelsBuilderified"&gt;compare the two projects yourself&lt;/a&gt; and see which fits your needs and style the best.&lt;/p&gt;
&lt;p&gt;I think I managed to be quite objective, so I'd like to finish off with a really subjective opinion. Using attributes which depend on a library clutters up your dependency chain. They might give meaning in context, and might live within a bounded context where it's alright to have the dependency. They may also help you stay DRY and separate concerns. ModelsBuilder also adds attributes to its classes, so there's that. Generally though, I try to steer away from them. Agree or not, all of the non-generated ModelsBuilder code is dependencyless and impossible not to get at first glance (OK, they depend on Umbraco.Core). Incidentally, my discontinued competitor to ModelsBuilder, &lt;a href="https://github.com/lars-erik/Umbraco.CodeGen"&gt;Umbraco CodeGen&lt;/a&gt;, generates 100% attribute- and dependencyless models (OK, they depend on Umbraco.Core). I'm regularly pestering &lt;a href="https://our.umbraco.org/member/6724"&gt;Stephane Gay&lt;/a&gt; about opening up the ModelsBuilder writer so I can swap out the generated classes with clean, dependencyless beauty. When that happens, you'll be in full control over your generated models.&lt;/p&gt;
&lt;p&gt;Happy modelling, and stay &lt;a href="https://en.wikipedia.org/wiki/Don't_repeat_yourself"&gt;DRY&lt;/a&gt;!&lt;/p&gt;
</description>
      <pubDate>Fri, 14 Oct 2016 22:13:52 Z</pubDate>
      <a10:updated>2016-10-14T22:13:52Z</a10:updated>
    </item>
  </channel>
</rss>