Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide interfaces for all services #362

Closed
nozzlegear opened this issue Apr 26, 2019 · 5 comments
Closed

Provide interfaces for all services #362

nozzlegear opened this issue Apr 26, 2019 · 5 comments

Comments

@nozzlegear
Copy link
Owner

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.

@evaldas-raisutis
Copy link

evaldas-raisutis commented May 2, 2019

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.

@Alfetta159
Copy link

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.

@nozzlegear
Copy link
Owner Author

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
Copy link
Owner Author

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

@nozzlegear
Copy link
Owner Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants