diff --git a/Momento/Momento.cs b/Momento/Momento.cs index 6fbc98da..7a65f904 100644 --- a/Momento/Momento.cs +++ b/Momento/Momento.cs @@ -10,11 +10,13 @@ namespace MomentoSdk { - public class Momento + public class Momento : IDisposable { private readonly string cacheEndpoint; private readonly string authToken; private readonly ScsControlClient client; + private readonly GrpcChannel channel; + private bool disposedValue; /// /// @@ -23,9 +25,9 @@ public class Momento public Momento(string authToken) { Claims claims = JwtUtils.decodeJwt(authToken); - GrpcChannel channel = GrpcChannel.ForAddress("https://" + claims.controlEndpoint + ":443", new GrpcChannelOptions() { Credentials = ChannelCredentials.SecureSsl }); + this.channel = GrpcChannel.ForAddress("https://" + claims.controlEndpoint + ":443", new GrpcChannelOptions() { Credentials = ChannelCredentials.SecureSsl }); Header[] headers = { new Header(name: "Authorization", value: authToken) }; - CallInvoker invoker = channel.Intercept(new HeaderInterceptor(headers)); + CallInvoker invoker = this.channel.Intercept(new HeaderInterceptor(headers)); this.client = new ScsControlClient(invoker); this.authToken = authToken; this.cacheEndpoint = "https://" + claims.cacheEndpoint + ":443"; @@ -117,5 +119,26 @@ private Boolean CheckValidCacheName(String cacheName) return true; } + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + this.channel.Dispose(); + } + + // TODO: free unmanaged resources (unmanaged objects) and override finalizer + // TODO: set large fields to null + disposedValue = true; + } + } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } } } diff --git a/Momento/MomentoCache.cs b/Momento/MomentoCache.cs index 54bd2357..c58be428 100644 --- a/Momento/MomentoCache.cs +++ b/Momento/MomentoCache.cs @@ -11,15 +11,18 @@ namespace MomentoSdk { - public class MomentoCache + public class MomentoCache : IDisposable { private readonly ScsClient client; private readonly uint defaultTtlSeconds; + private readonly GrpcChannel channel; + private bool disposedValue; + protected MomentoCache(string authToken, string cacheName, string endpoint, uint defaultTtlSeconds) { - GrpcChannel channel = GrpcChannel.ForAddress(endpoint, new GrpcChannelOptions() { Credentials = ChannelCredentials.SecureSsl }); + this.channel = GrpcChannel.ForAddress(endpoint, new GrpcChannelOptions() { Credentials = ChannelCredentials.SecureSsl }); Header[] headers = { new Header(name: "Authorization", value: authToken), new Header(name: "cache", value: cacheName) }; - CallInvoker invoker = channel.Intercept(new HeaderInterceptor(headers)); + CallInvoker invoker = this.channel.Intercept(new HeaderInterceptor(headers)); this.client = new ScsClient(invoker); this.defaultTtlSeconds = defaultTtlSeconds; } @@ -271,5 +274,27 @@ private long GetUnixTime() DateTime now = DateTime.Now; return ((DateTimeOffset)now).ToUnixTimeSeconds(); } + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + this.channel.Dispose(); + } + + // TODO: free unmanaged resources (unmanaged objects) and override finalizer + // TODO: set large fields to null + disposedValue = true; + } + } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } } }