jeudi 18 juin 2020

Factory pattern with conditional dependencies between Services of same family

I have a task which involves multiple payment services being made available depending upon a user's subscription level.

I want to find the best way to handle the following situation.

If the user has a specific subscription level than the appropriate payment service should be made available. This is my current implementation

GatewayFactory : IGatewayFactory 
{
   GatewayFactory (IEnumerable<IGatewayService> service) 
   {
   }

   IGatewayService ResolveGateway(TypeEnum enum) 
   {
       .... based on the provided input I'm returning the correct instance of the IGatewayService 
   } 
} 

IGatewayService 
{
   /// used by GatewayFactory 
   TypeEnum Enum { get; }

   ... extra methods
}

MY problem concerns how to design some relations. This is in continuation of the task, In the case the GatewayService is unavailable for its target audience (type of subscription), then it should fall back to another (but still specific) GatewayService. Example GatewayService_C fails then GatewayService_A should kick in its place.

1st this is my registration

        _serviceCollection.AddScoped<IGatewayFactory, GatewayFactory >();
        _serviceCollection.AddScoped<IGatewayService , GatewayService_A>();
        _serviceCollection.AddScoped<IGatewayService , GatewayService_B>();
        _serviceCollection.AddScoped<IGatewayService , GatewayService_C>();

I could think of two solutions none of which I find it to be fit.

1st "solution" I could manipulate the order of the registration, registering GatewayService_A at the end and thus when injecting IGatewayService I get an instance of GatewayService_A, but, it is not an option.

2nd solution, works but it doesn't make sens. Letting GatewayService_C be aware of my list of other gateways. The solution would consists of Injecting the IEnumerable, just like in GatewayFactory, and then get whatever service I need in this case GatewayService_A.

What I want to do in the end is this

class GatewayService_C
{
     public GatewayService_C(IGatewayService service)
     {

     } 
}

where the IGatewayService is the instance of GatewayService_A.

I've tried having a base IGatewayService from which I just extend other more specific interfaces, the issue is that when register each specific gateway with its concrete type, I will not be able to inject into GatewayFactory the IEnumerable service, actually I can inject but It will be empty.

Some help for this situation ?

Aucun commentaire:

Enregistrer un commentaire