Lifetimes
editLifetimes
editIf you are using an IOC/Dependency Injection container, it’s always useful to know the best practices around the lifetime of your objects.
In general, we advise folks to register an ElasticClient
instance as a singleton; the client is thread safe,
so sharing an instance across threads is fine.
The actual moving part that benefits from being a singleton is ConnectionSettings
because
caches are per ConnectionSettings
.
In some applications ,it could make perfect sense to have multiple ElasticClient
instances registered with different
connection settings such as when your application connects to two different Elasticsearch clusters.
Due to the semantic versioning of Elasticsearch.Net and NEST and their alignment to versions of Elasticsearch, all instances of ElasticClient
and
Elasticsearch clusters that are connected to must be on the same major version
Let’s demonstrate which components are disposed by creating our own derived ConnectionSettings
, IConnectionPool
and IConnection
types
private class AConnectionSettings : ConnectionSettings { public AConnectionSettings(IConnectionPool pool, IConnection connection) : base(pool, connection) { } public bool IsDisposed { get; private set; } protected override void DisposeManagedResources() { this.IsDisposed = true; base.DisposeManagedResources(); } } private class AConnectionPool : SingleNodeConnectionPool { public AConnectionPool(Uri uri, IDateTimeProvider dateTimeProvider = null) : base(uri, dateTimeProvider) { } public bool IsDisposed { get; private set; } protected override void DisposeManagedResources() { this.IsDisposed = true; base.DisposeManagedResources(); } } private class AConnection : InMemoryConnection { public bool IsDisposed { get; private set; } protected override void DisposeManagedResources() { this.IsDisposed = true; base.DisposeManagedResources(); } }
ConnectionSettings
, IConnectionPool
and IConnection
all explicitly implement IDisposable
var connection = new AConnection(); var connectionPool = new AConnectionPool(new Uri("http://localhost:9200")); var settings = new AConnectionSettings(connectionPool, connection); settings.IsDisposed.Should().BeFalse(); connectionPool.IsDisposed.Should().BeFalse(); connection.IsDisposed.Should().BeFalse();
Disposing an instance of ConnectionSettings
will also dispose the IConnectionPool
and IConnection
it uses
var connection = new AConnection(); var connectionPool = new AConnectionPool(new Uri("http://localhost:9200")); var settings = new AConnectionSettings(connectionPool, connection); using (settings) { } settings.IsDisposed.Should().BeTrue(); connectionPool.IsDisposed.Should().BeTrue(); connection.IsDisposed.Should().BeTrue();