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