Implementing IPriceService with default IPriceService as its dependency
In EPiServer Commerce prices are loaded via the IPriceService and IPriceDetailService. I needed to customise the IPriceService logic but just to tweak the price filtering and still intend to call the default IPriceService internally to reuse the base functionality.
This is where confusion ensues, how does one configure the dependency resolver (StructureMap) to return my custom price service implementation which itself has a dependency on the same IPriceService interface? Turns out StructureMap has a method called EnrichWith to achieve this.
So I have my implementation called “CustomPriceService” and the default EPiServer implmentation is “PriceServiceDatabase“. My CustomPriceService constructor looks like this:
public CustomPriceService(IPriceService defaultPriceService)
{
this._defaultPriceService = defaultPriceService;
}
Now I have the local field _defaultPriceService that I can call for default functionality throughout my custom implementation and it still retains the injected abstraction for unit testing purposes.
To configure StructureMap all that is needed is:
container.For<IPriceService>().Use<PriceServiceDatabase>().EnrichWith((context, systemPriceService) => new CustomPriceService(systemPriceService));
When an IPriceService dependency is resolved StructureMap will get the default EPiServer Commerce “PriceServiceDatabase” and then create my “CustomPriceService” passing the PriceServiceDatabase into the constructor.
If your constructor needs other dependencies you can use the “IContext” that EnrichWith provides, for example:
container.For<IPriceService>().Use<PriceServiceDatabase>().EnrichWith((context, systemPriceService) => new CustomPriceService(systemPriceService, context.GetInstance<ICurrentMarket>()));
Hopefully this will help anyone trying to figure out how to get StructureMap to configure a dependency for a given type to itself have a dependency on the same type.