4

I am creating a custom computed content search field that has one dependency: ISearchSettings. I'd like it to be injected via constructor:

public class CustomField : AbstractComputedIndexField
{
    private readonly ISearchSettings _searchSettings;

    public CustomField(ISearchSettings searchSettings)
    {
        this._searchSettings = searchSettings;
    }

    public override object ComputeFieldValue(IIndexable indexable)
    {
        /* ... */
    }
}

How can I achieve this with Sitecore 8.1?

5
  • I think if you want them to be inserted in the constructor (i.e. like in controller), you have to override the factory or index class. The easiest way is to use the standard Asp MVC dependency resolver + parameter-less constructor. p.s. Make sure that you investigate the computed field lifetime because I doubt it is being re-created each time it computes the value for indexing. – Andrey Bobrov Nov 3 '16 at 8:05
  • @adb Using the dependency resolver would defeat the purpose of using DI, which is the fact that my modules and components are not aware where the dependencies are coming from. Could you please clarify what you mean when you say I have to override the factory of index class? – Dmytro Shevchenko Nov 3 '16 at 8:11
  • It is quite easy to find where the field is injected. So, when you add your computed index field there is a node with method in it: <fields hint="raw:AddComputedIndexField">. The AddComputedIndexField leads us to the IDocumentBuilderOptions.AddComputedIndexField(XmlNode configNode). Here you can see that field is created from the type attribute using reflection. This is a place to put your custom constructor behavior with DI. – Andrey Bobrov Nov 3 '16 at 8:28
  • @adb That sounds interesting. Would you share this solution with more details as an answer? – Dmytro Shevchenko Nov 3 '16 at 8:32
  • I have added an answer – Andrey Bobrov Nov 3 '16 at 9:15
3

When you add a computed index field to the configuration, the section uses a certain method to instantiate resulting .Net objects for each computed field type:

<fields hint="raw:AddComputedIndexField">

As we can see here, the method is the AddComputedIndexField function from the IDocumentBuilderOptions interface.

Depending on your configuration you should either override the Solr or Lucene document builder.

All in all they work kinda same. You should override the:

public virtual void AddComputedIndexField(XmlNode configNode)

Inside the AddComputedIndexField method it is calling the protected static CreateComputedIndexfield method that actually creates a field instance. You should probably copy its body (use reflector or dotPeek) and add something like

Container.GetInstance(typeName) as IComputedIndexField

in the end instead of standard reflection code.

The document builder can be replaced in the index configuration as follows:

 <documentOptions type="TypeName, Assembly">

I haven't tested this approach, but it should work. Please, let me know if it worked for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.