Skip to content

How to register a custom IRedisDatabaseProvider to utilize Azure DefaultCredentials #566

Description

@advapiIT

Hello,
Due to Devops restriction I need to use redis with Azure DefaultAzure credentials... I've been able to run it using the following link

Now I've implemented a custom EasyCaching Redis

   public class AzureRedisDatabaseProvider : IRedisDatabaseProvider
   {
           /// <summary>
           /// The options.
           /// </summary>
           private readonly RedisDBOptions _options;

           /// <summary>
           /// The connection multiplexer.
           /// </summary>
           private Lazy<ConnectionMultiplexer> _connectionMultiplexer;

       public AzureRedisDatabaseProvider(string name, RedisOptions options)
       {
           _options = options.DBConfig;
           _connectionMultiplexer = new Lazy<ConnectionMultiplexer>(CreateConnectionMultiplexer);
           _name = name;
       }

       private readonly string _name;

           public string DBProviderName => this._name;

           /// <summary>
           /// Gets the database connection.
           /// </summary>
           public IDatabase GetDatabase()
           {
               try
               {

                   var database = _connectionMultiplexer.Value.GetDatabase();
                   if (!string.IsNullOrEmpty(_options.KeyPrefix))
                       database = database.WithKeyPrefix(_options.KeyPrefix);
                   return database;
               }
               catch (Exception)
               {
                   _connectionMultiplexer = new Lazy<ConnectionMultiplexer>(CreateConnectionMultiplexer);
                   throw;
               }
           }

           /// <summary>
           /// Gets the server list.
           /// </summary>
           /// <returns>The server list.</returns>
           public IEnumerable<IServer> GetServerList()
           {
               var endpoints = GetMastersServersEndpoints();

               foreach (var endpoint in endpoints)
               {
                   yield return _connectionMultiplexer.Value.GetServer(endpoint);
               }
           }

           /// <summary>
           /// Creates the connection multiplexer.
           /// </summary>
           /// <returns>The connection multiplexer.</returns>
           private ConnectionMultiplexer CreateConnectionMultiplexer()
           {
               if (_options.ConfigurationOptions != null)
                   return ConnectionMultiplexer.Connect(_options.ConfigurationOptions);

               if (string.IsNullOrWhiteSpace(_options.Configuration))
               {
                   var configurationOptions = new ConfigurationOptions
                   {
                       ConnectTimeout = _options.ConnectionTimeout,
                       User = _options.Username,
                       Password = _options.Password,
                       Ssl = _options.IsSsl,
                       SslHost = _options.SslHost,
                       AllowAdmin = _options.AllowAdmin,
                       DefaultDatabase = _options.Database,
                       AbortOnConnectFail = _options.AbortOnConnectFail,
                   }.ConfigureForAzureWithTokenCredentialAsync(new DefaultAzureCredential()).GetAwaiter().GetResult() ;

                   foreach (var endpoint in _options.Endpoints)
                   {
                       configurationOptions.EndPoints.Add(endpoint.Host, endpoint.Port);
                   }

                   return ConnectionMultiplexer.Connect(configurationOptions);
               }
               else
               {
                   return ConnectionMultiplexer.Connect(_options.Configuration);
               }
           }

           /// <summary>
           /// Gets the masters servers endpoints.
           /// </summary>
           private List<EndPoint> GetMastersServersEndpoints()
           {
               var masters = new List<EndPoint>();
               foreach (var ep in _connectionMultiplexer.Value.GetEndPoints())
               {
                   var server = _connectionMultiplexer.Value.GetServer(ep);
                   if (server.IsConnected)
                   {
                       //Cluster
                       if (server.ServerType == ServerType.Cluster)
                       {
                           masters.AddRange(server.ClusterConfiguration.Nodes.Where(n => !n.IsReplica).Select(n => n.EndPoint));
                           break;
                       }
                       // Single , Master-Slave
                       if (server.ServerType == ServerType.Standalone && !server.IsReplica)
                       {
                           masters.Add(ep);
                           break;
                       }
                   }
               }
               return masters;
           }
       
   }

But I don't know how to register it in place of default one. I've tried to use services.AddSingleton<IRedisDatabaseProvider, AzureRedisDatabaseProvider>(); but It gives me an error

`System.InvalidOperationException: 'Unable to resolve service for type 'System.String' while attempting to activate 'TheTourGuy.Packages.CacheEviction.RegisterExtensions+AzureRedisDatabaseProvider'.'

This is due to the constructor, If I comment this I got

System.ArgumentException: 'No endpoints specified (Parameter 'config')'

But I'm 100% sure I'm registering wrong... any help?

`

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions