When creating new property type that stores content references then it’s recommended to implement PropertySoftLinkIndexer class. It will be used for indexing links to other content. For example when item type of PropertyList has ContentReference property then we should implement PropertySoftLinkIndexer returning all links from the list. In this article I will show how to implement generic PropertySoftLinkIndexer for PropertyList.
PropertySoftLinkIndexer deleting page

Let use modified Contact block example to build the list property. I changed the Contact class and now it has two properties Name and Link.

PropertySoftLinkIndexer PropertyList editor

When deleting content that is referenced by contact item we want to see warning message.

Basic implementation

When we defined one PropertyList type with only one ContentReference inside, then we can use simple indexer implementation prepared for this single class. We have to implement IPropertySoftLinkIndexer<IList<Contact>> interface and annotate class with ServiceConfiguration attrbiute.

In ResolveReferences method I’m iterating through all list items and indexing value of “Link” property.

Using reflection to get all references

When Contact class has more than one ContentReference property then we could try to find all links using reflection.

In GetContentReferences method I’m finding all ContentReferences using reflection and then pass the result to the ResolveReferences method responsible for indexing.

Using build-in ContentReference list indexer

In the private ResolveReferences method I’m indexing references based on ContentReferences list parameter. There is already an indexer for list of ContentReferences. We could try to use it.

In FindContentReferenceIndexer method I get all available instances of IPropertySoftLinkIndexer and search for the class with implemented IPropertySoftLinkIndexer<IList<ContentReference>> interface. ContentReference list indexer has ResolveReferences that takes list of ContentReferences as parameter and returns SoftLinks list.
I had to use ServiceLocator instead of dependency injection, because of bi-directional dependencies.

Making indexer generic

When we have many defiitions of PropertyList with different ContentReference properties inside then we could try to use generic implementation of ListPropertyIndexer. Instead of using IPropertySoftLinkIndexer<IList<Contact>>, the indexer will implement generic version of IPropertySoftLinkIndexer<IList<T>>. We won’t use ServiceConfiguration anymore, because the indexer will be registered in ConfigurableModule.

The ConfigurableModule filters out all PropertyList types and registers indexers.

Indexing PropertyList with other indexable properties

The item of the PropertyList can have other indexable properties like list of ContentReferences.

PropertySoftLinkIndexer ContentReference list property

We could have indexing logic for each of those properties inside indexer, but I prepared generic solution. Every content is indexed by ContentSoftLinkIndexer.
I defined FakeContent class used to wrap obect into Content. For each PropertyList item I’m creating FakeContent and then execute GetLinks method. In this example the indexer will return all links from ContentReference list.

The full source code can be found on Github.