AdvantageCMS.Core.Common.BaseClasses Namespace
Build With Advantage

SearchIndexer Class

Important note Important

This is a custom plug-in DLL for advanced search indexing requirements.

Ensure the following assemblies are referenced in the main solution:

  • AdvantageCMS.Core.dll
  • AdvantageCMS.Data.dll
  • AdvantageCMS.Keyoti.dll
  • Keyoti4.SearchEngine.Core.dll
  • Keyoti4.SearchEngine.Web.dll

Namespace:  AdvantageCSP.Keyoti.SiteIndexer
Assembly:  AdvantageCSP.Keyoti.SiteIndexer (in AdvantageCSP.Keyoti.SiteIndexer.dll)

Syntax


public class SearchIndexer : SearchIndexPluginBase, 
	IDisposable

Remarks


This is the indexer the platform ships with and the worked example to read before writing a custom one. It satisfies the plug-in contract in four places: a public three-argument constructor chained to the base, plus the three abstract members BuildIndex()()()(), Dispatcher_NeedObject(Object, NeedObjectEventArgs) and Dispatcher_Action(Object, ActionEventArgs).

The host is AdvantageCSP.Keyoti.KeyotiSearchBuilder, driven by the out-of-process AdvantageCSP.BuildIndex console — a plug-in never runs inside the website. For each search domain not switched off by EnableIndexing()()()(), the host loads the assembly named by SearchIndexDll()()()() from the folder holding the executable, activates every exported type assignable to SearchIndexPluginBase with the arguments (configuration, searchDomain, "AdvantageLanguageId"), calls BuildIndex()()()() exactly once, and then disposes the instance. Because the host does not stop after the first match, keep exactly one public plug-in class per assembly — two public classes means two full crawls of the same domain. Helper and intermediate classes must be internal; a public abstract intermediate base throws out of Activator.CreateInstance and aborts the whole domain.

The crawl state this class reads and mutates — ProcessedLinks, NotFoundLinks, ErrorLinks, LinkDocumentMapList, PreviousScrapeResults, PageInformation and AIInfo — all lives on SearchIndexPluginBase and none of it is thread safe. PageInformation and AIInfo are a single "current page" slot replaced on ResponseFromServerReceived()()()(), so every handler below assumes one page's events arrive in order and are never interleaved with another page's. Do not add crawler threads and do not start asynchronous work inside a handler.

One deviation not to copy: Dispose()()()() is declared new rather than overriding Dispose(bool), so the host never reaches it. See the remarks on that member for the shape a custom indexer should use instead.

Examples


The skeleton a custom indexer starts from — one public class, the three-argument constructor, and the three abstract members:
C#
public class AcmeSearchIndexer : SearchIndexPluginBase
{
    private ExtendedParserProvider _parserProvider;

    public AcmeSearchIndexer(Configuration configuration, AdvantageSearchDomain searchDomain, string cookieLanguage)
        : base(configuration, searchDomain, cookieLanguage)
    {
        _parserProvider = new ExtendedParserProvider(configuration, SearchDomain);
    }

    public override SearchIndexPluginIndexResult BuildIndex() { /* drive the crawl */ }

    public override void Dispatcher_NeedObject(object sender, NeedObjectEventArgs e)
    {
        if (e.RequiredObject is ParserProvider)
            e.RequiredObject = _parserProvider;
    }

    public override void Dispatcher_Action(object sender, ActionEventArgs e) { /* crawl lifecycle */ }

    protected override void Dispose(bool disposing)
    {
        if (disposing && _parserProvider != null) _parserProvider.Dispose();
        base.Dispose(disposing);
    }
}

Inheritance Hierarchy


Object
  SearchIndexPluginBase
    AdvantageCSP.Keyoti.SiteIndexer..::..SearchIndexer