public HttpRequestRateLimiterMiddleware(RequestDelegate next, IOptions <HttpRequestRateLimiterOptions <TKey> > options, IConfiguration config, ILoggerFactory loggerFactory)
        {
            Next    = next ?? throw new ArgumentNullException(nameof(next));
            Config  = config ?? throw new ArgumentNullException(nameof(config));
            Options = options?.Value ?? throw new ArgumentNullException(nameof(options));

            RateLimiter       = new RateLimiter <TKey>(RateLimiterOptions);
            ConcurrentLimiter = new ConcurrentLimiter <TKey>(Options.MaxConcurrentRequestsPerSrcSubnet);
        }
        // Factory メソッド
        public static IHttpRequestRateLimiterHashKey?CreateFromHttpContext <TKey>(HttpContext context, HttpRequestRateLimiterOptions <TKey> options) where TKey : IHttpRequestRateLimiterHashKey
        {
            // Src IP の処理
            IPAddress srcIp = context.Connection.RemoteIpAddress._UnmapIPv4();

            if (options.SrcIPExcludeLocalNetwork)
            {
                // ローカルネットワークを除外する
                if (srcIp._GetIPAddressType()._IsLocalNetwork())
                {
                    return(null);
                }
            }

            // サブネットマスクの AND をする
            if (srcIp.AddressFamily == AddressFamily.InterNetwork)
            {
                // IPv4
                srcIp = IPUtil.IPAnd(srcIp, IPUtil.IntToSubnetMask4(options.SrcIPv4SubnetLength));
            }
            else
            {
                // IPv6
                srcIp = IPUtil.IPAnd(srcIp, IPUtil.IntToSubnetMask6(options.SrcIPv6SubnetLength));
            }

            if (typeof(TKey) == typeof(SrcIPAddress))
            {
                if (srcIp != null)
                {
                    return(new SrcIPAddress(srcIp));
                }
            }

            return(null);
        }