Create a custom processor
For two-way synchronization to work, a processor must be present that compares the two entities originating from Sitecore and the external system respectively.
A base processor Sitecore.Commerce.Pipelines.Products.ResolveChangesProcessor does most of the work and resolves the configured SynchronizationStrategy to use for comparison.
The responsibility of the processor is to read two product entities from Sitecore and the external system respectively, compare and resolve the changes, and return the resulting entity along with an indication of where the result must be saved.
The current ResolveChangesProcessor implementation only saves one collection of resulting entities to be saved, which means the same instances are saved to both Sitecore and the external system if the direction is set to both.
A custom version could save different versions to two separate collections to be saved in the two systems respectively.
The two processors responsible for reading the product entities from Sitecore and the external system respectively, must write the result to two distinct and different pipeline arguments, so that they do not interfere.
To create a custom processor for a given entity type:
-
Create a new class that inherits from the
ResolveChangesProcessorprocessor.Leave the constructor empty but make sure to call the base constructor.
-
Override the
GetSitecoreEntitiesmethod.The method must read the stored Sitecore entities and return an enumerable collection of objects of the given type. The naming convention for the
PipelineArgscollection is to prefix the type name with the word Sitecore as the key. For example,SitecoreManufacturers. -
Override the
GetExternalCommerceSystemEntitiesmethod.The method must read the stored external entities and return an enumerable collection of objects of the given type. The naming convention for the
PipelineArgsis to simply use the type name as the key. For example,Manufacturers. -
Override the
SaveEntitiesmethod.The method must save the resulting entities to the
PipelineArgscollection. The naming convention is to use the type name as the key. For example,Manufacturers.
The implementation of the ResolveManufacturerChanges processor is shown in the following code snippet:
public class ResolveManufacturersChanges : ResolveChangesProcessor
{
/// <summary>
/// Initializes an instance of the <see cref="ResolveManufacturersChanges" /> class.
/// </summary>
/// <param name="synchronizationStrategy">The synchronization strategy.</param>
public ResolveManufacturersChanges([NotNull] ISynchronizationStrategy synchronizationStrategy) : base(synchronizationStrategy)
{
}
/// <summary>
/// Gets entities stored in Sitecore.
/// </summary>
/// <param name="args">The arguments.</param>
/// <returns>Sitecore entities.</returns>
protected override IEnumerable<ProductEntity> GetSitecoreEntities(ServicePipelineArgs args)
{
return args.Request.Properties["SitecoreManufacturers"] as IEnumerable<ProductEntity> ?? Enumerable.Empty<Manufacturer>();
}
/// <summary>
/// Gets entities stored in external commerce system.
/// </summary>
/// <param name="args">The arguments.</param>
/// <returns>External commerce system entities.</returns>
protected override IEnumerable<ProductEntity> GetExternalCommerceSystemEntities(ServicePipelineArgs args)
{
return args.Request.Properties["Manufacturers"] as IEnumerable<ProductEntity> ?? Enumerable.Empty<Manufacturer>();
}
/// <summary>
/// Saves the entities to the arguments.
/// </summary>
/// <param name="args">The arguments.</param>
/// <param name="productEntities">The product entities.</param>
protected override void SaveEntities(ServicePipelineArgs args, IEnumerable<ProductEntity> productEntities)
{
args.Request.Properties["Manufacturers"] = productEntities.Cast<Manufacturer>();
}
}