Umbraco 8 and custom CollectionBuilders

By Markus Johansson
2020-03-10

A very nice feature in the latest version of Umbraco (8.0+) is that they’ve made it really easy to implement your own CollectionBuilders. This raises two obvious questions:

What is a CollectionBuilder?

A collection builder is used to create a collection of Types, the main purpose being a collection of types that you would like to keep in a certain order. Umbraco uses this to register stuff like ContentFinders, Components and lots of other things.
The syntax looks something like this:

// Append
composition.Components().Append<MyCustomComponent>()
// Insert After
composition.Components().InsertAfter<MyCustomComponent,AnotherComponent>()

By leverage this feature you can create your own collection of types and make sure that the concrete instances in the collection is sorted in the way you want.

How would I implement a custom CollectionBuilder?

We’re basically looking at 3 small pieces that we need to get this in place. Let’s say that we have a type called ITextProcessor with multiple different implementations that we need to store in our custom collection in a given order. We’ll start with the collection it self by creating a new class that inherits from BuilderCollectionBase, all we need to do is to pass the type we want to store in the collection as a type parameter and implement the default constructor: 

public class TextProcessorsCollection : BuilderCollectionBase<ITextProcessor>
{
    public TextProcessorsCollection (IEnumerable< ITextProcessor > items) : base(items)
    {
    }
}

 Next up is the “Collection Builder” it self, here we inherit from “OrderedCollectionBuilderBase” and pass 3 type parameters:
1. The builder type it self
2. The collection type
3. The type of the items in the collection


And also implement one single property, “This”. It should look something like:

public class TextProcessorsCollectionBuilder :
OrderedCollectionBuilderBase< TextProcessorsCollectionBuilder, TextProcessorsCollection,ITextProcessor>
{
    protected override TextProcessorsCollectionBuilder This => this;
}

 The last thing we should do is to implement an extension method so the builder will be easy to use during composition, let’s create one like this:

public static class TextProcessorsCollectionExtensions
{
    public static TextProcessorsCollectionBuilder TextProcessors(this Composition composition)
=> composition.WithCollectionBuilder< TextProcessorsCollectionBuilder >();
}

After this we can work with our list during Composition using the extension method like so:

public class MySiteComposer : IUserComposer
{
    public void Compose(Composition composition)
    {
    composition.TextProcessors().Append<RemoveSpaceTextProcessor>();
    composition.TextProcessors().Append<AddLineBreaksTextProcessor>();
    }
}

 When we want to use the list in our code, we can get it from the IOC-container, prefferebly using consrtructor injection

public class MyController : SurfaceController
{
    public void MyController(TextProcessorsCollection textProcessors)
    {
        // Save as local variable
    }
}





More blog posts



15 januari 2021

Umbraco and MiniProfiler