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
}
}