public void Cfg_Valid_AppConfig_ByNameByLoader()
        {
            // arrange
            string fileName  = GetCfgFileName(@"/app.config");
            string cacheName = "C1";

            // act
            var cfg   = ConfigurationBuilder.LoadConfigurationFile(fileName, cacheName);
            var cache = CacheFactory.FromConfiguration <object>(cfg);

            // assert
            cache.Configuration.CacheUpdateMode.Should().Be(CacheUpdateMode.Up);
            cache.CacheHandles.Count().Should().Be(3);
            AssertCacheHandleConfig(cache.CacheHandles.ElementAt(0), "h1", ExpirationMode.None, new TimeSpan(0, 0, 50));
            AssertCacheHandleConfig(cache.CacheHandles.ElementAt(1), "h2", ExpirationMode.Absolute, new TimeSpan(0, 20, 0));
            AssertCacheHandleConfig(cache.CacheHandles.ElementAt(2), "h3", ExpirationMode.Sliding, new TimeSpan(20, 0, 0));
        }
Exemplo n.º 2
0
        static void Test2(ICacheManagerConfiguration configuration)
        {
            var cache = CacheFactory.FromConfiguration <object>(cacheName2, configuration);

            dictionary.Add(cacheName2, cache);
            cache.Add("keyC", "valueC");
            cache.Put("keyD", 23);
            cache.Update("keyC", v => 24);

            Console.WriteLine("KeyC is " + cache.Get("keyC")); // should be valueC
            Console.WriteLine("KeyD is " + cache.Get("keyD")); // should be 24
            cache.Remove("keyC");

            Console.WriteLine("KeyC removed? " + (cache.Get("keyC") == null).ToString());

            Console.WriteLine("We are done Test2 ...");
        }
Exemplo n.º 3
0
        static void Test1(ICacheManagerConfiguration configuration)
        {
            var cache = CacheFactory.FromConfiguration <object>(cacheName1, configuration);

            dictionary.Add(cacheName1, cache);
            cache.Add("keyA", "valueA");
            cache.Put("keyB", 23);
            cache.Update("keyB", v => 42);

            Console.WriteLine("KeyA is " + cache.Get("keyA")); // should be valueA
            Console.WriteLine("KeyB is " + cache.Get("keyB")); // should be 42
            cache.Remove("keyA");

            Console.WriteLine("KeyA removed? " + (cache.Get("keyA") == null).ToString());

            Console.WriteLine("We are done Test1 ...");
        }
Exemplo n.º 4
0
        public async Task Memcached_RaceCondition_WithoutCasHandling()
        {
            // arrange
            using (var cache = CacheFactory.FromConfiguration <RaceConditionTestElement>(
                       TestManagers.BaseConfiguration.Builder
                       .WithUpdateMode(CacheUpdateMode.Up)
                       .WithMemcachedCacheHandle(Configuration)
                       .WithExpiration(ExpirationMode.Absolute, TimeSpan.FromMinutes(20))
                       .Build()))
            {
                var key = Guid.NewGuid().ToString();
                cache.Remove(key);
                cache.Add(key, new RaceConditionTestElement()
                {
                    Counter = 0
                });
                int numThreads         = 5;
                int iterations         = 10;
                int numInnerIterations = 10;

                // act
                await ThreadTestHelper.RunAsync(
                    async() =>
                {
                    for (int i = 0; i < numInnerIterations; i++)
                    {
                        var val = cache.Get(key);
                        val.Should().NotBeNull();
                        val.Counter++;

                        cache.Put(key, val);
                    }

                    await Task.Delay(10);
                },
                    numThreads,
                    iterations);

                // assert
                var result = cache.Get(key);
                result.Should().NotBeNull();
                Trace.TraceInformation("Counter increased to " + result.Counter);
                result.Counter.Should().NotBe(numThreads * numInnerIterations * iterations);
            }
        }
Exemplo n.º 5
0
        public void Cfg_Valid_CfgFile_ExpirationVariances()
        {
            // arrange
            string fileName  = GetCfgFileName(@"/Configuration/configuration.valid.allFeatures.config");
            string cacheName = "ExpirationVariances";

            // act
            var cfg   = ConfigurationBuilder.LoadConfigurationFile(fileName, cacheName);
            var cache = CacheFactory.FromConfiguration <object>(cfg);

            // assert
            cache.Configuration.UpdateMode.Should().Be(CacheUpdateMode.Full);
            cache.CacheHandles.Count().Should().Be(4);
            AssertCacheHandleConfig(cache.CacheHandles.ElementAt(0), "h1", ExpirationMode.None, new TimeSpan(0, 0, 50));
            AssertCacheHandleConfig(cache.CacheHandles.ElementAt(1), "h2", ExpirationMode.Sliding, new TimeSpan(0, 5, 0));
            AssertCacheHandleConfig(cache.CacheHandles.ElementAt(2), "h3", ExpirationMode.None, new TimeSpan(0, 0, 0));
            AssertCacheHandleConfig(cache.CacheHandles.ElementAt(3), "h4", ExpirationMode.Absolute, new TimeSpan(0, 20, 0));
        }
Exemplo n.º 6
0
        public void Redis_LoadWithRedisBackplane_FromAppConfigConnectionStrings()
        {
            // RedisConfigurations should load this from AppSettings from app.config
            // arrange
            string cacheName = "redisWithBackplaneAppConfigConnectionStrings";

            // act
            var cfg    = ConfigurationBuilder.LoadConfiguration(cacheName);
            var cache  = CacheFactory.FromConfiguration <object>(cfg);
            var handle = cache.CacheHandles.First(p => p.Configuration.IsBackplaneSource) as RedisCacheHandle <object>;

            // test running something on the redis handle, Count should be enough to test the connection
            Action count = () => { var x = handle.Count; };

            // assert
            handle.Should().NotBeNull();
            count.ShouldNotThrow();
        }
Exemplo n.º 7
0
        /// <summary>
        /// 获取CacheManager实例
        /// </summary>
        /// <typeparam name="TCacheValue">缓存值的类型</typeparam>
        /// <param name="cacheName">缓存配置名称<see cref="CacheConfigNames"/>(默认使用内存缓存<see cref="CacheConfigNames.runtimeMemoryCache"/>)</param>
        /// <returns></returns>
        private static ICacheManager <TCacheValue> CacheManagerInstance <TCacheValue>(string cacheName)
        {
            cacheName = cacheName ?? CacheConfigNames.runtimeMemoryCache;
            string instanceName = GetCacheInstanceName(cacheName, typeof(TCacheValue));

            if (!_cacheManagers.ContainsKey(instanceName))
            {
                lock (Locker)
                {
                    if (!_cacheManagers.ContainsKey(instanceName))
                    {
                        var cfg = GetCacheManagerConfig(cacheName);
                        _cacheManagers[instanceName] = CacheFactory.FromConfiguration <TCacheValue>(instanceName, cfg);
                    }
                }
            }
            return(_cacheManagers[instanceName] as ICacheManager <TCacheValue>);
        }
        public static ICacheManager <object> CreateRedisAndDicCacheWithBackplane(int database = 0, bool sharedRedisConfig = true, string channelName = null, Serializer serializer = Serializer.Proto, bool useLua = true)
        {
            var redisKey = sharedRedisConfig ? "redisConfig" + database : Guid.NewGuid().ToString();

            var builder = BaseConfiguration.Builder;

            builder.WithUpdateMode(CacheUpdateMode.Up)
            .WithDictionaryHandle()
            .EnableStatistics()
            .And
            .WithMaxRetries(int.MaxValue)
            .TestSerializer(serializer)
            .WithRetryTimeout(1000)
            .WithRedisConfiguration(redisKey, config =>
            {
                config
                .WithAllowAdmin()
                .WithDatabase(database)
                .WithEndpoint(RedisHost, RedisPort);

                if (!useLua)
                {
                    config.UseCompatibilityMode("2.4");
                }
            })
            .WithRedisCacheHandle(redisKey, true)
            .EnableStatistics();

            if (channelName != null)
            {
                builder.WithRedisBackplane(redisKey, channelName);
            }
            else
            {
                builder.WithRedisBackplane(redisKey);
            }

            var cache = CacheFactory.FromConfiguration <object>(
                $"{database}|{sharedRedisConfig}|{serializer}|{useLua}" + Guid.NewGuid().ToString(),
                builder.Build());

            return(cache);
        }
Exemplo n.º 9
0
        public void Memcached_Update_ItemNotAdded()
        {
            // arrange
            using (var cache = CacheFactory.FromConfiguration <RaceConditionTestElement>(
                       TestManagers.BaseConfiguration.Builder
                       .WithUpdateMode(CacheUpdateMode.Up)
                       .WithMemcachedCacheHandle(Configuration)
                       .WithExpiration(ExpirationMode.Absolute, TimeSpan.FromMinutes(20))
                       .Build()))
            {
                RaceConditionTestElement value;

                // act
                Func <bool> act = () => cache.TryUpdate(Guid.NewGuid().ToString(), item => item, out value);

                // assert
                act().Should().BeFalse("Item has not been added to the cache");
            }
        }
Exemplo n.º 10
0
        ////[Trait("category", "Unreliable")]
        public void Redis_Multiple_PubSub_Change()
        {
            // arrange
            string fileName    = BaseCacheManagerTest.GetCfgFileName(@"/Configuration/configuration.valid.allFeatures.config");
            var    channelName = Guid.NewGuid().ToString();

            // redis config name must be same for all cache handles, configured via file and via code
            // otherwise the pub sub channel name is different
            string cacheName = "redisConfig";

            RedisConfigurations.LoadConfiguration(fileName, RedisConfigurationSection.DefaultSectionName);

            var cfg = ConfigurationBuilder.LoadConfigurationFile(fileName, cacheName);

            cfg.BackPlateChannelName = channelName;

            var cfgCache = CacheFactory.FromConfiguration <object>(cfg);

            var item = new CacheItem <object>(Guid.NewGuid().ToString(), "something");

            // act/assert
            RedisTests.RunMultipleCaches(
                (cacheA, cacheB) =>
            {
                cacheA.Put(item);
                Thread.Sleep(10);
                var value = cacheB.Get(item.Key);
                value.Should().Be(item.Value, cacheB.ToString());
                cacheB.Put(item.Key, "new value");
            },
                (cache) =>
            {
                Thread.Sleep(12);
                var value = cache.Get(item.Key);
                value.Should().Be("new value", cache.ToString());
            },
                2,
                TestManagers.CreateRedisAndSystemCacheWithBackPlate(69, true, channelName),
                cfgCache,
                TestManagers.CreateRedisCache(69),
                TestManagers.CreateRedisAndSystemCacheWithBackPlate(69, true, channelName));
        }
Exemplo n.º 11
0
        public void Cfg_Valid_CfgFile_AllDefaults()
        {
            // arrange
            string fileName  = GetCfgFileName(@"/Configuration/configuration.valid.allFeatures.config");
            string cacheName = "onlyDefaultsCache";

            // act
            var cfg   = ConfigurationBuilder.LoadConfigurationFile(fileName, cacheName);
            var cache = CacheFactory.FromConfiguration <string>(cfg);

            // assert
            cache.Configuration.UpdateMode.Should().Be(CacheUpdateMode.Up);
            cache.Configuration.SerializerType.Should().BeNull();
            cache.Configuration.LoggerFactoryType.Should().BeNull();
            cache.Configuration.BackplaneType.Should().BeNull();
            cache.Configuration.RetryTimeout.Should().Be(100);
            cache.Configuration.MaxRetries.Should().Be(50);
            cache.CacheHandles.Count().Should().Be(1);
            AssertCacheHandleConfig(cache.CacheHandles.ElementAt(0), "defaultsHandle", ExpirationMode.None, TimeSpan.Zero);
        }
Exemplo n.º 12
0
        public void Redis_Valid_CfgFile_LoadWithConnectionString()
        {
            // arrange
            string fileName  = BaseCacheManagerTest.GetCfgFileName(@"/Configuration/configuration.valid.allFeatures.config");
            string cacheName = "redisConfigFromConnectionString";

            // have to load the configuration manually because the file is not avialbale to the default ConfigurtaionManager
            RedisConfigurations.LoadConfiguration(fileName, RedisConfigurationSection.DefaultSectionName);
            var redisConfig = RedisConfigurations.GetConfiguration("redisConnectionString");

            // act
            var cfg   = ConfigurationBuilder.LoadConfigurationFile(fileName, cacheName);
            var cache = CacheFactory.FromConfiguration <object>(cfg);

            // assert
            cache.CacheHandles.Any(p => p.Configuration.IsBackplaneSource).Should().BeTrue();

            // database is the only option apart from key and connection string which must be set, database will not be set through connection string
            // to define which database should actually be used...
            redisConfig.Database.Should().Be(131);
        }
Exemplo n.º 13
0
        private static void UnityInjectionExample()
        {
            UnityContainer container = new UnityContainer();

            container.RegisterType <ICacheManager <object> >(
                new ContainerControlledLifetimeManager(),
                new InjectionFactory((c) => CacheFactory.FromConfiguration <object>("myCache")));

            container.RegisterType <UnityInjectionExampleTarget>();

            // resolving the test target object should also resolve the cache instance
            var target = container.Resolve <UnityInjectionExampleTarget>();

            target.PutSomethingIntoTheCache();

            // our cache manager instance should still be there so should the object we added in the
            // previous step.
            var checkTarget = container.Resolve <UnityInjectionExampleTarget>();

            checkTarget.GetSomething();
        }
Exemplo n.º 14
0
        public void Redis_Valid_CfgFile_LoadWithRedisBackplane()
        {
            // arrange
            string fileName  = BaseCacheManagerTest.GetCfgFileName(@"/Configuration/configuration.valid.allFeatures.config");
            string cacheName = "redisConfigFromConfig";

            // have to load the configuration manually because the file is not avialbale to the default ConfigurtaionManager
            RedisConfigurations.LoadConfiguration(fileName, RedisConfigurationSection.DefaultSectionName);
            var redisConfig = RedisConfigurations.GetConfiguration("redisFromCfgConfigurationId");

            // act
            var cfg   = ConfigurationBuilder.LoadConfigurationFile(fileName, cacheName);
            var cache = CacheFactory.FromConfiguration <object>(cfg);

            // assert
            cache.CacheHandles.Any(p => p.Configuration.IsBackplaneSource).Should().BeTrue();

            redisConfig.Database.Should().Be(113);
            redisConfig.ConnectionTimeout.Should().Be(1200);
            redisConfig.AllowAdmin.Should().BeTrue();
        }
Exemplo n.º 15
0
        public static void ClassInit(TestContext context)
        {
            container = new UnityContainer();

            var cacheConfig = ConfigurationBuilder.BuildConfiguration(settings =>
            {
                settings
                .WithJsonSerializer()
                .WithSystemRuntimeCacheHandle("inprocess")
                .And
                .WithRedisConfiguration("redisLocal", "localhost:6379,ssl=false,allowAdmin=true")
                .WithRedisBackPlate("redisLocal")
                .WithRedisCacheHandle("redisLocal", true);
            });

            container.RegisterType(
                typeof(ICacheManager <>),
                new ContainerControlledLifetimeManager(),
                new InjectionFactory(
                    (c, t, n) => CacheFactory.FromConfiguration(t.GetGenericArguments()[0], cacheConfig)));
        }
        public static ICacheManager <T> CreateRedisCache <T>(int database = 0, bool sharedRedisConfig = true, Serializer serializer = Serializer.GzJson)
        {
            var redisKey = sharedRedisConfig ? "redisConfig" + database : Guid.NewGuid().ToString();
            var cache    = CacheFactory.FromConfiguration <T>(
                BaseConfiguration.Builder
                .TestSerializer(serializer)
                .WithMaxRetries(int.MaxValue)
                .WithRetryTimeout(1000)
                .WithRedisConfiguration(redisKey, config =>
            {
                config
                .WithDatabase(database)
                .WithEndpoint(RedisHost, RedisPort);
            })
                .WithRedisBackplane(redisKey)
                .WithRedisCacheHandle(redisKey, true)
                .EnableStatistics()
                .Build());

            return(cache);
        }
Exemplo n.º 17
0
        public void Cfg_Valid_CfgFile_DefaultSysMemCache()
        {
            // arrange
            string fileName  = GetCfgFileName(@"/Configuration/configuration.valid.allFeatures.config");
            string cacheName = "DefaultSysMemCache";

            // act
            var cfg   = ConfigurationBuilder.LoadConfigurationFile(fileName, cacheName);
            var cache = CacheFactory.FromConfiguration <object>(cfg);

            var memHandle = cache.CacheHandles.ElementAt(0) as MemoryCacheHandle <object>;

            memHandle.CacheSettings.Get(0).Should().Be("42");
            memHandle.CacheSettings.Get(1).Should().Be("69");
            memHandle.CacheSettings.Get(2).Should().Be("00:10:00");

            // assert
            cache.Configuration.UpdateMode.Should().Be(CacheUpdateMode.None);
            cache.CacheHandles.Count().Should().Be(1);
            AssertCacheHandleConfig(cache.CacheHandles.ElementAt(0), "default", ExpirationMode.Sliding, new TimeSpan(0, 5, 0));
        }
Exemplo n.º 18
0
        private static void SimpleCustomBuildConfigurationUsingConfigBuilder()
        {
            // this is using the CacheManager.Core.Configuration.ConfigurationBuilder to build a
            // custom config you can do the same with the CacheFactory
            var cfg = ConfigurationBuilder.BuildConfiguration(settings =>
            {
                settings.WithUpdateMode(CacheUpdateMode.Up)
                .WithDictionaryHandle()
                .EnablePerformanceCounters()
                .WithExpiration(ExpirationMode.Sliding, TimeSpan.FromSeconds(10));
            });

            var cache = CacheFactory.FromConfiguration <string>(cfg);

            cache.Add("key", "value");

            // reusing the configuration and using the same cache for different types:
            var numbers = CacheFactory.FromConfiguration <int>(cfg);

            numbers.Add("intKey", 2323);
            numbers.Update("intKey", v => v + 1);
        }
Exemplo n.º 19
0
        static ICacheManager <TValue> GetCacheManager <TValue>()
        {
            var configuration = new ConfigurationBuilder()
                                .WithJsonSerializer()//todo cuizj: 使用 System.Text.Json.JsonSerializer
                                .WithMicrosoftMemoryCacheHandle("memory")
                                .And
                                .WithRedisConfiguration(ConfigKey, builder =>
                                                        builder.WithAllowAdmin().WithDatabase(0).WithEndpoint("127.0.0.1", 7000)
                                                        .EnableKeyspaceEvents())//需要开启 redis notify-keyspace-events "Exe"
                                .WithMaxRetries(50)
                                .WithRetryTimeout(50)
                                .WithRedisBackplane(ConfigKey)//启用二级缓存同步
                                .WithRedisCacheHandle(ConfigKey, true)
                                .And
                                .WithMicrosoftLogging(LoggerFactory.Create(builder =>
                                                                           builder.AddSimpleConsole().SetMinimumLevel(LogLevel.Information)))
                                .Build();

            var cacheManager = CacheFactory.FromConfiguration <TValue>(configuration);

            return(cacheManager);
        }
Exemplo n.º 20
0
        protected void Application_Start()
        {
            var container = new UnityContainer();

            GlobalConfiguration.Configure(WebApiConfig.Register);
            GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);

            var cacheConfig = ConfigurationBuilder.BuildConfiguration(settings =>
            {
                settings
                .WithSystemRuntimeCacheHandle("inprocess");
                ////.WithExpiration(ExpirationMode.Absolute, TimeSpan.FromMinutes(10));
                ////settings.WithRedisBackPlate("redisConnection");
                ////settings.WithRedisCacheHandle("redisConnection", true);
            });

            container.RegisterType(
                typeof(ICacheManager <>),
                new ContainerControlledLifetimeManager(),
                new InjectionFactory(
                    (c, t, n) => CacheFactory.FromConfiguration(t.GetGenericArguments()[0], cacheConfig)));
        }
Exemplo n.º 21
0
        public void Refresh()
        {
            if (DataConfigHelper.CacheConfigLoader != null)
            {
                DataConfigHelper.CacheConfigLoader.Reload();
            }

            Dictionary <string, ICacheManager <object> > mgrs = new Dictionary <string, ICacheManager <object> >();

            CacheManagerSection section = ConfigurationManager.GetSection(CACHE_SECTION_NAME) as CacheManagerSection;

            if (section != null && section.CacheManagers != null)
            {
                foreach (var item in section.CacheManagers)
                {
                    ICacheManagerConfiguration cfg = null;
                    if (DataConfigHelper.CacheConfigLoader != null)
                    {
                        cfg = DataConfigHelper.CacheConfigLoader.GetCacheConfig(item.Name);
                    }

                    if (mgrs.ContainsKey(item.Name))
                    {
                        mgrs.Remove(item.Name);
                    }

                    var cache = cfg == null?CacheFactory.FromConfiguration <object>(item.Name)
                                    : CacheFactory.FromConfiguration <object>(item.Name, cfg);

                    if (cache != null)
                    {
                        mgrs.Add(item.Name, cache);
                    }
                }
            }

            m_Mgrs = mgrs; // thread-safe (reads and writes of reference types are atomic)
        }
Exemplo n.º 22
0
        public ISeadQueryCache Create(string hostname, int port)
        {
            var cache = CacheFactory.FromConfiguration <object>(ConfigurationBuilder.BuildConfiguration(settings =>
            {
                settings
                .WithJsonSerializer()
                .WithRedisConfiguration("redis", config =>
                {
                    config.WithAllowAdmin()
                    .WithDatabase(0)
                    .WithConnectionTimeout(3000)
                    .WithEndpoint(hostname, port);
                })
                .WithMaxRetries(3)
                .WithRetryTimeout(100)
                .WithRedisBackplane("redis")
                .WithRedisCacheHandle("redis", true);
            }));

            var manager = new SeadQueryCache(cache);

            return(manager);
        }
Exemplo n.º 23
0
        public static IHummingbirdHostBuilder AddCache(this IHummingbirdHostBuilder hostBuilder, Action <IHummingbirdCacheConfig> setupOption = null)
        {
            var config = new HummingbirdCacheConfig();

            if (setupOption != null)
            {
                setupOption(config);
            }
            hostBuilder.Services.AddSingleton(typeof(IHummingbirdCacheConfig), config);
            hostBuilder.Services.AddSingleton(typeof(ICacheManager <object>), sp =>
            {
                var Configuration      = sp.GetRequiredService <IConfiguration>();
                var cacheConfiguration = Configuration.GetCacheConfiguration(config.ConfigName).Builder.Build();
                var cacheManager       = CacheFactory.FromConfiguration <object>(config.ConfigName, cacheConfiguration);



                return(cacheManager);
            });
            hostBuilder.Services.AddSingleton(typeof(IHummingbirdCache <object>), typeof(HummingbirdCacheManagerCache <object>));
            hostBuilder.Services.AddSingleton(typeof(IHummingbirdCache <>), typeof(HummingbirdCacheManagerCache <>));
            return(hostBuilder);
        }
Exemplo n.º 24
0
        private static void AppConfigLoadInstalledCacheCfg()
        {
            var cache = CacheFactory.FromConfiguration <object>("myCache");

            cache.Add("key", "value");
        }
Exemplo n.º 25
0
        private static void InitializePlatform(
            IAppBuilder app,
            IUnityContainer container,
            IPathMapper pathMapper,
            string connectionString,
            HangfireLauncher hangfireLauncher,
            string modulesPath,
            ModuleInitializerOptions moduleInitializerOptions)
        {
            container.RegisterType <ICurrentUser, CurrentUser>(new HttpContextLifetimeManager());
            container.RegisterType <IUserNameResolver, UserNameResolver>();

            #region Setup database

            using (var db = new SecurityDbContext(connectionString))
            {
                new IdentityDatabaseInitializer().InitializeDatabase(db);
            }

            using (var context = new PlatformRepository(connectionString, container.Resolve <AuditableInterceptor>(), new EntityPrimaryKeyGeneratorInterceptor()))
            {
                new PlatformDatabaseInitializer().InitializeDatabase(context);
            }

            hangfireLauncher.ConfigureDatabase();

            #endregion

            Func <IPlatformRepository> platformRepositoryFactory = () => new PlatformRepository(connectionString, container.Resolve <AuditableInterceptor>(), new EntityPrimaryKeyGeneratorInterceptor());
            container.RegisterType <IPlatformRepository>(new InjectionFactory(c => platformRepositoryFactory()));
            container.RegisterInstance(platformRepositoryFactory);
            var moduleCatalog = container.Resolve <IModuleCatalog>();

            #region Caching

            //Cure for System.Runtime.Caching.MemoryCache freezing
            //https://www.zpqrtbnk.net/posts/appdomains-threads-cultureinfos-and-paracetamol
            app.SanitizeThreadCulture();
            ICacheManager <object> cacheManager = null;

            var redisConnectionString = ConfigurationHelper.GetConnectionStringValue("RedisConnectionString");

            //Try to load cache configuration from web.config first
            //Should be aware to using Web cache cache handle because it not worked in native threads. (Hangfire jobs)
            if (ConfigurationManager.GetSection(CacheManagerSection.DefaultSectionName) is CacheManagerSection cacheManagerSection)
            {
                CacheManagerConfiguration configuration = null;

                var defaultCacheManager = cacheManagerSection.CacheManagers.FirstOrDefault(p => p.Name.EqualsInvariant("platformCache"));
                if (defaultCacheManager != null)
                {
                    configuration = ConfigurationBuilder.LoadConfiguration(defaultCacheManager.Name);
                }

                var redisCacheManager = cacheManagerSection.CacheManagers.FirstOrDefault(p => p.Name.EqualsInvariant("redisPlatformCache"));
                if (redisConnectionString != null && redisCacheManager != null)
                {
                    configuration = ConfigurationBuilder.LoadConfiguration(redisCacheManager.Name);
                }

                if (configuration != null)
                {
                    configuration.LoggerFactoryType          = typeof(CacheManagerLoggerFactory);
                    configuration.LoggerFactoryTypeArguments = new object[] { container.Resolve <ILog>() };
                    cacheManager = CacheFactory.FromConfiguration <object>(configuration);
                }
            }

            // Create a default cache manager if there is no any others
            if (cacheManager == null)
            {
                cacheManager = CacheFactory.Build("platformCache", settings =>
                {
                    settings.WithUpdateMode(CacheUpdateMode.Up)
                    .WithSystemRuntimeCacheHandle("memCacheHandle")
                    .WithExpiration(ExpirationMode.Sliding, TimeSpan.FromMinutes(5));
                });
            }

            container.RegisterInstance(cacheManager);

            #endregion

            #region Settings

            var platformModuleManifest = new ModuleManifest
            {
                Id              = "VirtoCommerce.Platform",
                Version         = PlatformVersion.CurrentVersion.ToString(),
                PlatformVersion = PlatformVersion.CurrentVersion.ToString(),
                Settings        = new[]
                {
                    new ModuleSettingsGroup
                    {
                        Name     = "Platform|Notifications|SendGrid",
                        Settings = new []
                        {
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SendGrid.ApiKey",
                                ValueType   = ModuleSetting.TypeSecureString,
                                Title       = "SendGrid API key",
                                Description = "Your SendGrid API key"
                            }
                        }
                    },
                    new ModuleSettingsGroup
                    {
                        Name     = "Platform|Notifications|SendingJob",
                        Settings = new []
                        {
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SendingJob.TakeCount",
                                ValueType   = ModuleSetting.TypeInteger,
                                Title       = "Job Take Count",
                                Description = "Take count for sending job"
                            }
                        }
                    },
                    new ModuleSettingsGroup
                    {
                        Name     = "Platform|Notifications|SmtpClient",
                        Settings = new []
                        {
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SmptClient.Host",
                                ValueType   = ModuleSetting.TypeString,
                                Title       = "Smtp server host",
                                Description = "Smtp server host"
                            },
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SmptClient.Port",
                                ValueType   = ModuleSetting.TypeInteger,
                                Title       = "Smtp server port",
                                Description = "Smtp server port"
                            },
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SmptClient.Login",
                                ValueType   = ModuleSetting.TypeString,
                                Title       = "Smtp server login",
                                Description = "Smtp server login"
                            },
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SmptClient.Password",
                                ValueType   = ModuleSetting.TypeSecureString,
                                Title       = "Smtp server password",
                                Description = "Smtp server password"
                            },
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SmptClient.UseSsl",
                                ValueType   = ModuleSetting.TypeBoolean,
                                Title       = "Use SSL",
                                Description = "Use secure connection"
                            },
                        }
                    },
                    new ModuleSettingsGroup
                    {
                        Name     = "Platform|Security",
                        Settings = new []
                        {
                            new ModuleSetting
                            {
                                Name         = "VirtoCommerce.Platform.Security.AccountTypes",
                                ValueType    = ModuleSetting.TypeString,
                                Title        = "Account types",
                                Description  = "Dictionary for possible account types",
                                IsArray      = true,
                                ArrayValues  = Enum.GetNames(typeof(AccountType)),
                                DefaultValue = AccountType.Manager.ToString()
                            }
                        }
                    },
                    new ModuleSettingsGroup
                    {
                        Name     = "Platform|User Profile",
                        Settings = new[]
                        {
                            new ModuleSetting
                            {
                                Name      = "VirtoCommerce.Platform.UI.MainMenu.State",
                                ValueType = ModuleSetting.TypeJson,
                                Title     = "Persisted state of main menu"
                            },
                            new ModuleSetting
                            {
                                Name         = "VirtoCommerce.Platform.UI.Language",
                                ValueType    = ModuleSetting.TypeString,
                                Title        = "Language",
                                Description  = "Default language (two letter code from ISO 639-1, case-insensitive). Example: en, de",
                                DefaultValue = "en"
                            },
                            new ModuleSetting
                            {
                                Name         = "VirtoCommerce.Platform.UI.RegionalFormat",
                                ValueType    = ModuleSetting.TypeString,
                                Title        = "Regional format",
                                Description  = "Default regional format (CLDR locale code, with dash or underscore as delemiter, case-insensitive). Example: en, en_US, sr_Cyrl, sr_Cyrl_RS",
                                DefaultValue = "en"
                            },
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.UI.TimeZone",
                                ValueType   = ModuleSetting.TypeString,
                                Title       = "Time zone",
                                Description = "Default time zone (IANA time zone name [tz database], exactly as in database, case-sensitive). Examples: America/New_York, Europe/Moscow"
                            },
                            new ModuleSetting
                            {
                                Name         = "VirtoCommerce.Platform.UI.ShowMeridian",
                                ValueType    = ModuleSetting.TypeBoolean,
                                Title        = "Meridian labels based on user preferences",
                                Description  = "When set to true (by default), system will display time in format like '12 hour format' when possible",
                                DefaultValue = true.ToString()
                            },
                            new ModuleSetting
                            {
                                Name         = "VirtoCommerce.Platform.UI.UseTimeAgo",
                                ValueType    = ModuleSetting.TypeBoolean,
                                Title        = "Use time ago format when is possible",
                                Description  = "When set to true (by default), system will display date in format like 'a few seconds ago' when possible",
                                DefaultValue = true.ToString()
                            },
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.UI.FullDateThreshold",
                                ValueType   = ModuleSetting.TypeInteger,
                                Title       = "Full date threshold",
                                Description = "Number of units after time ago format will be switched to full date format"
                            },
                            new ModuleSetting
                            {
                                Name          = "VirtoCommerce.Platform.UI.FullDateThresholdUnit",
                                ValueType     = ModuleSetting.TypeString,
                                Title         = "Full date threshold unit",
                                Description   = "Unit of full date threshold",
                                DefaultValue  = "Never",
                                AllowedValues = new[]
                                {
                                    "Never",
                                    "Seconds",
                                    "Minutes",
                                    "Hours",
                                    "Days",
                                    "Weeks",
                                    "Months",
                                    "Quarters",
                                    "Years"
                                }
                            },
                            new ModuleSetting
                            {
                                Name         = "VirtoCommerce.Platform.UI.FourDecimalsInMoney",
                                ValueType    = ModuleSetting.TypeBoolean,
                                Title        = "Show 4 decimal digits for money",
                                Description  = "Set to true to show 4 decimal digits for money. By default - false, 2 decimal digits are shown.",
                                DefaultValue = "false",
                            },
                        }
                    },
                    new ModuleSettingsGroup
                    {
                        Name     = "Platform|User Interface",
                        Settings = new[]
                        {
                            new ModuleSetting
                            {
                                Name         = "VirtoCommerce.Platform.UI.Customization",
                                ValueType    = ModuleSetting.TypeJson,
                                Title        = "Customization",
                                Description  = "JSON contains personalization settings of manager UI",
                                DefaultValue = "{\n" +
                                               "  \"title\": \"Virto Commerce\",\n" +
                                               "  \"logo\": \"Content/themes/main/images/logo.png\",\n" +
                                               "  \"contrast_logo\": \"Content/themes/main/images/contrast-logo.png\",\n" +
                                               "  \"favicon\": \"favicon.ico\"\n" +
                                               "}"
                            }
                        }
                    }
                }
            };

            var settingsManager = new SettingsManager(moduleCatalog, platformRepositoryFactory, cacheManager, new[] { new ManifestModuleInfo(platformModuleManifest) });
            container.RegisterInstance <ISettingsManager>(settingsManager);

            #endregion

            #region Dynamic Properties

            container.RegisterType <IDynamicPropertyService, DynamicPropertyService>(new ContainerControlledLifetimeManager());

            #endregion

            #region Notifications

            // Redis
            if (!string.IsNullOrEmpty(redisConnectionString))
            {
                // Cache
                RedisConfigurations.AddConfiguration(new RedisConfiguration("redisConnectionString", redisConnectionString));

                // SignalR
                // https://stackoverflow.com/questions/29885470/signalr-scaleout-on-azure-rediscache-connection-issues
                GlobalHost.DependencyResolver.UseRedis(new RedisScaleoutConfiguration(redisConnectionString, "VirtoCommerce.Platform.SignalR"));
            }

            // SignalR
            var tempCounterManager = new TempPerformanceCounterManager();
            GlobalHost.DependencyResolver.Register(typeof(IPerformanceCounterManager), () => tempCounterManager);
            var hubConfiguration = new HubConfiguration {
                EnableJavaScriptProxies = false
            };
            app.MapSignalR("/" + moduleInitializerOptions.RoutePrefix + "signalr", hubConfiguration);

            var hubSignalR = GlobalHost.ConnectionManager.GetHubContext <ClientPushHub>();
            var notifier   = new InMemoryPushNotificationManager(hubSignalR);
            container.RegisterInstance <IPushNotificationManager>(notifier);

            var resolver = new LiquidNotificationTemplateResolver();
            container.RegisterInstance <INotificationTemplateResolver>(resolver);

            var notificationTemplateService = new NotificationTemplateServiceImpl(platformRepositoryFactory);
            container.RegisterInstance <INotificationTemplateService>(notificationTemplateService);

            var notificationManager = new NotificationManager(resolver, platformRepositoryFactory, notificationTemplateService);
            container.RegisterInstance <INotificationManager>(notificationManager);

            IEmailNotificationSendingGateway emailNotificationSendingGateway = null;

            var emailNotificationSendingGatewayName = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:Gateway", "Default");

            if (string.Equals(emailNotificationSendingGatewayName, "Default", StringComparison.OrdinalIgnoreCase))
            {
                emailNotificationSendingGateway = new DefaultSmtpEmailNotificationSendingGateway(settingsManager);
            }
            else if (string.Equals(emailNotificationSendingGatewayName, "SendGrid", StringComparison.OrdinalIgnoreCase))
            {
                emailNotificationSendingGateway = new SendGridEmailNotificationSendingGateway(settingsManager);
            }

            if (emailNotificationSendingGateway != null)
            {
                container.RegisterInstance(emailNotificationSendingGateway);
            }

            ISmsNotificationSendingGateway smsNotificationSendingGateway = null;
            var smsNotificationSendingGatewayName = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway", "Default");

            if (smsNotificationSendingGatewayName.EqualsInvariant("Default"))
            {
                smsNotificationSendingGateway = new DefaultSmsNotificationSendingGateway();
            }
            else if (smsNotificationSendingGatewayName.EqualsInvariant("Twilio"))
            {
                smsNotificationSendingGateway = new TwilioSmsNotificationSendingGateway(new TwilioSmsGatewayOptions
                {
                    AccountId       = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:AccountId"),
                    AccountPassword = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:AccountPassword"),
                    Sender          = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:Sender"),
                });
            }
            else if (smsNotificationSendingGatewayName.EqualsInvariant("ASPSMS"))
            {
                smsNotificationSendingGateway = new AspsmsSmsNotificationSendingGateway(new AspsmsSmsGatewayOptions
                {
                    AccountId       = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:AccountId"),
                    AccountPassword = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:AccountPassword"),
                    Sender          = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:Sender"),
                    JsonApiUri      = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:Notifications:SmsGateway:ASPSMS:JsonApiUri"),
                });
            }

            if (smsNotificationSendingGateway != null)
            {
                container.RegisterInstance(smsNotificationSendingGateway);
            }

            #endregion

            #region Assets

            var blobConnectionString = BlobConnectionString.Parse(ConfigurationHelper.GetConnectionStringValue("AssetsConnectionString"));

            if (string.Equals(blobConnectionString.Provider, FileSystemBlobProvider.ProviderName, StringComparison.OrdinalIgnoreCase))
            {
                var fileSystemBlobProvider = new FileSystemBlobProvider(NormalizePath(pathMapper, blobConnectionString.RootPath), blobConnectionString.PublicUrl);

                container.RegisterInstance <IBlobStorageProvider>(fileSystemBlobProvider);
                container.RegisterInstance <IBlobUrlResolver>(fileSystemBlobProvider);
            }
            else if (string.Equals(blobConnectionString.Provider, AzureBlobProvider.ProviderName, StringComparison.OrdinalIgnoreCase))
            {
                var azureBlobProvider = new AzureBlobProvider(blobConnectionString.ConnectionString, blobConnectionString.CdnUrl);
                container.RegisterInstance <IBlobStorageProvider>(azureBlobProvider);
                container.RegisterInstance <IBlobUrlResolver>(azureBlobProvider);
            }

            container.RegisterType <IAssetEntryService, AssetEntryService>(new ContainerControlledLifetimeManager());
            container.RegisterType <IAssetEntrySearchService, AssetEntryService>(new ContainerControlledLifetimeManager());

            #endregion

            #region Modularity

            var modulesDataSources    = ConfigurationHelper.SplitAppSettingsStringValue("VirtoCommerce:ModulesDataSources");
            var externalModuleCatalog = new ExternalManifestModuleCatalog(moduleCatalog.Modules, modulesDataSources, container.Resolve <ILog>());
            container.RegisterType <ModulesController>(new InjectionConstructor(externalModuleCatalog, new ModuleInstaller(modulesPath, externalModuleCatalog), notifier, container.Resolve <IUserNameResolver>(), settingsManager));

            #endregion

            #region ChangeLogging

            var changeLogService = new ChangeLogService(platformRepositoryFactory);
            container.RegisterInstance <IChangeLogService>(changeLogService);

            #endregion

            #region Security
            container.RegisterInstance <IPermissionScopeService>(new PermissionScopeService());
            container.RegisterType <IRoleManagementService, RoleManagementService>(new ContainerControlledLifetimeManager());

            var apiAccountProvider = new ApiAccountProvider(platformRepositoryFactory, cacheManager);
            container.RegisterInstance <IApiAccountProvider>(apiAccountProvider);

            container.RegisterType <IClaimsIdentityProvider, ApplicationClaimsIdentityProvider>(new ContainerControlledLifetimeManager());

            container.RegisterInstance(app.GetDataProtectionProvider());
            container.RegisterType <SecurityDbContext>(new InjectionConstructor(connectionString));
            container.RegisterType <IUserStore <ApplicationUser>, ApplicationUserStore>();
            container.RegisterType <IAuthenticationManager>(new InjectionFactory(c => HttpContext.Current.GetOwinContext().Authentication));
            container.RegisterType <ApplicationUserManager>();
            container.RegisterType <ApplicationSignInManager>();

            var nonEditableUsers = ConfigurationHelper.GetAppSettingsValue("VirtoCommerce:NonEditableUsers", string.Empty);
            container.RegisterInstance <ISecurityOptions>(new SecurityOptions(nonEditableUsers));

            container.RegisterType <ISecurityService, SecurityService>();

            container.RegisterType <IPasswordCheckService, PasswordCheckService>();

            #endregion

            #region ExportImport
            container.RegisterType <IPlatformExportImportManager, PlatformExportImportManager>();
            #endregion

            #region Serialization

            container.RegisterType <IExpressionSerializer, XmlExpressionSerializer>();

            #endregion

            #region Events
            var inProcessBus = new InProcessBus();
            container.RegisterInstance <IHandlerRegistrar>(inProcessBus);
            container.RegisterInstance <IEventPublisher>(inProcessBus);

            inProcessBus.RegisterHandler <UserChangedEvent>(async(message, token) => await container.Resolve <LogChangesUserChangedEventHandler>().Handle(message));
            inProcessBus.RegisterHandler <UserPasswordChangedEvent>(async(message, token) => await container.Resolve <LogChangesUserChangedEventHandler>().Handle(message));
            inProcessBus.RegisterHandler <UserResetPasswordEvent>(async(message, token) => await container.Resolve <LogChangesUserChangedEventHandler>().Handle(message));
            #endregion
        }
Exemplo n.º 26
0
        public void Configuration(IAppBuilder app)
        {
            var applicationInsightsKey = Environment.GetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY");

            if (!string.IsNullOrEmpty(applicationInsightsKey))
            {
                TelemetryConfiguration.Active.InstrumentationKey = applicationInsightsKey;
            }

            if (_managerAssembly != null)
            {
                AreaRegistration.RegisterAllAreas();
                CallChildConfigure(app, _managerAssembly, "VirtoCommerce.Platform.Web.Startup", "Configuration", "~/areas/admin", "admin/");
            }

            var appSettings = ConfigurationManager.AppSettings;

            UnityWebActivator.Start();
            var container = UnityConfig.GetConfiguredContainer();

            UnityServiceLocator locator = new UnityServiceLocator(container);

            ServiceLocator.SetLocatorProvider(() => locator);

            //Cure for System.Runtime.Caching.MemoryCache freezing
            //https://www.zpqrtbnk.net/posts/appdomains-threads-cultureinfos-and-paracetamol
            app.SanitizeThreadCulture();
            // Caching configuration
            // Be cautious with SystemWebCacheHandle because it does not work in native threads (Hangfire jobs).
            var localCache        = CacheFactory.FromConfiguration <object>("storefrontCache");
            var localCacheManager = new LocalCacheManager(localCache);

            container.RegisterInstance <ILocalCacheManager>(localCacheManager);

            //Because CacheManagerOutputCacheProvider used diff cache manager instance need translate clear region by this way
            //https://github.com/MichaCo/CacheManager/issues/32
            localCacheManager.OnClearRegion += (sender, region) =>
            {
                try
                {
                    CacheManagerOutputCacheProvider.Cache.ClearRegion(region.Region);
                }
                catch { }
            };
            localCacheManager.OnClear += (sender, args) =>
            {
                try
                {
                    CacheManagerOutputCacheProvider.Cache.Clear();
                }
                catch { }
            };

            var distributedCache = CacheFactory.Build("distributedCache", settings =>
            {
                var jsonSerializerSettings = new JsonSerializerSettings {
                    TypeNameHandling = TypeNameHandling.All
                };
                var redisCacheEnabled = appSettings.GetValue("VirtoCommerce:Storefront:RedisCache:Enabled", false);

                var memoryHandlePart = settings
                                       .WithJsonSerializer(jsonSerializerSettings, jsonSerializerSettings)
                                       .WithUpdateMode(CacheUpdateMode.Up)
                                       .WithSystemRuntimeCacheHandle("memory")
                                       .WithExpiration(ExpirationMode.Absolute, TimeSpan.FromHours(1));

                if (redisCacheEnabled)
                {
                    var redisCacheConnectionStringName = appSettings.GetValue("VirtoCommerce:Storefront:RedisCache:ConnectionStringName", "RedisCache");
                    var redisConnectionString          = ConfigurationManager.ConnectionStrings[redisCacheConnectionStringName].ConnectionString;

                    memoryHandlePart
                    .And
                    .WithRedisConfiguration("redis", redisConnectionString)
                    .WithRetryTimeout(100)
                    .WithMaxRetries(1000)
                    .WithRedisBackplane("redis")
                    .WithRedisCacheHandle("redis", true)
                    .WithExpiration(ExpirationMode.Absolute, TimeSpan.FromHours(1));
                }
            });
            var distributedCacheManager = new DistributedCacheManager(distributedCache);

            container.RegisterInstance <IDistributedCacheManager>(distributedCacheManager);

            var logger = LogManager.GetLogger("default");

            container.RegisterInstance <ILogger>(logger);

            // Create new work context for each request
            container.RegisterType <WorkContext, WorkContext>(new PerRequestLifetimeManager());
            Func <WorkContext> workContextFactory = () => container.Resolve <WorkContext>();

            container.RegisterInstance(workContextFactory);

            // Workaround for old storefront base URL: remove /api/ suffix since it is already included in every resource address in VirtoCommerce.Client library.
            var baseUrl = ConfigurationManager.ConnectionStrings["VirtoCommerceBaseUrl"].ConnectionString;

            if (baseUrl != null && baseUrl.EndsWith("/api/", StringComparison.OrdinalIgnoreCase))
            {
                var apiPosition = baseUrl.LastIndexOf("/api/", StringComparison.OrdinalIgnoreCase);
                if (apiPosition >= 0)
                {
                    baseUrl = baseUrl.Remove(apiPosition);
                }
            }

            var apiAppId     = appSettings["vc-public-ApiAppId"];
            var apiSecretKey = appSettings["vc-public-ApiSecretKey"];

            container.RegisterInstance(new HmacCredentials(apiAppId, apiSecretKey));

            container.RegisterType <VirtoCommerceApiRequestHandler>(new PerRequestLifetimeManager());

            ServicePointManager.UseNagleAlgorithm = false;

            var compressionHandler = new System.Net.Http.HttpClientHandler
            {
                AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
            };

            var baseUri = new Uri(baseUrl);

            container.RegisterType <ICartModuleApiClient>(new PerRequestLifetimeManager(), new InjectionFactory(c => new CartModuleApiClient(baseUri, c.Resolve <VirtoCommerceApiRequestHandler>(), compressionHandler)));
            container.RegisterType <ICatalogModuleApiClient>(new PerRequestLifetimeManager(), new InjectionFactory(c => new CatalogModuleApiClient(baseUri, c.Resolve <VirtoCommerceApiRequestHandler>(), compressionHandler)));
            container.RegisterType <IContentModuleApiClient>(new PerRequestLifetimeManager(), new InjectionFactory(c => new ContentModuleApiClient(baseUri, c.Resolve <VirtoCommerceApiRequestHandler>(), compressionHandler)));
            container.RegisterType <ICoreModuleApiClient>(new PerRequestLifetimeManager(), new InjectionFactory(c => new CoreModuleApiClient(baseUri, c.Resolve <VirtoCommerceApiRequestHandler>(), compressionHandler)));
            container.RegisterType <ICustomerModuleApiClient>(new PerRequestLifetimeManager(), new InjectionFactory(c => new CustomerModuleApiClient(baseUri, c.Resolve <VirtoCommerceApiRequestHandler>(), compressionHandler)));
            container.RegisterType <IInventoryModuleApiClient>(new PerRequestLifetimeManager(), new InjectionFactory(c => new InventoryModuleApiClient(baseUri, c.Resolve <VirtoCommerceApiRequestHandler>(), compressionHandler)));
            container.RegisterType <IMarketingModuleApiClient>(new PerRequestLifetimeManager(), new InjectionFactory(c => new MarketingModuleApiClient(baseUri, c.Resolve <VirtoCommerceApiRequestHandler>(), compressionHandler)));
            container.RegisterType <IOrdersModuleApiClient>(new PerRequestLifetimeManager(), new InjectionFactory(c => new OrdersModuleApiClient(baseUri, c.Resolve <VirtoCommerceApiRequestHandler>(), compressionHandler)));
            container.RegisterType <IPlatformModuleApiClient>(new PerRequestLifetimeManager(), new InjectionFactory(c => new PlatformModuleApiClient(baseUri, c.Resolve <VirtoCommerceApiRequestHandler>(), compressionHandler)));
            container.RegisterType <IPricingModuleApiClient>(new PerRequestLifetimeManager(), new InjectionFactory(c => new PricingModuleApiClient(baseUri, c.Resolve <VirtoCommerceApiRequestHandler>(), compressionHandler)));
            container.RegisterType <IQuoteModuleApiClient>(new PerRequestLifetimeManager(), new InjectionFactory(c => new QuoteModuleApiClient(baseUri, c.Resolve <VirtoCommerceApiRequestHandler>(), compressionHandler)));
            container.RegisterType <ISearchApiModuleApiClient>(new PerRequestLifetimeManager(), new InjectionFactory(c => new SearchApiModuleApiClient(baseUri, c.Resolve <VirtoCommerceApiRequestHandler>(), compressionHandler)));
            container.RegisterType <IStoreModuleApiClient>(new PerRequestLifetimeManager(), new InjectionFactory(c => new StoreModuleApiClient(baseUri, c.Resolve <VirtoCommerceApiRequestHandler>(), compressionHandler)));
            container.RegisterType <ISitemapsModuleApiClient>(new PerRequestLifetimeManager(), new InjectionFactory(c => new SitemapsModuleApiClient(baseUri, c.Resolve <VirtoCommerceApiRequestHandler>(), compressionHandler)));
            container.RegisterType <ISubscriptionModuleApiClient>(new PerRequestLifetimeManager(), new InjectionFactory(c => new SubscriptionModuleApiClient(baseUri, c.Resolve <VirtoCommerceApiRequestHandler>(), compressionHandler)));

            container.RegisterType <IMarketingService, MarketingServiceImpl>();
            container.RegisterType <IPromotionEvaluator, PromotionEvaluator>();
            container.RegisterType <ITaxEvaluator, TaxEvaluator>();
            container.RegisterType <IPricingService, PricingServiceImpl>();
            container.RegisterType <ICustomerService, CustomerServiceImpl>();
            container.RegisterType <IMenuLinkListService, MenuLinkListServiceImpl>();
            container.RegisterType <ISeoRouteService, SeoRouteService>();

            container.RegisterType <ICartBuilder, CartBuilder>();
            container.RegisterType <IQuoteRequestBuilder, QuoteRequestBuilder>();
            container.RegisterType <ICatalogSearchService, CatalogSearchServiceImpl>();
            container.RegisterType <IAuthenticationManager>(new InjectionFactory(context => HttpContext.Current.GetOwinContext().Authentication));
            container.RegisterType <IStorefrontUrlBuilder, StorefrontUrlBuilder>(new PerRequestLifetimeManager());

            //Register domain events
            container.RegisterType <IEventPublisher <OrderPlacedEvent>, EventPublisher <OrderPlacedEvent> >();
            container.RegisterType <IEventPublisher <UserLoginEvent>, EventPublisher <UserLoginEvent> >();
            container.RegisterType <IEventPublisher <QuoteRequestUpdatedEvent>, EventPublisher <QuoteRequestUpdatedEvent> >();
            //Register event handlers (observers)
            container.RegisterType <IAsyncObserver <OrderPlacedEvent>, CustomerServiceImpl>("Invalidate customer cache when user placed new order");
            container.RegisterType <IAsyncObserver <QuoteRequestUpdatedEvent>, CustomerServiceImpl>("Invalidate customer cache when quote request was updated");
            container.RegisterType <IAsyncObserver <UserLoginEvent>, CartBuilder>("Merge anonymous cart with loggined user cart");
            container.RegisterType <IAsyncObserver <UserLoginEvent>, QuoteRequestBuilder>("Merge anonymous quote request with loggined user quote");

            var cmsContentConnectionString = BlobConnectionString.Parse(ConfigurationManager.ConnectionStrings["ContentConnectionString"].ConnectionString);
            var themesBasePath             = cmsContentConnectionString.RootPath.TrimEnd('/') + "/" + "Themes";
            var staticContentBasePath      = cmsContentConnectionString.RootPath.TrimEnd('/') + "/" + "Pages";
            //Use always file system provider for global theme
            var globalThemesBlobProvider = new FileSystemContentBlobProvider(ResolveLocalPath("~/App_Data/Themes/default"));
            IContentBlobProvider       themesBlobProvider;
            IStaticContentBlobProvider staticContentBlobProvider;

            if ("AzureBlobStorage".Equals(cmsContentConnectionString.Provider, StringComparison.OrdinalIgnoreCase))
            {
                themesBlobProvider        = new AzureBlobContentProvider(cmsContentConnectionString.ConnectionString, themesBasePath, localCacheManager);
                staticContentBlobProvider = new AzureBlobContentProvider(cmsContentConnectionString.ConnectionString, staticContentBasePath, localCacheManager);
            }
            else
            {
                themesBlobProvider        = new FileSystemContentBlobProvider(ResolveLocalPath(themesBasePath));
                staticContentBlobProvider = new FileSystemContentBlobProvider(ResolveLocalPath(staticContentBasePath));
            }
            container.RegisterInstance <IStaticContentBlobProvider>(staticContentBlobProvider);

            var shopifyLiquidEngine = new ShopifyLiquidThemeEngine(localCacheManager, workContextFactory, () => container.Resolve <IStorefrontUrlBuilder>(), themesBlobProvider, globalThemesBlobProvider, "~/themes/assets", "~/themes/global/assets");

            container.RegisterInstance <ILiquidThemeEngine>(shopifyLiquidEngine);

            //Register liquid engine
            ViewEngines.Engines.Add(new DotLiquidThemedViewEngine(shopifyLiquidEngine));

            // Shopify model binders convert Shopify form fields with bad names to VirtoCommerce model properties.
            container.RegisterType <IModelBinderProvider, ShopifyModelBinderProvider>("shopify");

            //Static content service
            var staticContentService = new StaticContentServiceImpl(shopifyLiquidEngine, localCacheManager, workContextFactory, () => container.Resolve <IStorefrontUrlBuilder>(), StaticContentItemFactory.GetContentItemFromPath, staticContentBlobProvider);

            container.RegisterInstance <IStaticContentService>(staticContentService);
            //Register generate sitemap background job
            container.RegisterType <GenerateSitemapJob>(new InjectionFactory(c => new GenerateSitemapJob(themesBlobProvider, c.Resolve <ISitemapsModuleApiClient>(), c.Resolve <IStorefrontUrlBuilder>())));

            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters, workContextFactory, () => container.Resolve <CommonController>());
            RouteConfig.RegisterRoutes(RouteTable.Routes, container.Resolve <ISeoRouteService>(), workContextFactory, () => container.Resolve <IStorefrontUrlBuilder>());
            AuthConfig.ConfigureAuth(app, () => container.Resolve <IStorefrontUrlBuilder>());
            container.Resolve <BundleConfig>().RegisterBundles(BundleTable.Bundles);

            //This special binders need because all these types not contains default ctor and Money with Currency properties
            ModelBinders.Binders.Add(typeof(Model.Cart.Shipment), new CartModelBinder <Model.Cart.Shipment>(workContextFactory));
            ModelBinders.Binders.Add(typeof(Model.Cart.Payment), new CartModelBinder <Model.Cart.Payment>(workContextFactory));
            ModelBinders.Binders.Add(typeof(Model.Order.PaymentIn), new OrderModelBinder <Model.Order.PaymentIn>(workContextFactory));

            app.Use <WorkContextOwinMiddleware>(container);
            app.UseStageMarker(PipelineStage.PostAuthorize);
            app.Use <StorefrontUrlRewriterOwinMiddleware>(container);
            app.UseStageMarker(PipelineStage.PostAuthorize);
        }
Exemplo n.º 27
0
        protected void Application_Start()
        {
            var appName = ConfigurationManager.AppSettings["AppName"] ?? string.Empty;


            /*
             * Turning on HTTPS locally without properly setting up the DataFlow.Web project
             * can result in webpage timeouts and redirect errors. To have Https work locally,
             * go to the project properties and change "SSL Enabled" from False to True.
             * Take note of the SSL URL that is then generated. Now, right click on DataFlow.Web
             * and go to Properties and then navigate to the Web tab and enter the SSL URL
             * for Project URL.
             */
            if (HostingEnvironment.IsDevelopmentEnvironment == false)
            {
                var forceHttps = Convert.ToBoolean(ConfigurationManager.AppSettings["ForceHttps"] ?? "false");

                if (forceHttps)
                {
                    GlobalFilters.Filters.Add(new RequireHttpsAttribute());
                }
            }

            var cacheConfig = ConfigurationBuilder.BuildConfiguration(appName, settings =>
            {
                settings.WithUpdateMode(CacheUpdateMode.None)
                .WithSystemRuntimeCacheHandle(appName)
                .EnableStatistics()
                .EnablePerformanceCounters()
                .WithExpiration(ExpirationMode.Sliding, TimeSpan.FromHours(2));
            });
            var cacheFactory = CacheFactory.FromConfiguration <string>(appName, cacheConfig);

            var builder = new ContainerBuilder();

            builder.RegisterControllers(typeof(MvcApplication).Assembly);
            builder.RegisterAggregateService <IBaseServices>();
            builder.RegisterModule <AutofacWebTypesModule>();
            builder.RegisterModule(new AutoMapperModule());
            builder.RegisterType <DataFlowDbContext>().InstancePerRequest();
            builder.RegisterType <EdFiService>().InstancePerRequest();
            builder.RegisterType <EdFiMetadataProcessor>().InstancePerRequest();
            builder.RegisterType <ConfigurationService>().AsImplementedInterfaces().InstancePerRequest();
            builder.Register(c => LogManager.GetLogger(appName)).As <ILogger>().InstancePerRequest();
            builder.RegisterType <NLogService>().AsImplementedInterfaces().InstancePerRequest();
            builder.RegisterType <WebConfigAppSettingsService>().AsImplementedInterfaces().SingleInstance();
            builder.RegisterType <AgentService>().InstancePerRequest();

            builder.RegisterType <CacheService>().WithParameters(new[]
            {
                new TypedParameter(typeof(ICacheManagerConfiguration), cacheConfig),
                new TypedParameter(typeof(ICacheManager <string>), cacheFactory)
            }).As <ICacheService>().SingleInstance();

            var container = builder.Build();

            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

            GlobalConfiguration.Configure(WebApiConfig.Register);

            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
Exemplo n.º 28
0
        private static void InitializePlatform(IAppBuilder app, IUnityContainer container, string connectionStringName, HangfireLauncher hangfireLauncher, string modulesPath)
        {
            container.RegisterType <ICurrentUser, CurrentUser>(new HttpContextLifetimeManager());
            container.RegisterType <IUserNameResolver, UserNameResolver>();

            #region Setup database

            using (var db = new SecurityDbContext(connectionStringName))
            {
                new IdentityDatabaseInitializer().InitializeDatabase(db);
            }

            using (var context = new PlatformRepository(connectionStringName, container.Resolve <AuditableInterceptor>(), new EntityPrimaryKeyGeneratorInterceptor()))
            {
                new PlatformDatabaseInitializer().InitializeDatabase(context);
            }

            hangfireLauncher.ConfigureDatabase();

            #endregion


            Func <IPlatformRepository> platformRepositoryFactory = () => new PlatformRepository(connectionStringName, container.Resolve <AuditableInterceptor>(), new EntityPrimaryKeyGeneratorInterceptor());
            container.RegisterType <IPlatformRepository>(new InjectionFactory(c => platformRepositoryFactory()));
            container.RegisterInstance(platformRepositoryFactory);
            var moduleCatalog = container.Resolve <IModuleCatalog>();

            #region Caching
            ICacheManager <object> cacheManager = null;
            //Try to load cache configuration from web.config first
            if (ConfigurationManager.GetSection(CacheManagerSection.DefaultSectionName) != null)
            {
                cacheManager = CacheFactory.FromConfiguration <object>("platformCache");
            }
            else
            {
                cacheManager = CacheFactory.Build("platformCache", settings =>
                {
                    //Should be aware to using Web cache cache handle because it not worked in native threads. (Hangfire jobs)
                    settings.WithUpdateMode(CacheUpdateMode.Up)
                    .WithSystemRuntimeCacheHandle("memCacheHandle")
                    .WithExpiration(ExpirationMode.Absolute, TimeSpan.FromDays(1));
                });
            }
            container.RegisterInstance(cacheManager);
            #endregion

            #region Settings

            var platformModuleManifest = new ModuleManifest
            {
                Id              = "VirtoCommerce.Platform",
                Version         = PlatformVersion.CurrentVersion.ToString(),
                PlatformVersion = PlatformVersion.CurrentVersion.ToString(),
                Settings        = new[]
                {
                    new ModuleSettingsGroup
                    {
                        Name     = "Platform|Notifications|SendGrid",
                        Settings = new []
                        {
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SendGrid.ApiKey",
                                ValueType   = ModuleSetting.TypeString,
                                Title       = "SendGrid API key",
                                Description = "Your SendGrid API key"
                            }
                        }
                    },
                    new ModuleSettingsGroup
                    {
                        Name     = "Platform|Notifications|SendingJob",
                        Settings = new []
                        {
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SendingJob.TakeCount",
                                ValueType   = ModuleSetting.TypeInteger,
                                Title       = "Job Take Count",
                                Description = "Take count for sending job"
                            }
                        }
                    },
                    new ModuleSettingsGroup
                    {
                        Name     = "Platform|Notifications|SmtpClient",
                        Settings = new []
                        {
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SmptClient.Host",
                                ValueType   = ModuleSetting.TypeString,
                                Title       = "Smtp server host",
                                Description = "Smtp server host"
                            },
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SmptClient.Port",
                                ValueType   = ModuleSetting.TypeInteger,
                                Title       = "Smtp server port",
                                Description = "Smtp server port"
                            },
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SmptClient.Login",
                                ValueType   = ModuleSetting.TypeString,
                                Title       = "Smtp server login",
                                Description = "Smtp server login"
                            },
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SmptClient.Password",
                                ValueType   = ModuleSetting.TypeSecureString,
                                Title       = "Smtp server password",
                                Description = "Smtp server password"
                            },
                            new ModuleSetting
                            {
                                Name        = "VirtoCommerce.Platform.Notifications.SmptClient.UseSsl",
                                ValueType   = ModuleSetting.TypeBoolean,
                                Title       = "Use SSL",
                                Description = "Use secure connection"
                            },
                        }
                    },
                    new ModuleSettingsGroup
                    {
                        Name     = "Platform|Security",
                        Settings = new []
                        {
                            new ModuleSetting
                            {
                                Name         = "VirtoCommerce.Platform.Security.AccountTypes",
                                ValueType    = ModuleSetting.TypeString,
                                Title        = "Account types",
                                Description  = "Dictionary for possible account types",
                                IsArray      = true,
                                ArrayValues  = Enum.GetNames(typeof(AccountType)),
                                DefaultValue = AccountType.Manager.ToString()
                            }
                        }
                    },
                    new ModuleSettingsGroup
                    {
                        Name     = "Platform|User Profile",
                        Settings = new[]
                        {
                            new ModuleSetting
                            {
                                Name      = "VirtoCommerce.Platform.UI.MainMenu.State",
                                ValueType = ModuleSetting.TypeJson,
                                Title     = "Persisted state of main menu"
                            },
                            new ModuleSetting
                            {
                                Name         = "VirtoCommerce.Platform.UI.Language",
                                ValueType    = ModuleSetting.TypeString,
                                Title        = "Language",
                                Description  = "Default language (two letter code from ISO 639-1)",
                                DefaultValue = "en"
                            }
                        }
                    },
                    new ModuleSettingsGroup
                    {
                        Name     = "Platform|User Interface",
                        Settings = new[]
                        {
                            new ModuleSetting
                            {
                                Name         = "VirtoCommerce.Platform.UI.Customization",
                                ValueType    = ModuleSetting.TypeJson,
                                Title        = "Customization",
                                Description  = "JSON contains personalization settings of manager UI",
                                DefaultValue = "{\n" +
                                               "  \"title\": \"Virto Commerce\",\n" +
                                               "  \"logo\": \"Content/themes/main/images/logo.png\",\n" +
                                               "  \"contrast_logo\": \"Content/themes/main/images/contrast-logo.png\"\n" +
                                               "}"
                            }
                        }
                    }
                }
            };

            var settingsManager = new SettingsManager(moduleCatalog, platformRepositoryFactory, cacheManager, new[] { new ManifestModuleInfo(platformModuleManifest) });
            container.RegisterInstance <ISettingsManager>(settingsManager);

            #endregion

            #region Dynamic Properties

            container.RegisterType <IDynamicPropertyService, DynamicPropertyService>(new ContainerControlledLifetimeManager());

            #endregion

            #region Notifications

            var hubSignalR = GlobalHost.ConnectionManager.GetHubContext <ClientPushHub>();
            var notifier   = new InMemoryPushNotificationManager(hubSignalR);
            container.RegisterInstance <IPushNotificationManager>(notifier);

            var resolver = new LiquidNotificationTemplateResolver();
            container.RegisterInstance <INotificationTemplateResolver>(resolver);

            var notificationTemplateService = new NotificationTemplateServiceImpl(platformRepositoryFactory);
            container.RegisterInstance <INotificationTemplateService>(notificationTemplateService);

            var notificationManager = new NotificationManager(resolver, platformRepositoryFactory, notificationTemplateService);
            container.RegisterInstance <INotificationManager>(notificationManager);

            IEmailNotificationSendingGateway emailNotificationSendingGateway = null;

            var emailNotificationSendingGatewayName = ConfigurationManager.AppSettings.GetValue("VirtoCommerce:Notifications:Gateway", "Default");

            if (string.Equals(emailNotificationSendingGatewayName, "Default", StringComparison.OrdinalIgnoreCase))
            {
                emailNotificationSendingGateway = new DefaultSmtpEmailNotificationSendingGateway(settingsManager);
            }
            else if (string.Equals(emailNotificationSendingGatewayName, "SendGrid", StringComparison.OrdinalIgnoreCase))
            {
                emailNotificationSendingGateway = new SendGridEmailNotificationSendingGateway(settingsManager);
            }

            if (emailNotificationSendingGateway != null)
            {
                container.RegisterInstance(emailNotificationSendingGateway);
            }

            var defaultSmsNotificationSendingGateway = new DefaultSmsNotificationSendingGateway();
            container.RegisterInstance <ISmsNotificationSendingGateway>(defaultSmsNotificationSendingGateway);

            #endregion

            #region Assets

            var blobConnectionString = BlobConnectionString.Parse(ConfigurationManager.ConnectionStrings["AssetsConnectionString"].ConnectionString);

            if (string.Equals(blobConnectionString.Provider, FileSystemBlobProvider.ProviderName, StringComparison.OrdinalIgnoreCase))
            {
                var fileSystemBlobProvider = new FileSystemBlobProvider(NormalizePath(blobConnectionString.RootPath), blobConnectionString.PublicUrl);

                container.RegisterInstance <IBlobStorageProvider>(fileSystemBlobProvider);
                container.RegisterInstance <IBlobUrlResolver>(fileSystemBlobProvider);
            }
            else if (string.Equals(blobConnectionString.Provider, AzureBlobProvider.ProviderName, StringComparison.OrdinalIgnoreCase))
            {
                var azureBlobProvider = new AzureBlobProvider(blobConnectionString.ConnectionString);
                container.RegisterInstance <IBlobStorageProvider>(azureBlobProvider);
                container.RegisterInstance <IBlobUrlResolver>(azureBlobProvider);
            }


            #endregion

            #region Modularity

            var modulesDataSources    = ConfigurationManager.AppSettings.SplitStringValue("VirtoCommerce:ModulesDataSources");
            var externalModuleCatalog = new ExternalManifestModuleCatalog(moduleCatalog.Modules, modulesDataSources, container.Resolve <ILog>());
            container.RegisterType <ModulesController>(new InjectionConstructor(externalModuleCatalog, new ModuleInstaller(modulesPath, externalModuleCatalog), notifier, container.Resolve <IUserNameResolver>(), settingsManager));

            #endregion

            #region ChangeLogging

            var changeLogService = new ChangeLogService(platformRepositoryFactory);
            container.RegisterInstance <IChangeLogService>(changeLogService);

            #endregion

            #region Security
            container.RegisterInstance <IPermissionScopeService>(new PermissionScopeService());
            container.RegisterType <IRoleManagementService, RoleManagementService>(new ContainerControlledLifetimeManager());

            var apiAccountProvider = new ApiAccountProvider(platformRepositoryFactory, cacheManager);
            container.RegisterInstance <IApiAccountProvider>(apiAccountProvider);

            container.RegisterType <IClaimsIdentityProvider, ApplicationClaimsIdentityProvider>(new ContainerControlledLifetimeManager());

            container.RegisterInstance(app.GetDataProtectionProvider());
            container.RegisterType <SecurityDbContext>(new InjectionConstructor(connectionStringName));
            container.RegisterType <IUserStore <ApplicationUser>, ApplicationUserStore>();
            container.RegisterType <IAuthenticationManager>(new InjectionFactory(c => HttpContext.Current.GetOwinContext().Authentication));
            container.RegisterType <ApplicationUserManager>();
            container.RegisterType <ApplicationSignInManager>();

            var nonEditableUsers = ConfigurationManager.AppSettings.GetValue("VirtoCommerce:NonEditableUsers", string.Empty);
            container.RegisterInstance <ISecurityOptions>(new SecurityOptions(nonEditableUsers));

            container.RegisterType <ISecurityService, SecurityService>();

            #endregion

            #region ExportImport
            container.RegisterType <IPlatformExportImportManager, PlatformExportImportManager>();
            #endregion

            #region Serialization

            container.RegisterType <IExpressionSerializer, XmlExpressionSerializer>();

            #endregion
        }
 private static void InitializeStaticCache(string cacheName)
 {
     cacheInstance = CacheFactory.FromConfiguration <object>(cacheName);
 }
Exemplo n.º 30
0
        public void Configuration(IAppBuilder app)
        {
            if (_managerAssembly != null)
            {
                AreaRegistration.RegisterAllAreas();
                CallChildConfigure(app, _managerAssembly, "VirtoCommerce.Platform.Web.Startup", "Configuration", "~/areas/admin", "admin/");
            }

            UnityWebActivator.Start();
            var container = UnityConfig.GetConfiguredContainer();

            //Caching configuration (system runtime memory handle)
            var cacheManager = CacheFactory.FromConfiguration <object>("storefrontCache");

            container.RegisterInstance <ICacheManager <object> >(cacheManager);
            //Because CacheManagerOutputCacheProvider used diff cache manager instance need translate clear region by this way
            //https://github.com/MichaCo/CacheManager/issues/32
            cacheManager.OnClearRegion += (sender, region) =>
            {
                try
                {
                    CacheManagerOutputCacheProvider.Cache.ClearRegion(region.Region);
                }
                catch (Exception)
                {
                }
            };
            cacheManager.OnClear += (sender, args) =>
            {
                try
                {
                    CacheManagerOutputCacheProvider.Cache.Clear();
                }
                catch (Exception)
                {
                }
            };

            var logger = LogManager.GetLogger("default");

            container.RegisterInstance <ILogger>(logger);

            // Workaround for old storefront base URL: remove /api/ suffix since it is already included in every resource address in VirtoCommerce.Client library.
            var baseUrl = ConfigurationManager.ConnectionStrings["VirtoCommerceBaseUrl"].ConnectionString;

            if (baseUrl != null && baseUrl.EndsWith("/api/", StringComparison.OrdinalIgnoreCase))
            {
                var apiPosition = baseUrl.LastIndexOf("/api/", StringComparison.OrdinalIgnoreCase);
                if (apiPosition >= 0)
                {
                    baseUrl = baseUrl.Remove(apiPosition);
                }
            }

            var apiClient = new HmacApiClient(baseUrl, ConfigurationManager.AppSettings["vc-public-ApiAppId"], ConfigurationManager.AppSettings["vc-public-ApiSecretKey"]);

            container.RegisterInstance <ApiClient>(apiClient);

            container.RegisterType <IStoreModuleApi, StoreModuleApi>();
            container.RegisterType <IVirtoCommercePlatformApi, VirtoCommercePlatformApi>();
            container.RegisterType <ICustomerManagementModuleApi, CustomerManagementModuleApi>();
            container.RegisterType <ICommerceCoreModuleApi, CommerceCoreModuleApi>();
            container.RegisterType <ICustomerManagementModuleApi, CustomerManagementModuleApi>();
            container.RegisterType <ICatalogModuleApi, CatalogModuleApi>();
            container.RegisterType <IPricingModuleApi, PricingModuleApi>();
            container.RegisterType <IInventoryModuleApi, InventoryModuleApi>();
            container.RegisterType <IShoppingCartModuleApi, ShoppingCartModuleApi>();
            container.RegisterType <IOrderModuleApi, OrderModuleApi>();
            container.RegisterType <IMarketingModuleApi, MarketingModuleApi>();
            container.RegisterType <ICMSContentModuleApi, CMSContentModuleApi>();
            container.RegisterType <IQuoteModuleApi, QuoteModuleApi>();
            container.RegisterType <ISearchModuleApi, SearchModuleApi>();
            container.RegisterType <IMarketingService, MarketingServiceImpl>();
            container.RegisterType <IPromotionEvaluator, PromotionEvaluator>();
            container.RegisterType <ICartValidator, CartValidator>();
            container.RegisterType <IPricingService, PricingServiceImpl>();
            container.RegisterType <ICustomerService, CustomerServiceImpl>();

            container.RegisterType <ICartBuilder, CartBuilder>();
            container.RegisterType <IQuoteRequestBuilder, QuoteRequestBuilder>();
            container.RegisterType <ICatalogSearchService, CatalogSearchServiceImpl>();
            container.RegisterType <IAuthenticationManager>(new InjectionFactory((context) => HttpContext.Current.GetOwinContext().Authentication));


            container.RegisterType <IStorefrontUrlBuilder, StorefrontUrlBuilder>(new PerRequestLifetimeManager());

            //Register domain events
            container.RegisterType <IEventPublisher <OrderPlacedEvent>, EventPublisher <OrderPlacedEvent> >();
            container.RegisterType <IEventPublisher <UserLoginEvent>, EventPublisher <UserLoginEvent> >();
            //Register event handlers (observers)
            container.RegisterType <IAsyncObserver <OrderPlacedEvent>, CustomerServiceImpl>("Invalidate customer cache when user placed new order");
            container.RegisterType <IAsyncObserver <UserLoginEvent>, CartBuilder>("Merge anonymous cart with loggined user cart");
            container.RegisterType <IAsyncObserver <UserLoginEvent>, QuoteRequestBuilder>("Merge anonymous quote request with loggined user quote");

            // Create new work context for each request
            container.RegisterType <WorkContext, WorkContext>(new PerRequestLifetimeManager());
            Func <WorkContext> workContextFactory = () => container.Resolve <WorkContext>();

            container.RegisterInstance(workContextFactory);

            var themesPath          = ConfigurationManager.AppSettings["vc-public-themes"] ?? "~/App_data/Themes";
            var shopifyLiquidEngine = new ShopifyLiquidThemeEngine(cacheManager, workContextFactory, () => container.Resolve <IStorefrontUrlBuilder>(), ResolveLocalPath(themesPath), "~/themes/assets", "~/themes/global/assets");

            container.RegisterInstance <ILiquidThemeEngine>(shopifyLiquidEngine);
            //Register liquid engine
            ViewEngines.Engines.Add(new DotLiquidThemedViewEngine(shopifyLiquidEngine));

            // Shopify model binders convert Shopify form fields with bad names to VirtoCommerce model properties.
            container.RegisterType <IModelBinderProvider, ShopifyModelBinderProvider>("shopify");

            var staticContentPath = ConfigurationManager.AppSettings["vc-public-pages"] ?? "~/App_data/Pages";
            //Static content service
            var staticContentService = new StaticContentServiceImpl(ResolveLocalPath(staticContentPath), new Markdown(), shopifyLiquidEngine, cacheManager, workContextFactory, () => container.Resolve <IStorefrontUrlBuilder>());

            container.RegisterInstance <IStaticContentService>(staticContentService);

            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters, () => container.Resolve <WorkContext>());
            RouteConfig.RegisterRoutes(RouteTable.Routes, () => container.Resolve <WorkContext>(), container.Resolve <ICommerceCoreModuleApi>(), container.Resolve <IStaticContentService>(), cacheManager);
            AuthConfig.ConfigureAuth(app, () => container.Resolve <IStorefrontUrlBuilder>());

            app.Use <WorkContextOwinMiddleware>(container);
            app.UseStageMarker(PipelineStage.ResolveCache);
        }