public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration, OrderingSettings settings)
        {
            services.AddDbContext <OrderingContext>(options =>
            {
                if (configuration.GetValue <bool>("DBInMemory"))
                {
                    options.UseInMemoryDatabase("OrdersDB",
                                                (ops) =>
                    {
                    });
                }
                else
                {
                    options.UseSqlServer(settings.OrdersDBConnectionString,
                                         sqlServerOptionsAction: sqlOptions =>
                    {
                        sqlOptions.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name);
                        //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency
                        sqlOptions.EnableRetryOnFailure(maxRetryCount: 10, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
                    });

                    // Changing default behavior when client evaluation occurs to throw.
                    // Default in EF Core would be to log a warning when client evaluation is performed.
                    options.ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning));
                    //Check Client vs. Server evaluation: https://docs.microsoft.com/en-us/ef/core/querying/client-eval
                }
            });

            return(services);
        }
 public Startup(IConfiguration configuration)
 {
     _configuration = configuration;
     _settings      = _configuration.GetSection(Program.AppName).Get <OrderingSettings>();
 }
        public static IServiceCollection AddCustomMassTransitAzureServiceBus(
            this IServiceCollection services,
            OrderingSettings settings,
            bool isSagaTest)
        {
            services.AddMassTransit(options =>
            {
                // Integration Events as Masstransit Consumers.
                // options.AddConsumersFromNamespaceContaining<OrderToPayConsumer>();

                options.AddBus(provider => Bus.Factory.CreateUsingAzureServiceBus(cfg =>
                {
                    // cfg.EnablePartitioning = true; // Message Broker is enabled !
                    cfg.RequiresSession = !isSagaTest;
                    cfg.UseJsonSerializer();

                    // var host = cfg.Host(settings.EventBusConnectionString, hostConfig =>
                    var host = cfg.Host(new Uri(settings.EventBusUrl), hostConfig =>
                    {
                        // hostConfig.ExchangeType = ExchangeType.Topic;
                        // hostConfig.TransportType = Microsoft.Azure.ServiceBus.TransportType.AmqpWebSockets;
                        //hostConfig.RetryLimit = 3;
                        //hostConfig.OperationTimeout = TimeSpan.FromMinutes(1);
                        hostConfig.SharedAccessSignature(x =>
                        {
                            x.KeyName         = settings.EventBusKeyName;
                            x.SharedAccessKey = settings.EventBusSharedAccessKey;
                            // https://github.com/Azure/azure-service-bus-dotnet/issues/399
                            // without this line MassTransit sets the Token TTL to 0.00 instead of null
                            x.TokenTimeToLive = TimeSpan.FromDays(1);
                        });
                    });

                    // cfg.SubscriptionEndpoint(host, "buscriptionxxx", "topicxxx", config => { config.xxx });

                    // cfg.Send<IEvent>(x =>
                    cfg.Send <OrderReadyToBillMessage>(x =>
                    {
                        x.UseSessionIdFormatter(context =>
                        {
                            var sessionId = context.CorrelationId.ToString();
                            context.SetReplyToSessionId(sessionId);
                            return(sessionId);
                        });
                    });

                    cfg.ReceiveEndpoint(host, "saga_sales_queue", e =>
                    {
                        e.UseCircuitBreaker(cb =>
                        {
                            cb.TrackingPeriod  = TimeSpan.FromMinutes(1);
                            cb.TripThreshold   = 15;
                            cb.ActiveThreshold = 10;
                            cb.ResetInterval   = TimeSpan.FromMinutes(5);
                        });

                        e.UseMessageRetry(r =>
                        {
                            r.Interval(4, TimeSpan.FromSeconds(30));
                        });

                        // All messages that should be published, are collected in a buffer, which is called “outbox”
                        //e.UseInMemoryOutbox();

                        //e.SubscribeMessageTopics = true;
                        //e.RemoveSubscriptions = true;
                        // e.EnablePartitioning = true;  // Message Broker is enabled !
                        e.MessageWaitTimeout = TimeSpan.FromMinutes(5);
                        e.RequiresSession    = !isSagaTest;

                        // e.Consumer<OrderToPayConsumer>( );
                        // e.Consumer(() => provider.GetRequiredService<IConsumer<OrderToPayConsumer>>());

                        e.StateMachineSaga(provider.GetRequiredService <OrdersSagaStateMachine>(),
                                           provider.GetRequiredService <ISagaRepository <OrderSagaState> >());
                    });
                }));
            });

            // services.AddSingleton<ISendEndpointProvider>(provider => provider.GetRequiredService<IBusControl>());

            // Required to start Bus Service.
            services.AddSingleton <Microsoft.Extensions.Hosting.IHostedService, BusHostedService>();

            if (isSagaTest)
            {
                services.AddSingleton <ISagaRepository <OrderSagaState>, InMemorySagaRepository <OrderSagaState> >();
            }
            else
            {
                services.AddSingleton <ISagaRepository <OrderSagaState>, MessageSessionSagaRepository <OrderSagaState> >();
            }

            services.AddSingleton <OrdersSagaStateMachine>();

            return(services);
        }