I have been following Akshay's video tutorials about SXC, the last one about creating a minion: https://www.konabos.com/blog/creating-a-minion-for-sitecore-commerce-xc-9/. In this tutorial he creates a Plugin with a minion that calculates loyalty points for customers based on previous orders by that customer. In the plugin he refers to multiple types that are found in other plugins, e.g. Order
, Customer
, LoyaltyComponent
(the latter type was created in another custom plugin in a previous tutorial).
How do I set up the dependencies to these types from my new minion plugin?
Or in general:
How do I refer to types that are declared in other commerce engine plugins (features)?
First thought was simply to refer to the other plugins directly, e.g. Sitecore.Commerce.Plugin.Orders
, Sitecore.Commerce.Plugin.Customers
, Plugin.Xxxx.Loyalty
but as the plugins are found in the feature-layer, I guess this is the wrong way to go, otherwise I would have features referencing each other.
Second thought was to refer to the Sitecore.Commerce.ServiceProxy
foundation project that is part of the commerce SDK. This proxy contains the types, deferred from the Commerce Engine API. The problem here is that the types of the ServiceProxy-project do not inherit from the base types found in Sitecore.Commerce.Core
so they are not directly usable with core functionality.
An example: In this method in my pipeline block I am trying to convert the order entities from a list to an object of type Order
, but it is not possible because Order
from the ServiceProxy project does not inherit from Sitecore.Commerce.Core.CommerceEntity
.
public override async Task<Customer> Run(Customer customer, CommercePipelineExecutionContext context)
{
var listName = $"Orders.ByCustomer-{customer.Id}";
var result = await _findEntitiesInListPipeline.Run(new FindEntitiesInListArgument(typeof(Order), listName, 0,int.MaxValue), context);
var customerOrderPoints = 0;
if (result?.List != null && result.List.Items.Any())
{
foreach (CommerceEntity entity in result.List.Items)
{
var order = (Order)entity; // <-- This is not possible because 'Order' is from ServiceProxy and inherits from another 'CommerceEntity' than the one found in Sitecore.Commerce.Core
if (order != null)
{
customerOrderPoints += order.HasComponent<LoyaltyComponent>()
? order.GetComponent<LoyaltyComponent>().PointsEarned
: 0;
}
var loyaltyComponent = customer.GetComponent<LoyaltyComponent>();
loyaltyComponent.PointsEarned = customerOrderPoints;
await _persistEntityPipeline.Run(new PersistEntityArgument(customer), context);
}
}
return customer;
}
So I can only make it work with the first approach but I don't want to go that way. Akshay's code is not on Github yet, so I can't see exactly how he has done.
EDIT: I noticed that the developer's guide for SXC 9 says
A plugin can also take a dependency on another plugin to extend its functionality.
This implies that it is okay to make direct references. But the Helix principles says that one feature module must never depend on another feature module, so perhaps the plugins should not be placed in the feature-layer like they are in this tutorial(?)