If you are developing modules in Drupal, then you know how usefull services are!

Services is a way to make functions reusable. We use services often when integrating functions with other modules, but what if you want to modify the service belonging to another module? To avoid modifying another module codebase, you can override the service instead!

Here are the steps on how to override a service in Drupal 8.

Firstly identify the service you want to override.
Ex. In this case we will be overriding "address.country_repository" service.

img

Next is to create your own custom module to override the service.
After creating the basic files for a module, you can now create the file to which it will tell Drupal to override that specific service. Save it in "/ module_name / src / module_nameServiceProvider .php "
Ex.

<? php

namespace Drupal \ module_name;

use Drupal \ Core \ DependencyInjection \ ServiceProviderBase;
use Drupal \ Core \ DependencyInjection \ ServiceProviderInterface;
use Drupal \ Core \ DependencyInjection \ ContainerBuilder;
use Symfony \ Component \ DependencyInjection \ Reference;

/ **
 * Will provide ability to Override core Drupal services
 * /
class ModuleNameServiceProvider extends ServiceProviderBase implements ServiceProviderInterface {

  / **
   * {@inheritdoc}
   * /
  public function alter (ContainerBuilder $ container) {
      $ definition = $ container-> getDefinition ('address.country_repository');
      $ definition-> setClass ('Drupal \ module_name \ OverrideCountryRepository')- > addArgument (new Reference ('language_manager'));
    }
}

NOTE: Make sure when you create the file, user the proper camel casing. Ex.ModuleNameSerivceProvider.php

Lastly you can now create the file to which it will modify the service. Save it in "/module_name/src/OverrideCountryRepository.php"
Ex.

<? php

namespace Drupal \ module_name;

use Commerce Guys \ Addressing \ Country \ CountryRepository as ExternalCountryRepository;
use Drupal \ Core \ Cache \ CacheBackendInterface;
use Drupal \ Core \ Language \ LanguageManagerInterface;

/ **
 * Defines the country repository.
 *
 * Countries are stored on disk in JSON and cached inside Drupal.
 * /
Class OverrideCountryRepository extends ExternalCountryRepository {

  / **
   * {@inheritdoc}
   * /
  protected $ cache;

  / **
   * {@inheritdoc}
   * /
  public function __construct (CacheBackendInterface $ cache, LanguageManagerInterface $ language_manager) {
    parent :: __ construct ();

    $this->cache = $cache;
    // The getCurrentLanguage() fallback is a workaround for core bug #2684873.
    $language = $language_manager->getConfigOverrideLanguage() ?: $language_manager->getCurrentLanguage();
    $this->defaultLocale = $language->getId();
  }

  /**
   * {@inheritdoc}
   */
  protected function loadDefinitions($locale) {

      // Add your logic here

    if (isset($this->definitions[$locale])) {
      return $this->definitions[$locale];
    }

    $ cache_key ='address.countries.'. $ locale;
    if ($ cached = $ this-> cache-> get ($ cache_key)) {
      $ this-> definitions [$ locale] = $ cached-> data;
    }
    else {
      $ filename = $ this-> definitionPath. $ Locale.'. Json';
      $ this-> definitions [$ locale] = json_decode (file_get_contents ($ filename), TRUE);
      $ this-> cache-> set ($ cache_key) ), $ this-> definitions [$ locale], CacheBackendInterface :: CACHE_PERMANENT, ['countries']);
    }

    return $ this-> definitions [$ locale];
  }

}

Once thats done, make sure to clear cache!