private IStaticContentService GetStaticContentService() { var cacheManager = new Mock <ILocalCacheManager>(); cacheManager.Setup(cache => cache.Get <ContentItem[]>(It.IsAny <string>(), It.IsAny <string>())).Returns <ContentItem[]>(null); var urlBuilder = new Mock <IStorefrontUrlBuilder>(); var liquidEngine = new Mock <ILiquidThemeEngine>(); var path = Path.Combine(Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).Parent.FullName, "Pages"); var blobProvider = new FileSystemContentBlobProvider(path); var retVal = new StaticContentServiceImpl(liquidEngine.Object, cacheManager.Object, () => null, () => urlBuilder.Object, StaticContentItemFactory.GetContentItemFromPath, blobProvider); return(retVal); }
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); }
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 // 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 = ConfigurationManager.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 = ConfigurationManager.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 = ConfigurationManager.AppSettings["vc-public-ApiAppId"]; var apiSecretKey = ConfigurationManager.AppSettings["vc-public-ApiSecretKey"]; var hmacHandler = new HmacRestRequestHandler(apiAppId, apiSecretKey); var currentUserHandler = new CurrentUserRestRequestHandler(workContextFactory); container.RegisterInstance <IVirtoCommerceCartApi>(new VirtoCommerceCartApi(new CartModule.Client.Client.ApiClient(baseUrl, new CartModule.Client.Client.Configuration(), hmacHandler.PrepareRequest, currentUserHandler.PrepareRequest))); container.RegisterInstance <IVirtoCommerceCatalogApi>(new VirtoCommerceCatalogApi(new CatalogModule.Client.Client.ApiClient(baseUrl, new CatalogModule.Client.Client.Configuration(), hmacHandler.PrepareRequest, currentUserHandler.PrepareRequest))); container.RegisterInstance <IVirtoCommerceContentApi>(new VirtoCommerceContentApi(new ContentModule.Client.Client.ApiClient(baseUrl, new ContentModule.Client.Client.Configuration(), hmacHandler.PrepareRequest, currentUserHandler.PrepareRequest))); container.RegisterInstance <IVirtoCommerceCoreApi>(new VirtoCommerceCoreApi(new CoreModule.Client.Client.ApiClient(baseUrl, new CoreModule.Client.Client.Configuration(), hmacHandler.PrepareRequest, currentUserHandler.PrepareRequest))); container.RegisterInstance <IVirtoCommerceCustomerApi>(new VirtoCommerceCustomerApi(new CustomerModule.Client.Client.ApiClient(baseUrl, new CustomerModule.Client.Client.Configuration(), hmacHandler.PrepareRequest, currentUserHandler.PrepareRequest))); container.RegisterInstance <IVirtoCommerceInventoryApi>(new VirtoCommerceInventoryApi(new InventoryModule.Client.Client.ApiClient(baseUrl, new InventoryModule.Client.Client.Configuration(), hmacHandler.PrepareRequest, currentUserHandler.PrepareRequest))); container.RegisterInstance <IVirtoCommerceMarketingApi>(new VirtoCommerceMarketingApi(new MarketingModule.Client.Client.ApiClient(baseUrl, new MarketingModule.Client.Client.Configuration(), hmacHandler.PrepareRequest, currentUserHandler.PrepareRequest))); container.RegisterInstance <IVirtoCommercePlatformApi>(new VirtoCommercePlatformApi(new Platform.Client.Client.ApiClient(baseUrl, new Platform.Client.Client.Configuration(), hmacHandler.PrepareRequest, currentUserHandler.PrepareRequest))); container.RegisterInstance <IVirtoCommercePricingApi>(new VirtoCommercePricingApi(new PricingModule.Client.Client.ApiClient(baseUrl, new PricingModule.Client.Client.Configuration(), hmacHandler.PrepareRequest, currentUserHandler.PrepareRequest))); container.RegisterInstance <IVirtoCommerceOrdersApi>(new VirtoCommerceOrdersApi(new OrderModule.Client.Client.ApiClient(baseUrl, new OrderModule.Client.Client.Configuration(), hmacHandler.PrepareRequest, currentUserHandler.PrepareRequest))); container.RegisterInstance <IVirtoCommerceQuoteApi>(new VirtoCommerceQuoteApi(new QuoteModule.Client.Client.ApiClient(baseUrl, new QuoteModule.Client.Client.Configuration(), hmacHandler.PrepareRequest, currentUserHandler.PrepareRequest))); container.RegisterInstance <IVirtoCommerceSearchApi>(new VirtoCommerceSearchApi(new SearchModule.Client.Client.ApiClient(baseUrl, new SearchModule.Client.Client.Configuration(), hmacHandler.PrepareRequest, currentUserHandler.PrepareRequest))); container.RegisterInstance <IVirtoCommerceStoreApi>(new VirtoCommerceStoreApi(new StoreModule.Client.Client.ApiClient(baseUrl, new StoreModule.Client.Client.Configuration(), hmacHandler.PrepareRequest, currentUserHandler.PrepareRequest))); container.RegisterType <IMarketingService, MarketingServiceImpl>(); container.RegisterType <IPromotionEvaluator, PromotionEvaluator>(); container.RegisterType <ICartValidator, CartValidator>(); container.RegisterType <IPricingService, PricingServiceImpl>(); container.RegisterType <ICustomerService, CustomerServiceImpl>(); container.RegisterType <IMenuLinkListService, MenuLinkListServiceImpl>(); 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); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters, workContextFactory, () => container.Resolve <CommonController>()); RouteConfig.RegisterRoutes(RouteTable.Routes, workContextFactory, container.Resolve <IVirtoCommerceCoreApi>(), container.Resolve <IStaticContentService>(), localCacheManager); AuthConfig.ConfigureAuth(app, () => container.Resolve <IStorefrontUrlBuilder>()); app.Use <WorkContextOwinMiddleware>(container); app.UseStageMarker(PipelineStage.PostAuthorize); app.Use <StorefrontUrlRewriterOwinMiddleware>(container); app.UseStageMarker(PipelineStage.PostAuthorize); }