1

I'm making an application that uses an external API. But I don't want my application to be dependant on the API. So I have been reading about how to achieve this. I read that the thing I want is loose coupling. I want to loosely couple my class that uses the external API from the rest of my application. My question is how do I achieve this. If read about different design patterns, I can't find one that helps with my problem.

public class GoogleCalendarService
{
   private const string CalendarId = ".....";

   private CalendarService Authenticate(string calendarId)
   {
      ...
   }

   public void Create(Booking newBooking, string userId)
   {
      ...

      InsertEvent(newEvent, userId);
   }

   private void Insert(Event newEvent, string userId)
   {
       call authenticate account

       ....
   }

   public List<Booking> GetEvents()
   {
       call authenticate account

       ...
   }
}

Above is my code for the class that uses the external API. In the rest of my application I use this class the following way:

public class MyApplication
{
   private void MyFunction()
   {
       GoogleCalendarService googleCalendarService = new GoogleCalendarService();

       googleCalendarService.CreateEvent(..., ...)
   }
}

I do this on multiple places in my application. So my question is: How can I loosely couple the API class from the rest?

Edit: I probably want a general calendar service interface that makes it easier to replace the google calendar service with an other calendar service when needed.

  • 3
    Dependency Injection. – H H May 27 '18 at 18:48
  • See [this](https://stackoverflow.com/q/2132772/60761) for a start. – H H May 27 '18 at 18:51
  • But define how 'loose' you want it. Would you want to depend on an `IGoogleCalendarService` or does it have to be an `IGeneralCalendarService` ? – H H May 27 '18 at 18:55
  • @HenkHolterman I want to be able to simply remove the GoogleCalendarService class from my application. (When it needs to be replaced for example) And replaced with an other calendar service. –  May 27 '18 at 18:57
  • OK, that is the IGeneralCalendarService and you will need wrappers. Do [edit] your question, comments don't count here. – H H May 27 '18 at 18:59

2 Answers2

3

that makes it easier to replace the google calendar service with an other calendar service

The main pattern you will want to look at is Adapter. But you would want to use that in combination with Dependency Injection.

The DI first:

public class MyApplication
{
   // constructor injection
   private IGeneralCalendarService  _calendarService;
   public MyApplication(IGeneralCalendarService  calendarService)
   {
     _calendarService = calendarService;  
   }

   private void MyFunction()
   {
       _calendarService.CreateEvent(..., ...)
   }
}

And the Adapter would look something like

public class GoogleCalendarServiceAdapter : IGeneralCalendarService  
{
   // implement the interface by calliong the Google API.
}

In addition you will need generic classes for Event etc. They belong to the same layer as the interface.

H H
  • 263,252
  • 30
  • 330
  • 514
  • Can you explain to me why an adapter is a good solution. If I make an interface and use dependency injection in addition to what I have now, wouldn't that be sufficient. Because I will always have one calendar service, never more than one. –  May 27 '18 at 19:17
  • i was also thinking of same solution, but didn't knew it's called adapter – Ehsan Sajjad May 27 '18 at 19:19
  • Yes, you could consider your GoogleCalendarService class a wrapper for the bare HttpClient calls. But you might run into problems later when mapping to another service. More layers is more control. As a PoC, pick another service and see how well you can reuse Event and Booking. – H H May 27 '18 at 19:19
2

You need to write a wrapper around that API. And rewrite every Output/Input of that API with your wrapper IO. And after that, you can take advantage of Dependancy Injection to use your own code. By this way you can have an abstraction layer around that API

Armin Neo
  • 78
  • 1
  • 5