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 avaiable.
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.
Override TransactionLibrary.GetShippingMethods()
As an example to show you how to achieve this we'll override the GetShippingMethods()
on the TransactionLibrary
.
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 derive TransactionLibraryInternal
. Since it doesn't contain any empty constructors we have to inject the right dependencies and send them to the base class. Fortunately the dependency injection container will figure out which dependencies to pass to the constructor in the first place.
public class ExtendedTransactionLibrary : TransactionLibraryInternal { public ExtendedTransactionLibrary ( ILocalizationContext localizationContext, IClientContext clientContext, ICatalogContext catalogContext, IOrderContext orderContext, CheckoutService checkoutService, IOrderService orderService, IPaymentMethodService defaultPaymentMethodService, IEmailService emailService, CatalogLibraryInternal catalogLibraryInternal ) : base(localizationContext, clientContext, catalogContext, orderContext, checkoutService,orderService, defaultPaymentMethodService,emailService,catalogLibraryInternal) { } }
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 appropiate actions:
public override ICollection<ShippingMethod> GetShippingMethods(Country country) { const string donationIdentifier = "donation"; var order = _orderContext.GetBasket(true).PurchaseOrder; //true creates the basket if it doesn't exists. 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 Overridden Library
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.