Changing Default Behavior of any API
With Ucommerce comes out of the box, a lot of APIs with default behavior, that works in most cases with most webshops. However not all business are alike and that is why Ucommerce enables you to override the default behavior of all APIs and services available.
Override the 80/20 APIs
The 80/20 APIs can be overriden in various ways:
- Libraries can be overriden by creating a new class and derive from the internal implementation, e.g. to override a
CatalogLibrary
API you'd derive fromCatalogLibraryInternal
and register it in the dependency injection container. - Context classes can be overriden in the same way or you can make a complete fresh implementation of the interfaces that drives the context classes.
- Lower level implementations such as queries, pricing services, shipping methods, pipeline tasks etc.
What is needed when changing the APIs or lower level components?
Regardless of what type in Ucommerce you're changing the recipe is always the same. There's always two things involved
-
Code
- Comes as no surprise. You need to either inherit a default implementation or create a new implementation of the given interface you're changing. There's always a hook-in. It is 'just' a matter of figuring out what and how.
-
Configuration
- Ucommerce relies heavily of IOC and dependency injection. We use
Castle windsor
as our tool for configuring the platform. When you have your code in place it is time to adjust the configuration.
- Ucommerce relies heavily of IOC and dependency injection. We use
Example overriding a component
Following this, we'll give a short example of how to modify the behavior in the platform. As said previously in this article, the recipe is the same, so consider this example a best practice way of changing anything in Ucommerce.
Override TransactionLibrary.GetShippingMethods()
As an example to show you how to achieve this we'll override the GetShippingMethods(Country)
on the ITransactionLibrary
.
For the example we'll assume that there are two types of products: "shipped goods" and "donations". Those are two different product definitions in our store:
Now this obviously requires two different shipping methods, since you do not ship a donation. We could choose to restrict the shipping methods on various levels, but in this case product definition will do.
The first thing we'll need to do is create a class and inherit Ucommerce.Api.TransactionLibrary
.
Now we can focus on the methods that we want to override. Let's assume that we cannot buy products and make donations on the same order. This will make the use case a little easier to deal with.
To make it even easier let's further assume that the donation products has a sku of: "donation".
A third and last assumption is that we have a shipping method of name "donation". We can then easily without fetching too much data look at the context and do appropriate actions:
public class MyTransactionLibrary : Ucommerce.Api.TransactionLibrary { public override ICollection<ShippingMethod> GetShippingMethods(Country country) { const string donationIdentifier = "donation"; var order = OrderContext.GetBasket(false).PurchaseOrder; //true creates the basket if it doesn't exists. In this case we'll leave it false if (order.OrderLines.Any(x => x.Sku == donationIdentifier)) { return ShippingMethod.Find(x => x.Name == donationIdentifier).ToList(); } //We did not find any products in the basket of type donation. //Let the base class handle the default behavior and get all except the donation shipping method. return base.GetShippingMethods(country).Where(x => x.Name != donationIdentifier).ToList(); } }
Registering the component
All there's left to do now is register the overriden service in the dependency injection container. Please refer to How to register a component in Ucommerce if you're interested in more details about components.