1

I have a clean architecture project that provide micro services, one of which is to access Agresso ERP web services.

https://***************/service.svc

it provide many services

  • https://**/service.svc?FooService/Foo
  • https://**/service.svc?BooService/Boo

each of which has it's own service reference(connected service), and each of which has many methods.

each call to any of the end point you need to pass credentials with it.

        var fooSoapClient = new FooSoapClient();
        var credentials = new WSCredentials
        {
            Username = "fakeuser",
            Password = "fakepassword",
            Client = "fakeclient",
        };
        var result =  fooSoapClient.GetFoosAsync(Foo filter,true,
                      credentials ); 

(P.S) credential class exist in all entities

namespace Foo1NS
{
  public partial class WSCredentials : object
  {
     public string Username {get;set;}

     public string Client {get;set;}

     public string Password {get;set;}
  }
}


 namespace Foo2NS
{
  public partial class WSCredentials : object
  {
     public string Username {get;set;}

     public string Client {get;set;}

     public string Password {get;set;}
  }
}

i can access all end points with no problem.

I have the following Questions:

  • Is there a generic solution i can follow for not to Fall in DRY?
  • is there a design pattern that best target this issue?
Dicekey
  • 405
  • 4
  • 12
  • 1
    I'd personally just encapsulate the implementation of each service in its own class. Perhaps use a base class to hold the URL and credentials for each service. – Wheels73 Oct 29 '18 at 14:43

1 Answers1

0

Here is what I've done in the past, it fits in well into Dependency Injection/containers if you use that as well. The key thing here is to define an single interface that all services will implement. Your code that uses this should only be using the interface.

Each class should implement an interface you define, e.g. IWebServiceOperations

public interface IWebServiceOperations
{
    WebServiceOperationResult GetFooAsync(WebServiceOperationRequest request);
}

I'll leave you to figure out the classes WebServiceOperationResult/Request, they just hold your request/response variables, including credentials.

Then each webservice you need to implement is done in a separate class. You also dictate in the constructor what type of implementation this is (FooSoap1 vs FooSoap2) e.g.

public class FooSoapClient : BaseClient, IWebServiceOperations
{  
    public FooSoapClient() : base(Clients.FooSoap1) 

    public GetFooAsync(...)
    {
         ...
    }  
}

public class BaseClient
{
    private readonly eFooServiceType _serviceType;
    public eFooServiceType ServiceType {
        get{
            return _serviceType;
        }
    }

    protected BaseClient(eFooServiceType service)
    {
        _serviceType = service;
    }
}

Now you should have a bunch of class references. Either your DI container can resolve these for you, based on the service type you want, or you could add them to a Dictionary, so if you wanted to operate against FooSoap1, you'd do...

var fooSoapClient1 = myServices[Clients.FooSoap1];
await fooSoapClient1.GetFooAsync(...)
raterus
  • 1,980
  • 20
  • 23