/// <summary>
        /// Gets the configured container.
        /// </summary>
        /// <param name="services">The services.</param>
        /// <param name="hostingEnvironment">The hosting environment.</param>
        /// <returns></returns>
        public static IContainer GetConfiguredContainer(IServiceCollection services,
                                                        IHostingEnvironment hostingEnvironment)
        {
            Container container = new Container();

            Dictionary <String, String[]> handlerEventTypesToSilentlyHandle = new Dictionary <String, String[]>();

            if (Startup.Configuration != null)
            {
                IConfigurationSection section = Startup.Configuration.GetSection("AppSettings:HandlerEventTypesToSilentlyHandle");

                if (section != null)
                {
                    Startup.Configuration.GetSection("AppSettings:HandlerEventTypesToSilentlyHandle").Bind(handlerEventTypesToSilentlyHandle);
                }
            }

            DomainEventTypesToSilentlyHandle eventTypesToSilentlyHandle = new DomainEventTypesToSilentlyHandle(handlerEventTypesToSilentlyHandle);

            //Can we create a static method in this class that returns IContainer?
            services.AddSingleton <IDomainEventTypesToSilentlyHandle>(eventTypesToSilentlyHandle);

            container.Configure(config =>
            {
                config.AddRegistry <CommonRegistry>();

                //if (HostingEnvironment.IsDevelopment())
                //{
                //    config.AddRegistry<DevelopmentRegistry>();
                //}
            });

            container.Populate(services);

            Startup.Container = container;

            return(Startup.Container);
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        /// <summary>
        /// Configures the services.
        /// </summary>
        /// <param name="services">The services.</param>
        public void ConfigureServices(IServiceCollection services)
        {
            ConfigurationReader.Initialise(Startup.Configuration);

            Startup.ConfigureEventStoreSettings();

            this.ConfigureMiddlewareServices(services);

            services.AddTransient <IMediator, Mediator>();
            services.AddSingleton <IEstateManagementManager, EstateManagementManager>();

            Boolean useConnectionStringConfig = Boolean.Parse(ConfigurationReader.GetValue("AppSettings", "UseConnectionStringConfig"));

            if (useConnectionStringConfig)
            {
                String connectionStringConfigurationConnString = ConfigurationReader.GetConnectionString("ConnectionStringConfiguration");
                services.AddSingleton <IConnectionStringConfigurationRepository, ConnectionStringConfigurationRepository>();
                services.AddTransient <ConnectionStringConfigurationContext>(c =>
                {
                    return(new ConnectionStringConfigurationContext(connectionStringConfigurationConnString));
                });

                // TODO: Read this from a the database and set
            }
            else
            {
                services.AddEventStoreClient(Startup.ConfigureEventStoreSettings);
                services.AddEventStoreProjectionManagerClient(Startup.ConfigureEventStoreSettings);
                services.AddEventStorePersistentSubscriptionsClient(Startup.ConfigureEventStoreSettings);
                services.AddSingleton <IConnectionStringConfigurationRepository, ConfigurationReaderConnectionStringRepository>();
            }

            services.AddTransient <IEventStoreContext, EventStoreContext>();
            services.AddSingleton <IEstateManagementRepository, EstateManagementRepository>();
            services.AddSingleton <IDbContextFactory <EstateReportingContext>, DbContextFactory <EstateReportingContext> >();

            Dictionary <String, String[]> handlerEventTypesToSilentlyHandle = new Dictionary <String, String[]>();

            if (Startup.Configuration != null)
            {
                IConfigurationSection section = Startup.Configuration.GetSection("AppSettings:HandlerEventTypesToSilentlyHandle");

                if (section != null)
                {
                    Startup.Configuration.GetSection("AppSettings:HandlerEventTypesToSilentlyHandle").Bind(handlerEventTypesToSilentlyHandle);
                }
            }

            services.AddSingleton <Func <String, EstateReportingContext> >(cont => (connectionString) => { return(new EstateReportingContext(connectionString)); });

            DomainEventTypesToSilentlyHandle eventTypesToSilentlyHandle = new DomainEventTypesToSilentlyHandle(handlerEventTypesToSilentlyHandle);

            services.AddTransient <IEventStoreContext, EventStoreContext>();
            services.AddSingleton <IAggregateRepository <EstateAggregate.EstateAggregate, DomainEventRecord.DomainEvent>, AggregateRepository <EstateAggregate.EstateAggregate, DomainEventRecord.DomainEvent> >();
            services.AddSingleton <IAggregateRepository <MerchantAggregate.MerchantAggregate, DomainEventRecord.DomainEvent>, AggregateRepository <MerchantAggregate.MerchantAggregate, DomainEventRecord.DomainEvent> >();
            services.AddSingleton <IAggregateRepository <ContractAggregate.ContractAggregate, DomainEventRecord.DomainEvent>, AggregateRepository <ContractAggregate.ContractAggregate, DomainEventRecord.DomainEvent> >();
            services.AddSingleton <IEstateDomainService, EstateDomainService>();
            services.AddSingleton <IMerchantDomainService, MerchantDomainService>();
            services.AddSingleton <IContractDomainService, ContractDomainService>();
            services.AddSingleton <IModelFactory, ModelFactory>();
            services.AddSingleton <Factories.IModelFactory, Factories.ModelFactory>();
            services.AddSingleton <ISecurityServiceClient, SecurityServiceClient>();

            ContractCreatedEvent c = new ContractCreatedEvent(Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid(), "");
            MerchantCreatedEvent m = new MerchantCreatedEvent(Guid.NewGuid(), Guid.NewGuid(), "", DateTime.Now);
            EstateCreatedEvent   e = new EstateCreatedEvent(Guid.NewGuid(), "");

            TypeProvider.LoadDomainEventsTypeDynamically();

            // request & notification handlers
            services.AddTransient <ServiceFactory>(context =>
            {
                return(t => context.GetService(t));
            });

            services.AddSingleton <IRequestHandler <CreateEstateRequest, String>, EstateRequestHandler>();
            services.AddSingleton <IRequestHandler <CreateEstateUserRequest, Guid>, EstateRequestHandler>();
            services.AddSingleton <IRequestHandler <AddOperatorToEstateRequest, String>, EstateRequestHandler>();

            services.AddSingleton <IRequestHandler <CreateMerchantRequest, String>, MerchantRequestHandler>();
            services.AddSingleton <IRequestHandler <AssignOperatorToMerchantRequest, String>, MerchantRequestHandler>();
            services.AddSingleton <IRequestHandler <CreateMerchantUserRequest, Guid>, MerchantRequestHandler>();
            services.AddSingleton <IRequestHandler <AddMerchantDeviceRequest, String>, MerchantRequestHandler>();
            services.AddSingleton <IRequestHandler <MakeMerchantDepositRequest, Guid>, MerchantRequestHandler>();

            services.AddSingleton <IRequestHandler <CreateContractRequest, String>, ContractRequestHandler>();
            services.AddSingleton <IRequestHandler <AddProductToContractRequest, String>, ContractRequestHandler>();
            services.AddSingleton <IRequestHandler <AddTransactionFeeForProductToContractRequest, String>, ContractRequestHandler>();

            services.AddSingleton <Func <String, String> >(container => (serviceName) =>
            {
                return(ConfigurationReader.GetBaseServerUri(serviceName).OriginalString);
            });

            HttpClientHandler httpClientHandler = new HttpClientHandler
            {
                ServerCertificateCustomValidationCallback = (message,
                                                             certificate2,
                                                             arg3,
                                                             arg4) =>
                {
                    return(true);
                }
            };
            HttpClient httpClient = new HttpClient(httpClientHandler);

            services.AddSingleton <HttpClient>(httpClient);
        }