예제 #1
0
        public static IFixerBuilder AddWebApi(this IFixerBuilder builder, string sectionName = SectionName)
        {
            if (!builder.TryRegister(RegistryName))
            {
                return(builder);
            }

            builder.Services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();
            builder.Services.AddSingleton(new WebApiEndpointDefinitions());
            builder.Services.AddRouting()
            .AddLogging()
            .AddMvcCore()
            .AddJsonFormatters()
            .AddDataAnnotations()
            .AddApiExplorer()
            .AddDefaultJsonOptions()
            .AddAuthorization();

            builder.Services.Scan(s =>
                                  s.FromAssemblies(AppDomain.CurrentDomain.GetAssemblies())
                                  .AddClasses(c => c.AssignableTo(typeof(IRequestHandler <,>)))
                                  .AsImplementedInterfaces()
                                  .WithTransientLifetime());

            builder.Services.AddTransient <IRequestDispatcher, RequestDispatcher>();

            return(builder);
        }
예제 #2
0
        private static IFixerBuilder AddServiceClient <T>(this IFixerBuilder builder, string serviceName,
                                                          RestEaseOptions options, Action <IFixerBuilder> registerFabio)
            where T : class
        {
            if (!builder.TryRegister(RegistryName))
            {
                return(builder);
            }

            var clientName = typeof(T).ToString();

            switch (options.LoadBalancer?.ToLowerInvariant())
            {
            case "consul":
                builder.AddConsulHttpClient(clientName, serviceName);
                break;

            case "fabio":
                builder.AddFabioHttpClient(clientName, serviceName);
                break;

            default:
                ConfigureDefaultClient(builder.Services, clientName, serviceName, options);
                break;
            }

            ConfigureForwarder <T>(builder.Services, clientName);

            registerFabio(builder);

            return(builder);
        }
        private static IFixerBuilder AddFabio(this IFixerBuilder builder, FabioOptions fabioOptions,
                                              HttpClientOptions httpClientOptions, Action <IFixerBuilder> registerConsul)
        {
            registerConsul(builder);
            builder.Services.AddSingleton(fabioOptions);

            if (!fabioOptions.Enabled || !builder.TryRegister(RegistryName))
            {
                return(builder);
            }

            if (httpClientOptions.Type?.ToLowerInvariant() == "fabio")
            {
                builder.Services.AddTransient <FabioMessageHandler>();
                builder.Services.AddHttpClient <IFabioHttpClient, FabioHttpClient>()
                .AddHttpMessageHandler <FabioMessageHandler>();
                builder.Services.AddHttpClient <IHttpClient, FabioHttpClient>()
                .AddHttpMessageHandler <FabioMessageHandler>();
            }

            using (var serviceProvider = builder.Services.BuildServiceProvider())
            {
                var registration = serviceProvider.GetService <AgentServiceRegistration>();
                registration.Tags = GetFabioTags(registration.Name, fabioOptions.Service);
                builder.Services.UpdateConsulRegistration(registration);
            }

            return(builder);
        }
예제 #4
0
        public static IFixerBuilder AddConsul(this IFixerBuilder builder,
                                              Func <IConsulOptionsBuilder, IConsulOptionsBuilder> buildOptions, HttpClientOptions httpClientOptions)
        {
            var options = buildOptions(new ConsulOptionsBuilder()).Build();

            return(builder.AddConsul(options, httpClientOptions));
        }
예제 #5
0
        public static IFixerBuilder AddJaeger(this IFixerBuilder builder,
                                              Func <IJaegerOptionsBuilder, IJaegerOptionsBuilder> buildOptions)
        {
            var options = buildOptions(new JaegerOptionsBuilder()).Build();

            return(builder.AddJaeger(options));
        }
예제 #6
0
        public static IFixerBuilder AddExceptionToMessageMapper <T>(this IFixerBuilder builder)
            where T : class, IExceptionToMessageMapper
        {
            builder.Services.AddSingleton <IExceptionToMessageMapper, T>();

            return(builder);
        }
예제 #7
0
        public static IFixerBuilder AddMongo(this IFixerBuilder builder, Func <IMongoDbOptionsBuilder,
                                                                               IMongoDbOptionsBuilder> buildOptions, IMongoDbSeeder seeder = null)
        {
            var mongoOptions = buildOptions(new MongoDbOptionsBuilder()).Build();

            return(builder.AddMongo(mongoOptions, seeder));
        }
예제 #8
0
        public static IFixerBuilder AddMongo(this IFixerBuilder builder, string sectionName = SectionName,
                                             IMongoDbSeeder seeder = null)
        {
            var mongoOptions = builder.GetOptions <MongoDbOptions>(sectionName);

            return(builder.AddMongo(mongoOptions, seeder));
        }
예제 #9
0
        public static IFixerBuilder AddMetrics(this IFixerBuilder builder,
                                               Func <IMetricsOptionsBuilder, IMetricsOptionsBuilder> buildOptions)
        {
            var options = buildOptions(new MetricsOptionsBuilder()).Build();

            return(builder.AddMetrics(options));
        }
예제 #10
0
        public static IFixerBuilder AddConsul(this IFixerBuilder builder, string sectionName = SectionName,
                                              string httpClientSectionName = "httpClient")
        {
            var consulOptions     = builder.GetOptions <ConsulOptions>(sectionName);
            var httpClientOptions = builder.GetOptions <HttpClientOptions>(httpClientSectionName);

            return(builder.AddConsul(consulOptions, httpClientOptions));
        }
예제 #11
0
        public static IFixerBuilder AddCommandHandlers(this IFixerBuilder builder)
        {
            builder.Services.Scan(s =>
                                  s.FromAssemblies(AppDomain.CurrentDomain.GetAssemblies())
                                  .AddClasses(c => c.AssignableTo(typeof(ICommandHandler <>)))
                                  .AsImplementedInterfaces()
                                  .WithTransientLifetime());

            return(builder);
        }
예제 #12
0
        public static IFixerBuilder AddServiceClient <T>(this IFixerBuilder builder, string serviceName,
                                                         string sectionName           = SectionName, string consulSectionName = "consul", string fabioSectionName = "fabio",
                                                         string httpClientSectionName = "httpClient")
            where T : class
        {
            var restEaseOptions = builder.GetOptions <RestEaseOptions>(sectionName);

            return(builder.AddServiceClient <T>(serviceName, restEaseOptions,
                                                b => b.AddFabio(fabioSectionName, consulSectionName, httpClientSectionName)));
        }
예제 #13
0
        public static IFixerBuilder AddFabio(this IFixerBuilder builder,
                                             Func <IFabioOptionsBuilder, IFabioOptionsBuilder> buildOptions,
                                             Func <IConsulOptionsBuilder, IConsulOptionsBuilder> buildConsulOptions,
                                             HttpClientOptions httpClientOptions)
        {
            var fabioOptions = buildOptions(new FabioOptionsBuilder()).Build();

            return(builder.AddFabio(fabioOptions, httpClientOptions,
                                    b => b.AddConsul(buildConsulOptions, httpClientOptions)));
        }
예제 #14
0
        public static IFixerBuilder AddMongoRepository <TEntity, TIdentifiable>(this IFixerBuilder builder,
                                                                                string collectionName)
            where TEntity : IIdentifiable <TIdentifiable>
        {
            builder.Services.AddTransient <IMongoRepository <TEntity, TIdentifiable> >(sp =>
            {
                var database = sp.GetService <IMongoDatabase>();
                return(new MongoRepository <TEntity, TIdentifiable>(database, collectionName));
            });

            return(builder);
        }
예제 #15
0
        public static IFixerBuilder AddServiceClient <T>(this IFixerBuilder builder, string serviceName,
                                                         Func <IRestEaseOptionsBuilder, IRestEaseOptionsBuilder> buildOptions,
                                                         Func <IConsulOptionsBuilder, IConsulOptionsBuilder> buildConsulOptions,
                                                         Func <IFabioOptionsBuilder, IFabioOptionsBuilder> buildFabioOptions,
                                                         HttpClientOptions httpClientOptions)
            where T : class
        {
            var options = buildOptions(new RestEaseOptionsBuilder()).Build();

            return(builder.AddServiceClient <T>(serviceName, options,
                                                b => b.AddFabio(buildFabioOptions, buildConsulOptions, httpClientOptions)));
        }
예제 #16
0
        public static IFixerBuilder AddHttpClient(this IFixerBuilder builder, string sectionName = SectionName)
        {
            if (!builder.TryRegister(RegistryName))
            {
                return(builder);
            }

            var options = builder.GetOptions <HttpClientOptions>(sectionName);

            builder.Services.AddSingleton(options);
            builder.Services.AddHttpClient <IHttpClient, FixerHttpClient>();

            return(builder);
        }
예제 #17
0
        public static IFixerBuilder AddRedis(this IFixerBuilder builder, RedisOptions options)
        {
            if (!builder.TryRegister(RegistryName))
            {
                return(builder);
            }

            builder.Services.AddDistributedRedisCache(o =>
            {
                o.Configuration = options.ConnectionString;
                o.InstanceName  = options.Instance;
            });

            return(builder);
        }
예제 #18
0
        public static IFixerBuilder AddConsul(this IFixerBuilder builder, ConsulOptions options,
                                              HttpClientOptions httpClientOptions)
        {
            builder.Services.AddSingleton(options);
            if (!options.Enabled || !builder.TryRegister(RegistryName))
            {
                return(builder);
            }

            if (httpClientOptions.Type?.ToLowerInvariant() == "consul")
            {
                builder.Services.AddTransient <ConsulServiceDiscoveryMessageHandler>();
                builder.Services.AddHttpClient <IConsulHttpClient, ConsulHttpClient>()
                .AddHttpMessageHandler <ConsulServiceDiscoveryMessageHandler>();
                builder.Services.AddHttpClient <IHttpClient, ConsulHttpClient>()
                .AddHttpMessageHandler <ConsulServiceDiscoveryMessageHandler>();
            }

            builder.Services.AddTransient <IConsulServicesRegistry, ConsulServicesRegistry>();
            builder.Services.AddSingleton <IConsulClient>(c => new ConsulClient(cfg =>
            {
                if (!string.IsNullOrEmpty(options.Url))
                {
                    cfg.Address = new Uri(options.Url);
                }
            }));

            var registration = builder.CreateConsulAgentRegistration(options);

            if (registration is null)
            {
                return(builder);
            }

            builder.Services.AddSingleton(registration);
            builder.AddBuildAction(sp =>
            {
                var consulRegistration = sp.GetService <AgentServiceRegistration>();
                var client             = sp.GetService <IConsulClient>();

                client.Agent.ServiceRegister(consulRegistration);
            });

            return(builder);
        }
예제 #19
0
        private static IFixerBuilder AddHandlerLogging(this IFixerBuilder builder, Type handlerType,
                                                       Type decoratorType, Assembly assembly = null)
        {
            assembly = assembly ?? Assembly.GetCallingAssembly();

            var handlers = assembly
                           .GetTypes()
                           .Where(t => t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == handlerType))
                           .ToList();

            handlers.ForEach(ch => GetExtensionMethods()
                             .FirstOrDefault(mi => !mi.IsGenericMethod && mi.Name == "Decorate")?
                             .Invoke(builder.Services, new object[]
            {
                builder.Services,
                ch.GetInterfaces().FirstOrDefault(),
                decoratorType.MakeGenericType(ch.GetInterfaces().FirstOrDefault()?.GenericTypeArguments.First())
            }));

            return(builder);
        }
예제 #20
0
        public static IFixerBuilder AddJaeger(this IFixerBuilder builder, JaegerOptions options)
        {
            builder.Services.AddSingleton(options);
            if (!options.Enabled)
            {
                var defaultTracer = ConveyDefaultTracer.Create();
                builder.Services.AddSingleton(defaultTracer);
                return(builder);
            }

            if (!builder.TryRegister(RegistryName) || _initialized)
            {
                return(builder);
            }

            _initialized = true;
            builder.Services.AddSingleton <ITracer>(sp =>
            {
                var loggerFactory = sp.GetRequiredService <ILoggerFactory>();

                var reporter = new RemoteReporter.Builder()
                               .WithSender(new UdpSender(options.UdpHost, options.UdpPort, options.MaxPacketSize))
                               .WithLoggerFactory(loggerFactory)
                               .Build();

                var sampler = GetSampler(options);

                var tracer = new Tracer.Builder(options.ServiceName)
                             .WithLoggerFactory(loggerFactory)
                             .WithReporter(reporter)
                             .WithSampler(sampler)
                             .Build();

                GlobalTracer.Register(tracer);

                return(tracer);
            });

            return(builder);
        }
예제 #21
0
        public static IFixerBuilder AddMongo(this IFixerBuilder builder, MongoDbOptions mongoOptions,
                                             IMongoDbSeeder seeder = null)
        {
            if (!builder.TryRegister(RegistryName))
            {
                return(builder);
            }

            builder.Services.AddSingleton(mongoOptions);

            builder.Services.AddSingleton <IMongoClient>(sp =>
            {
                var options = sp.GetService <MongoDbOptions>();
                return(new MongoClient(options.ConnectionString));
            });

            builder.Services.AddTransient(sp =>
            {
                var options = sp.GetService <MongoDbOptions>();
                var client  = sp.GetService <IMongoClient>();
                return(client.GetDatabase(options.Database));
            });

            builder.Services.AddTransient <IMongoDbInitializer, MongoDbInitializer>();
            builder.Services.AddTransient <IMongoSessionFactory, MongoSessionFactory>();

            if (seeder is null)
            {
                builder.Services.AddSingleton <IMongoDbSeeder, MongoDbSeeder>();
            }
            else
            {
                builder.Services.AddSingleton(seeder);
            }

            builder.AddInitializer <IMongoDbInitializer>();

            return(builder);
        }
예제 #22
0
 public static IFixerBuilder AddServiceBusEventDispatcher(this IFixerBuilder builder)
 {
     builder.Services.AddTransient <IEventDispatcher, ServiceBusMessageDispatcher>();
     return(builder);
 }
예제 #23
0
 public static IFixerBuilder AddInMemoryCommandDispatcher(this IFixerBuilder builder)
 {
     builder.Services.AddSingleton <ICommandDispatcher, CommandDispatcher>();
     return(builder);
 }
예제 #24
0
 public static IFixerBuilder AddInMemoryEventDispatcher(this IFixerBuilder builder)
 {
     builder.Services.AddSingleton <IEventDispatcher, EventDispatcher>();
     return(builder);
 }
예제 #25
0
        public static IFixerBuilder AddRedis(this IFixerBuilder builder, Func <IRedisOptionsBuilder, IRedisOptionsBuilder> buildOptions)
        {
            var options = buildOptions(new RedisOptionsBuilder()).Build();

            return(builder.AddRedis(options));
        }
예제 #26
0
        public static IFixerBuilder AddRedis(this IFixerBuilder builder, string sectionName = SectionName)
        {
            var options = builder.GetOptions <RedisOptions>(sectionName);

            return(builder.AddRedis(options));
        }
예제 #27
0
 public static void AddConsulHttpClient(this IFixerBuilder builder, string clientName, string serviceName)
 => builder.Services.AddHttpClient <IHttpClient, ConsulHttpClient>(clientName)
 .AddHttpMessageHandler(c => new ConsulServiceDiscoveryMessageHandler(
                            c.GetService <IConsulServicesRegistry>(),
                            c.GetService <ConsulOptions>(), serviceName, true));
예제 #28
0
        public static IFixerBuilder AddJaeger(this IFixerBuilder builder, string sectionName = SectionName)
        {
            var options = builder.GetOptions <JaegerOptions>(sectionName);

            return(builder.AddJaeger(options));
        }
예제 #29
0
        private static AgentServiceRegistration CreateConsulAgentRegistration(this IFixerBuilder builder,
                                                                              ConsulOptions options)
        {
            var enabled       = options.Enabled;
            var consulEnabled = Environment.GetEnvironmentVariable("CONSUL_ENABLED")?.ToLowerInvariant();

            if (!string.IsNullOrWhiteSpace(consulEnabled))
            {
                enabled = consulEnabled == "true" || consulEnabled == "1";
            }

            if (!enabled)
            {
                return(null);
            }

            if (string.IsNullOrWhiteSpace(options.Address))
            {
                throw new ArgumentException("Consul address can not be empty.",
                                            nameof(options.PingEndpoint));
            }

            var uniqueId = string.Empty;

            using (var serviceProvider = builder.Services.BuildServiceProvider())
            {
                uniqueId = serviceProvider.GetRequiredService <IServiceId>().Id;
            }

            var pingInterval        = options.PingInterval <= 0 ? 5 : options.PingInterval;
            var removeAfterInterval = options.RemoveAfterInterval <= 0 ? 10 : options.RemoveAfterInterval;

            var registration = new AgentServiceRegistration
            {
                Name    = options.Service,
                ID      = $"{options.Service}:{uniqueId}",
                Address = options.Address,
                Port    = options.Port
            };

            if (!options.PingEnabled)
            {
                return(registration);
            }


            var scheme = options.Address.StartsWith("http", StringComparison.InvariantCultureIgnoreCase)
                ? string.Empty
                : "http://";
            var check = new AgentServiceCheck
            {
                Interval = TimeSpan.FromSeconds(pingInterval),
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(removeAfterInterval),
                HTTP = $"{scheme}{options.Address}{(options.Port > 0 ? $":{options.Port}" : string.Empty)}/" +
                       $"{options.PingEndpoint}"
            };

            registration.Checks = new[] { check };

            return(registration);
        }
예제 #30
0
 public static IFixerBuilder AddServiceClient <T>(this IFixerBuilder builder, string serviceName,
                                                  RestEaseOptions options, ConsulOptions consulOptions, FabioOptions fabioOptions,
                                                  HttpClientOptions httpClientOptions)
     where T : class
 => builder.AddServiceClient <T>(serviceName, options,
                                 b => b.AddFabio(fabioOptions, consulOptions, httpClientOptions));