nozzlegear / ShopifySharp

ShopifySharp is a .NET library that helps developers easily authenticate with and manage Shopify stores.
https://nozzlegear.com/shopify-development-handbook
MIT License
742 stars 309 forks source link

Add ShopifySharp.Extensions.DependencyInjection project #963

Closed nozzlegear closed 9 months ago

nozzlegear commented 9 months ago

I'm working on adding a ShopifySharp.Extensions.DependencyInjection package in this pull request. The idea is that, for every service interface in ShopifySharp there will be a matching service "factory" interface that can be dependency injected like this:

public class OrdersController(IOrderServiceFactory orderServiceFactory) : Controller
{
    [HttpGet("order/{id}")]
    public async Task<ActionResult> GetOrder([FromRoute] long id)
    {
        var user = await DoSomethingToGetUser();
        var credentials = new ShopifySharp.ShopifyRestApiCredentials(user.ShopDomain, user.AccessToken);
        var orderService = orderServiceFactory.Create(credentials);
        var order = await orderService.GetAsync(id);

        return View(order);
    }
}

Adding the factories to the DI container can be done like this:

public void ConfigureServices(IServiceCollection services)
{
    services.AddShopifySharp();
}

Which will add every factory as a singleton to your DI container. The factories are configured to take a IRequestExecutionPolicy from the DI container as well, if you set one up:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IRequestExecutionPolicy, LeakyBucketExecutionPolicy>();
    services.AddShopifySharp();
}

If you only want to add certain factories to the container, you can skip the AddShopifySharp call and just add the factories you need:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IRequestExecutionPolicy, LeakyBucketExecutionPolicy>();
    services.AddSingleton<IOrderServiceFactory, OrderServiceFactory>();
    services.AddSingleton<ICustomerServiceFactory, CustomerServiceFactory>();
}

I'm open to feedback on the implementation! In a future pull request I want to add support for custom HttpClients.

One thing that I do plan on doing before merging this is moving all of the factories to the ShopifySharp package itself, and just keeping the DI setup/extension methods in the ShopifySharp.Extensions.DependencyInjection package. I think the factories are useful enough to have in ShopifySharp proper.

TODO

[1] A future improvement would run the generate_factories.fish script on the ShopifySharp project's builds and compare its output to previous runs, then publish the DI project if factories have changed.