# Extending the Elasticsearch Service in Sitefinity

## Overview

> info **PREREQUISITES**: This feature is available as of Sitefinity CMS 15.4.8637.

The `ElasticsearchService` class has been refactored to provide greater extensibility. Client initialization has been moved into dedicated factory methods, and the Elasticsearch client instance is now exposed through a lazy-initialized protected property. These changes allow derived classes to customize client configuration or replace the client entirely without modifying the base implementation.

> important **IMPORTANT**: As of Sitefinity CMS 15.4.8641, the signature of the virtual `GetAggregation` method is changed. If you override this method, update your implementation to match the new signature. This version also requires Elasticsearch server version 9.5.3 and a reindex of your Elasticsearch search indexes. For more information, see [API changes in Sitefinity CMS](https://www.progress.com/documentation/sitefinity-cms/api-changes-in-sitefinity-cms).

## Summary of changes

### Lazy-initialized `ElasticClient` property

The Elasticsearch client is no longer instantiated directly in the constructor. Instead, a **protected property** named `ElasticClient` defers creation until the first time it is accessed. It calls the `CreateElasticClient()` method, which can be overridden in subclasses.

### Overridable client creation methods

The following extension points have been introduced to allow consumers to customize the Elasticsearch client construction pipeline:

| Method                                                                 | Accessibility       | Purpose                                                                                                                                                                                                                                                                                                                                                                                                                                |
| ---------------------------------------------------------------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CreateElasticClient()`                                                | `protected virtual` | Provides complete control over client instantiation. Override this method when you need to supply an entirely custom `ElasticsearchClient` instance — for example, when integrating a custom HTTP transport, injecting interceptors, or applying non-standard connection pooling strategies. The default implementation calls `GetElasticClientSettings()` and passes the resulting settings to the `ElasticsearchClient` constructor. |
| `ConfigureElasticClientSettings(ElasticsearchClientSettings settings)` | `protected virtual` | Offers a lightweight customization hook that is invoked during settings construction. Override this method to append additional configuration, such as custom HTTP headers, proxy settings, or request timeout adjustments, without replacing the entire client creation logic. This method is called by `GetElasticClientSettings()` after all default configuration has been applied.                                                |
| `GetElasticClientSettings()`                                           | `protected`         | Constructs and returns the default `ElasticsearchClientSettings` instance with the service URI, authentication credentials, required mappings, and direct streaming enabled. This method guarantees a consistent baseline configuration. It calls `ConfigureElasticClientSettings` before returning, allowing derived classes to augment the settings.                                                                                 |

## Usage example

### Adding custom headers via `ConfigureElasticClientSettings`

When you need only minor adjustments to the client settings, override `ConfigureElasticClientSettings`. This keeps the base settings (including the endpoint URI, authentication, and default mappings) intact:

```C#
public class CustomElasticsearchService : ElasticsearchService
{

    protected override void ConfigureElasticClientSettings(ElasticsearchClientSettings settings)
    {
        // Add custom headers
        settings.GlobalHeaders(new NameValueCollection
        {
            { "X-Custom-Header", "my-value" }
        });
    }
}
```
