E-commerce 6: New Customization Model + Upgrade Instructions

Version 6 comes with brand new customization model which brings you more flexibility and easier customization. If you are one of those who did some customization to E-commerce in previous versions, you should definitely read this post. Also, you will be given instructions on how to upgrade all your e-commerce customizations to make them work in version 6.

Version 5.5 R2 and older
First, I would like to remind you of the customization model from older versions. I believe it helps you better identify the changes. Old customization model is built from 4 different namespaces:

a) CMS.CMSEcommerce
Contains default implementation of all providers and their methods, e.g. CMS.CMSEcommerce.OrderInfoProvider with SetOrderInfo(OrderInfo order) method

b) CMS.IEcommerce
Contains interfaces which define all customizable methods. Then, they are implemented by the corresponding custom providers and by the corresponding wrappers, e.g. CMS.IEcommerce.IOrderInfoProvider is implemented by the CMS.CustomECommerceProvider.CustomOrderInfoProvider and by the CMS.Ecommerce.OrderInfoProvider

c) CMS.Ecommerce
Contains providers which implement corresponding interfaces from CMS.IEcomemerce, e.g. CMS.Ecommerce.OrderInfoProvider implements CMS.IEcommerce.IOrderInfoProvider. Each method is implemented only as a simple wrapper, meaning that it calls corresponding method either from CMS.CMSEcommerce (if customization is OFF) or from CMS.CustomECommerceProvider (if customization is ON). Customization is turned on/off by the CMSUseCustomEcommerceProviders web.config key.

d) CMS.CustomECommerceProvider
Contains custom providers which implement corresponding interfaces from CMS.IEcomemerce, e.g. CMS.CustomECommerceProvider.OrderInfoProvider implements CMS.IEcommerce.IOrderInfoProvider. Each method is implemented in the way that our implementation is called by default, meaning that if you do not customize such method, it works in the default way, e.g. CMS.CMSEcommerce.OrderInfoProvider.SetOrderInfo(OrderInfo order ) is called inside  the CMS.CustomECommerceProvider.OrderInfoProvider.SetOrderInfo(OrderInfo order) by default.


Main disadvantages of the old model:
1) A lot of namespaces make the usability of the API quite complicated and mistake-prone.
2) There is a need for CustomOrderInfoProvider DLL recompilation after any modification in custom e-commerce providers (customization from App_Code is not supported).
3) A lot of very similar code in all providers (no abstraction) makes the maintenance (for us) and the orientation (for you with source code) very complicated.

Version 6
What we did in version 6? We threw CMS.CMSEcommerce, CMS.IEcommerce and CMS.CustomECommerceProvider away, moved default implementation to CMS.Ecommerce and prepared a brand new abstraction of our providers which gave us the possibility to significantly simplify and reduce their code and simplify the way of their customization.

Now, there is only one namespace (CMS.Ecommerce) which contains default implementation of all providers and their methods. Each provider has its inner static provider object (accessible through ProviderObject property) which is initialized to itself by default. For each public customizable method, there is the protected virtual method with name ending with 'Internal' which contains our implementation, e.g. for the SetOrderInfo method there is the SetOrderInfoInternal method. To make it work, the protected virtual method is called from its corresponding public method (e.g. ProviderObject.SetOrderInfoInternal(OrderInfo order) is called inside SetOrderInfo(OrderInfo order)). 

Then, to customize specific public method of the specific provider, e.g. to customize SetOrderInfo(OrderInfo order) method of the CMS.Ecommerce.OrderInfoProvider,  you need to:

1) create your custom class which inherits from the original corresponding provider, e.g. MyOrderInfoProvider class which inherits from CMS.Ecommerce.OrderInfoProvider

2) override the method(s) you would like to customize, e.g. override SetOrderInfoInternal(OrderInfo order) method to customize SetOrderInfo(OrderInfo order) method
3) Register your custom class as a new provider object of the original provider. Registration can be done either programmatically (e.g. OrderInfoProvider.ProviderObject = new MyOrderInfoProvider()) or using web.config settings


...if you are still confused or just want a real example, I recommend installing Kentico CMS 6 and navigating to <your web project folder>\App_Code\CMSModules\Ecommerce\Samples (or to <your web project folder>\Old_App_Code\CMSModules\Ecommerce\Samples if you installed Kentico CMS as a web application) folder. There are several cool examples of e-commerce customization like a) Buy product A, get product B with 20% discount, b) Product price based on culture,... and more. There is also an example of the class (SampleEcommerceModule.cs) where all sample e-commerce providers are registered.

Main advantages of the new model:
1) Easier usability (for you) and maintenance (for us) of the e-commerce API (only one namespace).
2) No need for recompiling any DLL after modification in custom e-commerce providers (customization can be done from App_Code)
3) Easy and unified way of customization which is used also by other providers in the system, see the example of the custom e-mail provider. Also, see Martin's blog post with more details.

Upgrade to version 6
Once you are familiar with the new model, it shouldn't be difficult for you to upgrade your customizations to version 6. All you need to do is to move code of all your custom implementations from the old custom providers in CustomECommerceProvider to your new custom providers. Also, CMSUseEcommerceCustomProviders web.config key has now no effect, so you can remove it from your web.config file. See the scheme bellow:

I believe that this post will help you understand the changes in e-commerce customization as well as upgrade your old e-commerce customizations to version 6. Anyway, feel free to put your further questions bellow.

Share this article on   LinkedIn

Petr Vozak

Technology Partnership Product Owner at Kentico. He works with technology partners to enrich the Kentico product offering and bring greater value to those using our products.


petr.vozak-kentico commented on

@Pipa: Hi, what kind of code did you try? Could you please be more specific? Thanks.

Pipa commented on

HI ,I tried this code but I am getting this error mssgaee:CS0103: The name EmailTemplateProvider' does not exist in the current contextSource File: c:\inetpub\wwwroot\Kentico\ImportProducts1.aspx.cs Line: 49 Any Ideas, what I am missing?Do I need to mention anything in the global.ascx.cs file?ThanksGitesh Shah

petr.vozak-kentico commented on

Hi Walter, I am happy that you found it useful. Also, thank you for adding info about inheriting the base behavior, I forgot to mention it ;)

Walter Gameiro commented on

Dear Petr,
Wonderful post. Thank you for this valuable information.

One thing that wasn't clear from your post, but may be of use to other readers:
If you want to inherit the base behavior (e.g. order creation) in your overriden OrderInfoProvider then you must call base.SetOrderInfoInternal() before you do your customizations.
This may be the case for most of the providers you override.

For example, if you want to update the payment status of an event Attendee when the order is updated, you can add the custom code to update the payment column in the Attendee object, but if you don't call base.SetOrderInfoInternal() first the order will not be created (unless you are creating it yourself, of course.)

The "Internal" methods seem to have behavior of their own - they are not empty/abstract methods for you to inject your custom logic, unlike other patterns used in the .Net Framework.

Jeroen Fürst commented on

Great job! Thank you for simplifying the namespaces :) Looking forward to the upgrade!