예제 #1
0
        public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IApplicationLifetime lifetime,
                                                         ConsulOption consulOption)
        {
            var consulClient = new ConsulClient(x => { x.Address = new Uri(consulOption.ConsulAddress); });

            var registration = new AgentServiceRegistration
            {
                ID      = Guid.NewGuid().ToString(),
                Name    = consulOption.ServiceName, //服务名
                Address = consulOption.ServiceIp,   //服务绑定IP
                Port    = consulOption.ServicePort, //服务绑定端口
                Check   = new AgentServiceCheck
                {
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5), //服务启动多久后注册
                    Interval = TimeSpan.FromSeconds(10),                      //监控检查时间间隔
                    HTTP     = consulOption.ServiceHealthCheck,               //健康检查地址
                    Timeout  = TimeSpan.FromSeconds(5)
                }
            };

            //服务注册
            consulClient.Agent.ServiceRegister(registration).Wait();

            //应用程序终止时,服务取消注册
            lifetime.ApplicationStopping.Register(() =>
            {
                consulClient.Agent.ServiceDeregister(registration.ID).Wait();
            });

            return(app);
        }
        private static ConfigInfo GetConfigInfo(ConfigInfo config)
        {
            ConsulOption option = SurgingConfig.MicroService.Consul;

            if (option != null)
            {
                var sessionTimeout = config.SessionTimeout.TotalSeconds;
                Double.TryParse(option.SessionTimeout, out sessionTimeout);
                config = new ConfigInfo(
                    option.ConnectionString,
                    TimeSpan.FromSeconds(sessionTimeout),
                    option.LockDelay ?? config.LockDelay,
                    option.RoutePath ?? config.RoutePath,
                    option.SubscriberPath ?? config.SubscriberPath,
                    option.CommandPath ?? config.CommandPath,
                    option.CachePath ?? config.CachePath,
                    option.MqttRoutePath ?? config.MqttRoutePath,
                    option.ReloadOnChange != null ? bool.Parse(option.ReloadOnChange) :
                    config.ReloadOnChange,
                    option.EnableChildrenMonitor != null ? bool.Parse(option.EnableChildrenMonitor) :
                    config.EnableChildrenMonitor
                    );
            }
            return(config);
        }
예제 #3
0
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IHostApplicationLifetime lifetime)
        {
            // CORS
            app.UseCors("CorsPolicy");

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapHub <MessageHub>("/messageHub");
                endpoints.MapControllers();
            });

            var consulOption = new ConsulOption
            {
                ServiceName        = Configuration["ConsulConfig:ServiceName"],
                ServiceIp          = Configuration["ConsulConfig:ServiceIP"],
                ServicePort        = Convert.ToInt32(Configuration["ConsulConfig:ServicePort"]),
                ServiceHealthCheck = Configuration["ConsulConfig:ServiceHealthCheck"],
                ConsulAddress      = Configuration["ConsulConfig:ConsulAddress"]
            };

            app.RegisterConsul(lifetime, consulOption);
        }
예제 #4
0
        private static void CheckConfig(ConsulOption serviceOptions)
        {
            if (serviceOptions == null)
            {
                throw new Exception("请正确配Consul");
            }

            if (string.IsNullOrEmpty(serviceOptions.ConsulUrl))
            {
                throw new Exception("请正确配置ConsulUrl");
            }

            if (string.IsNullOrEmpty(serviceOptions.ServiceName))
            {
                throw new Exception("请正确配置ServiceName");
            }

            if (string.IsNullOrEmpty(serviceOptions.HealthCheckUrl))
            {
                throw new Exception("请正确配置HealthCheckUrl");
            }

            if (serviceOptions.HealthCheckIntervalInSecond <= 0)
            {
                throw new Exception("请正确配置HealthCheckIntervalInSecond");
            }
        }
예제 #5
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseMvc();

            var consulOption = new ConsulOption
            {
                ServiceName        = Configuration["ServiceName"],
                ServiceIP          = Configuration["ServiceIP"],
                ServicePort        = Convert.ToInt32(Configuration["ServicePort"]),
                ServiceHealthCheck = Configuration["ServiceHealthCheck"],
                Address            = Configuration["ConsulAddress"]
            };

            app.RegisterConsul(lifetime, consulOption);
        }
        private static ConfigInfo GetConfigInfo(ConfigInfo config)
        {
            ConsulOption option  = null;
            var          section = CPlatform.AppConfig.GetSection("Consul");

            if (section.Exists())
            {
                option = section.Get <ConsulOption>();
            }
            else if (AppConfig.Configuration != null)
            {
                option = AppConfig.Configuration.Get <ConsulOption>();
            }

            if (option != null)
            {
                var sessionTimeout = config.SessionTimeout.TotalSeconds;
                Double.TryParse(option.SessionTimeout, out sessionTimeout);
                config = new ConfigInfo(
                    option.ConnectionString,
                    TimeSpan.FromSeconds(sessionTimeout),
                    option.RoutePath ?? config.RoutePath,
                    option.SubscriberPath ?? config.SubscriberPath,
                    option.CommandPath ?? config.CommandPath,
                    option.CachePath ?? config.CachePath,
                    option.MqttRoutePath ?? config.MqttRoutePath,
                    option.ReloadOnChange != null ? bool.Parse(option.ReloadOnChange) :
                    config.ReloadOnChange,
                    option.EnableChildrenMonitor != null ? bool.Parse(option.EnableChildrenMonitor) :
                    config.EnableChildrenMonitor
                    );
            }
            return(config);
        }
예제 #7
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });


            var consulOption = new ConsulOption
            {
                ServiceName        = Configuration["ServiceName"],
                ServiceIP          = Configuration["ServiceIP"],
                ServicePort        = Convert.ToInt32(Configuration["ServicePort"]),
                ServiceHealthCheck = Configuration["ServiceHealthCheck"],
                Address            = Configuration["ConsulAddress"]
            };

            app.RegisterConsul(lifetime, consulOption);
        }
예제 #8
0
        public static void RegisterConsul(ConsulOption consulOption)
        {
            var consulClient = new ConsulClient(x =>
            {
                // consul 服务地址
                x.Address = new Uri(consulOption.ConsulAddress);
            });

            var registration = new AgentServiceRegistration()
            {
                ID      = Guid.NewGuid().ToString(),
                Name    = consulOption.ServiceName, // 服务名
                Tags    = consulOption.Tags,
                Address = consulOption.ServiceIP,   // 服务绑定IP
                Port    = consulOption.ServicePort, // 服务绑定端口
                Check   = new AgentServiceCheck()
                {
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5), //服务启动多久后注册
                    Interval = TimeSpan.FromSeconds(10),                      //健康检查时间间隔
                    HTTP     = consulOption.ServiceHealthCheck,               //健康检查地址
                    Timeout  = TimeSpan.FromSeconds(5)
                },
                Meta = consulOption.Meta
            };

            // 服务注册
            consulClient.Agent.ServiceRegister(registration).Wait();
        }
예제 #9
0
        public static void RegisterToConsul(this IApplicationBuilder app, ConsulOption consulOption)
        {
            CheckConfig(consulOption);

            var serverId = $"{consulOption.ServiceName}-{(DateTime.UtcNow.Ticks - 621355968000000000) / 10000000}";

            var consulClient = new ConsulClient(ConsulClientConfiguration => ConsulClientConfiguration.Address = new Uri(consulOption.ConsulUrl));

            var lifetime = app.ApplicationServices.GetRequiredService <IHostApplicationLifetime>();

            lifetime.ApplicationStarted.Register(() =>
            {
                if (!TryGetServiceUrl(app, consulOption, out var serverListenUrl, out var errorMsg))
                {
                    throw new Exception(errorMsg);
                }

                var protocol = serverListenUrl.Scheme;
                var host     = serverListenUrl.Host;
                var port     = serverListenUrl.Port;
                var check    = new AgentServiceCheck
                {
                    ////服务启动多久后注册
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(3),
                    Interval = TimeSpan.FromSeconds(10),
                    HTTP     = $"{protocol}://{host}:{port}/{consulOption.HealthCheckUrl}",
                    //Timeout = TimeSpan.FromSeconds(5)
                };

                var registration = new AgentServiceRegistration()
                {
                    ID      = serverId,
                    Name    = consulOption.ServiceName,
                    Address = host,
                    Port    = port,
                    Meta    = new Dictionary <string, string>()
                    {
                        ["Protocol"] = protocol
                    },
                    Tags   = consulOption.ServerTags,
                    Checks = new AgentServiceCheck[] { check }
                };

                consulClient.Agent.ServiceRegister(registration).Wait();
            });

            lifetime.ApplicationStopping.Register(() =>
            {
                consulClient.Agent.ServiceDeregister(serverId).Wait();
            });
        }
예제 #10
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();

            var consulOption = new ConsulOption
            {
                ServiceName        = Configuration["ServiceName"],
                ServiceIP          = Configuration["ServiceIP"],
                ServicePort        = Convert.ToInt32(Configuration["ServicePort"]),
                ServiceHealthCheck = Configuration["ServiceHealthCheck"],
                Address            = Configuration["ConsulAddress"]
            };

            app.RegisterConsul(lifetime, consulOption);
        }
예제 #11
0
        public void Configure(IApplicationBuilder app,
                              IWebHostEnvironment env,
                              IHostApplicationLifetime hostApplicationLifetime
                              )
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();
            app.UseAuthentication();    //认证服务
            app.UseAuthorization();     //使用授权服务

            #region Consul服务注册
            //获取当前绑定域名
            var bindingUrl = app.ServerFeatures.Get <IServerAddressesFeature>().Addresses.First();
            Console.WriteLine("bindingUrl:" + bindingUrl);
            if (bindingUrl.Contains("+"))
            {
                //docker环境从环境变量获取,docker-compose启动时会设置该值
                bindingUrl = Environment.GetEnvironmentVariable("ServiceUrl", EnvironmentVariableTarget.Process);
                Console.WriteLine("environmentVariable:" + bindingUrl);
            }

            var u            = new Uri(bindingUrl);
            var consulOption = new ConsulOption();
            Configuration.Bind(nameof(ConsulOption), consulOption);
            consulOption.ServiceHealthCheck = bindingUrl + "/healthCheck";
            consulOption.ServiceIP          = u.Host;
            consulOption.ServicePort        = u.Port;
            app.UseConusl(hostApplicationLifetime, consulOption);
            #endregion

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
예제 #12
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

            var consulOption = new ConsulOption
            {
                ServiceName        = Configuration["ServiceName"],
                ServiceIP          = Configuration["ServiceIP"],
                ServicePort        = Convert.ToInt32(Configuration["ServicePort"]),
                ServiceHealthCheck = Configuration["ServiceHealthCheck"],
                Address            = Configuration["ConsulAddress"]
            };

            app.RegisterConsul(lifetime, consulOption);


            // 短路中间件,配置Controller路由
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
예제 #13
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime, ConsulOption consulOption)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            // 注册
            app.RegisterConsul(lifetime, consulOption);

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
예제 #14
0
        public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IHostApplicationLifetime lifetime, ConsulOption consulOption)
        {
            var consulClient = new ConsulClient(x =>
                                                x.Address = new Uri(consulOption.Address));//请求注册的 Consul 地址
            var httpCheck = new AgentServiceCheck()
            {
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5), //服务启动多久后注册
                Interval = TimeSpan.FromSeconds(10),                      //健康检查时间间隔,或者称为心跳间隔
                HTTP     = consulOption.ServiceHealthCheck,               //健康检查地址
                Timeout  = TimeSpan.FromSeconds(5)
            };

            // Register service with consul
            var registration = new AgentServiceRegistration()
            {
                Checks  = new[] { httpCheck },
                ID      = Guid.NewGuid().ToString(),
                Name    = consulOption.ServiceName,
                Address = consulOption.ServiceIP,
                Port    = consulOption.ServicePort,
                Tags    = new[] { $"urlprefix-/{consulOption.ServiceName}" }//添加 urlprefix-/servicename 格式的 tag 标签,以便 Fabio 识别
            };

            // 服务注册
            consulClient.Agent.ServiceRegister(registration).Wait();//服务启动时注册,内部实现其实就是使用 Consul API 进行注册(HttpClient发起)

            // 应用程序终止时,服务取消注册
            lifetime.ApplicationStopping.Register(() =>
            {
                consulClient.Agent.ServiceDeregister(registration.ID).Wait();//服务停止时取消注册
            });

            return(app);
        }
예제 #15
0
        private static bool TryGetServiceUrl(IApplicationBuilder app, ConsulOption consulOption, out Uri serverListenUrl, out string errorMsg)
        {
            errorMsg        = string.Empty;
            serverListenUrl = default;

            var allIPAddress = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()
                               .Select(p => p.GetIPProperties())
                               .SelectMany(p => p.UnicastAddresses)
                               .Where(p => p.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && !System.Net.IPAddress.IsLoopback(p.Address))
                               .Select(p => p.Address.ToString()).ToArray();

            //docker容器部署服务,从环境变量获取ServiceUriHost与Port
            if (consulOption.IsDocker)
            {
                var listenHostAndPort = Environment.GetEnvironmentVariable("DOCKER_LISTEN_HOSTANDPORT");
                if (string.IsNullOrEmpty(listenHostAndPort))
                {
                    errorMsg = "docker部署,必须配置DOCKER_LISTEN_HOSTANDPORT环境变量";
                    return(false);
                }
                serverListenUrl = new Uri(listenHostAndPort);
                return(true);
            }

            var listenUrls = app.ServerFeatures.Get <IServerAddressesFeature>()
                             .Addresses
                             .Select(url => new Uri(url)).ToArray();

            //不是docker容器部署,并且没有配置ServiceUriHost
            if (string.IsNullOrWhiteSpace(consulOption.ServiceUrl))
            {
                // 本机所有可用IP与listenUrls进行匹配, 如果listenUrl是"0.0.0.0"或"[::]", 则任意IP都符合匹配
                var matches = allIPAddress.SelectMany(ip =>
                                                      listenUrls
                                                      .Where(uri => ip == uri.Host || uri.Host == "0.0.0.0" || uri.Host == "[::]")
                                                      .Select(uri => new { Protocol = uri.Scheme, ServiceIP = ip, Port = uri.Port })
                                                      ).ToList();

                if (matches.Count == 0)
                {
                    errorMsg = $"没有匹配的Ip地址=[{string.Join(',', allIPAddress)}], urls={string.Join(',', (IEnumerable<Uri>)listenUrls)}.";
                    return(false);
                }
                else if (matches.Count == 1)
                {
                    serverListenUrl = new Uri($"{matches[0].Protocol}://{ matches[0].ServiceIP}:{matches[0].Port}");
                    return(true);
                }
                else
                {
                    errorMsg = $"请指定ServiceUrl: {string.Join(",", matches)}.";
                    return(false);
                }
            }

            // 如果提供了对外服务的IP, 只需要检测是否在listenUrls里面即可
            var  serviceUri = new Uri(consulOption.ServiceUrl);
            bool isExists   = listenUrls.Where(p => p.Host == serviceUri.Host || p.Host == "0.0.0.0" || p.Host == "[::]").Any();

            if (isExists)
            {
                serverListenUrl = serviceUri;
                return(true);
            }
            errorMsg = $"服务Ip配置错误 urls={string.Join(',', (IEnumerable<Uri>)listenUrls)}";
            return(false);
        }
예제 #16
0
 public ConsulNetClient(ConsulOption consulOption)
 {
     //EnsureUtil.NotNull(consulOption, "consulOption");
     _consulOption = consulOption;
 }
예제 #17
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime, ConsulOption consulOption)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            #region 使用中间件Metrics
            //string IsOpen = Configuration.GetSection("InfluxDB")["IsOpen"].ToLower();
            //if (IsOpen == "true")
            //{
            //    app.UseMetricsAllMiddleware();
            //    app.UseMetricsAllEndpoints();
            //}
            #endregion

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

            //配置使用Ocelot
            app.UseOcelot().Wait();

            // 注册Consul
            app.RegisterConsul(lifetime, consulOption);
        }
예제 #18
0
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime, ConsulOption consulOption)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            ExceptionlessClient.Default.Configuration.ApiKey    = Configuration.GetSection("Exceptionless:ApiKey").Value;
            ExceptionlessClient.Default.Configuration.ServerUrl = Configuration.GetSection("Exceptionless:ServerUrl").Value;
            app.UseExceptionless();

            // 注册Consul
            app.RegisterConsul(lifetime, consulOption);

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
예제 #19
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime, ConsulOption consulOption)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "ConsulUseExamples v1"));
            }

            // зЂВс
            app.RegisterConsul(lifetime, consulOption);

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
예제 #20
0
        public static async Task Main(string[] args)
        {
            IConfiguration Configuration;

            Startup = ConsoleAppConfigurator.BootstrapApp();
            var serviceCollection = new ServiceCollection();

            Startup.ConfigureServices(serviceCollection);
            ServiceProvider = serviceCollection.BuildServiceProvider();
            Configuration   = Startup.Configuration;
            var ConfigOptionsTest = new ConfigOptions();

            Configuration.GetSection("ConfigOptions").Bind(ConfigOptionsTest);
            DataOptions         dataOptions        = ServiceProvider.GetService <IOptions <DataOptions> >().Value;
            ConfigOptions       configOptions      = ServiceProvider.GetService <IOptions <ConfigOptions> >().Value;
            IConsulServicesFind consulServicesFind = ServiceProvider.GetRequiredService <IConsulServicesFind>();

            ConsulOption consulOption = new ConsulOption();

            Configuration.GetSection("ConsulOption").Bind(consulOption);
            //注册10个不健康的ServiceA节点
            consulOption.ServiceHealthCheck = "http://127.0.0.1:8088/healthCheck";
            for (int i = 0; i < 10; i++)
            {
                RegisterConsul(consulOption);
            }
            // Find the ServiceA

            using (var consulClient = new ConsulClient(a => a.Address = new Uri(dataOptions.ConsulUrl)))
            {
                CatalogService[] services = consulServicesFind.FindConsulServices("ServiceA").ToArray();

                if (services != null && services.Any())
                {
                    // 模拟随机一台进行请求,这里只是测试,可以选择合适的负载均衡工具或框架
                    Random r       = new Random();
                    int    index   = r.Next(services.Count());
                    var    service = services.ElementAt(index);

                    using (HttpClient client = new HttpClient())
                    {
                        var response = await client.GetAsync($"http://{service.ServiceAddress}:{service.ServicePort}/weatherforecast");

                        var result = await response.Content.ReadAsStringAsync();

                        Console.WriteLine(result);
                    }
                }
            }
            //注册10个不健康的ServiceB节点
            consulOption.ServiceName = "ServiceB";
            for (int i = 0; i < 10; i++)
            {
                RegisterConsul(consulOption);
            }
            //Find the ServiceB
            using (var consulClient = new ConsulClient(a => a.Address = new Uri(dataOptions.ConsulUrl)))
            {
                CatalogService[] services = consulServicesFind.FindConsulServices("ServiceB").ToArray();
                if (services != null && services.Any())
                {
                    // 模拟随机一台进行请求,这里只是测试,可以选择合适的负载均衡工具或框架
                    Random r       = new Random();
                    int    index   = r.Next(services.Count());
                    var    service = services.ElementAt(index);

                    using (HttpClient client = new HttpClient())
                    {
                        var response = await client.GetAsync($"http://{service.ServiceAddress}:{service.ServicePort}/weatherforecast");

                        var result = await response.Content.ReadAsStringAsync();

                        Console.WriteLine(result);
                    }
                }
            }
            //Put or Replace the config, the ServiceA and ServiceB will sync the config
            using (var consulClient = new ConsulClient(a => a.Address = new Uri(dataOptions.ConsulUrl)))
            {
                string jsonString = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"), Encoding.Default);
                var    putPair    = new KVPair("Config.json")
                {
                    Value = Encoding.UTF8.GetBytes(jsonString)
                };

                var putAttempt = await consulClient.KV.Put(putPair);

                if (putAttempt.Response)
                {
                    var getPair = await consulClient.KV.Get("Config.json");

                    string result = Encoding.UTF8.GetString(getPair.Response.Value, 0,
                                                            getPair.Response.Value.Length);
                    Console.WriteLine(result);
                }
            }
        }
예제 #21
0
 public TestController(ConsulOption consulOption, IHttpClientFactory httpClientFactory)
 {
     _consulOption      = consulOption;
     _httpClientFactory = httpClientFactory;
 }