ShopifySharp icon indicating copy to clipboard operation
ShopifySharp copied to clipboard

Provide interfaces for all services

Open nozzlegear opened this issue 5 years ago • 3 comments

I've been using a lot of dependency injection lately, but have found it mildly difficult to test any function that uses a ShopifySharp service since the package provides no interfaces for the services.

nozzlegear avatar Apr 26 '19 19:04 nozzlegear

I've been lately using ShopifySharp (cool lib!) in a DI heavy project which also runs integration tasks in multi tenant environment. Having interfaces would help a great deal, but I've also been slightly struggling with multi-tenant aspect of our integrations.

I ended up solving it so far with a two-fold solution.

Firstly, all resource services are provided by injecting a factory method into a constructor (for a command handler, for example) like:

public class CreateProductHandler : ICommandHandler<CreateProduct>
{
    private readonly Func<ShopAlias, ProductService> productServiceFactory;

    public CreateProductHandler(Func<ShopAlias, ProductService> productServiceFactory)
    {
        this.productServiceFactory = productServiceFactory;
    }
    public Task Handle(CreateProduct command)
    {
        var productService = this.productServiceFactory.Invoke(command.shopAlias);
        // ...
    }
}

This allows to get tenant-appropriate instance of ProductService by invoking the factory method. ShopAlias is passed down through a Command message. DI then has to be setup at Startup of course, for example with IServiceCollection:

services.Add<Func<ShopAlias, ProductService>>(x => shopAlias => 
{
  var shopConfigurations = x.GetService<ShopConfigurations>();
  var shopConfiguration = shopConfiguration.ByAlias(shopAlias);

  return new ProductService(shopConfiguration.Url, shopConfiguration.Token);
});

Now back to topic at hand, interfaces on Services would be great, since I could replace 'new' part with something that calls a factory service instead and return any implementation of IProductService.

evaldas-raisutis avatar May 02 '19 19:05 evaldas-raisutis

I find that DI is not necessarily an issue, but unit testing is painful w/o interfaces on all of the non-data object classes.

Alfetta159 avatar Jul 12 '22 17:07 Alfetta159

I agree that testing can be annoying without interfaces. I'm looking into implementing interfaces for all of the service classes within the next couple of weeks. Hopefully there's some kind of Roslyn analyzer tool out there that can do it all for me and save me a lot of copying/pasting! 😅

nozzlegear avatar Aug 15 '22 19:08 nozzlegear

Interfaces are being implemented in this PR: #891. Merging soon!

nozzlegear avatar Jun 25 '23 07:06 nozzlegear

All services except for two – AuthorizationService and MultipassService, because they're static – now have interfaces as of ShopifySharp 6.1.1 on Nuget.

nozzlegear avatar Jun 27 '23 18:06 nozzlegear