/// <summary>
        /// Default Cotr.
        /// </summary>
        /// <param name="config">Cache config</param>
        /// <param name="logger">Logger</param>
        /// <param name="connectionGenerator">Accepts ConnectionType (first argument) and
        /// ConnectionString (second argument) as input and returns an instance of DB connection (Must NOT be Opened).
        /// <para>Both ConnectionType and ConnectionString are exactly what mentioned in DbProfile Config.</para></param>
        public AsyncCacheMgr(IAsyncCacheConfig config, ILog logger,
                             Func <string, string, DbConnection> connectionGenerator)
        {
            config.ThrowIfNull($"{nameof(AsyncCacheMgr)}.{nameof(config)}");
            logger.ThrowIfNull($"{nameof(AsyncCacheMgr)}.{nameof(logger)}");
            connectionGenerator.ThrowIfNull($"{nameof(AsyncCacheMgr)}.{nameof(connectionGenerator)}");

            config.Validate();

            _maxConcurrency = StaticCalls.AdjustMaxConcurrency(config.MaxConcurrency);
            var connectionBlocker = new BlockingCollection <string>(_maxConcurrency);

            for (var i = 0; i < _maxConcurrency; i++)
            {
                connectionBlocker.Add("DB" + i);
            }

            _cacheProfiles    = config.CacheProfiles.Validate();
            _initInputBuilder = new InitInputBuilder
            {
                DatabaseProfiles      = config.DbProfiles.Validate(),
                ReloadProfiles        = config.ReloadProfiles.Validate(),
                SerializationProfiles = config.SerializationProfiles.Validate(),
                LocalCacheFolder      = config.CacheLocalFolder.ToDirectoryInfo(),
                ConnectionBlocker     = connectionBlocker,
                ConnectionGenerator   = connectionGenerator,
                Logger = logger,
                Token  = _cts.Token
            };

            _cacheCollection = new ConcurrentQueue <IAsyncCache>();
            _cacheDictionary = new ConcurrentDictionary <Type, object>();
        }
 /// <summary>
 /// Basic config validation.
 /// </summary>
 /// <param name="config">instance value to validate.</param>
 public static void Validate(this IAsyncCacheConfig config)
 {
     try
     {
         config.ThrowIfNull(nameof(IAsyncCacheConfig));
         config.CacheLocalFolder.ThrowIfNullOrWhiteSpace($"{nameof(IAsyncCacheConfig)}" +
                                                         $".{nameof(config.CacheLocalFolder)}");
         config.MaxConcurrency.ThrowIfNegative($"{nameof(IAsyncCacheConfig)}.{nameof(config.MaxConcurrency)}");
         config.CacheProfiles.ThrowIfNullOrEmpty($"{nameof(IAsyncCacheConfig)}.{nameof(config.CacheProfiles)}");
         config.ReloadProfiles.ThrowIfNullOrEmpty($"{nameof(IAsyncCacheConfig)}.{nameof(config.ReloadProfiles)}");
         config.DbProfiles.ThrowIfNullOrEmpty($"{nameof(IAsyncCacheConfig)}.{nameof(config.DbProfiles)}");
         config.SerializationProfiles.ThrowIfNullOrEmpty($"{nameof(IAsyncCacheConfig)}" +
                                                         $".{nameof(config.SerializationProfiles)}");
     }
     catch (Exception e)
     {
         throw new AsyncCacheException(AsyncCacheErrorCode.InvalidConfig, "Some config is invalid", e);
     }
 }