Skip to main content

Type Script - Interfaces and Inversion of Control

Plan

The paln is to learn how Inversion of Control - IoC and Interfaces can be used to achieve loosely coupled design for programs in Type Script.

We learn by writing a program which automatically responds to Discord messages.

Program will listen for the messages, check for a specific word ex: ping in the message and then send reply to the message if the word is found in the message.

What is Discord ?

Discord is a group-chatting platform originally built for gamers, but which has since become a general use platform for all sorts of communities.

Pre Requisites

Discord

  1. Create an account in Discord https://discord.com/
  2. Download and install Discord application on your computer or open in Browser
  3. Add a Server -> Create My Own Server
  4. Browse the following url and create an application - https://discord.com/developers/applications
  5. After creating the application, create a Bot inside the application
  6. Copy Client ID of the application
  7. Add the bot to your Discord Server by replacing the client id in the following url: https://discord.com/api/oauth2/authorize?client_id=<REPLACE_YOUR_CLIENT_ID_HERE>&scope=bot&permissions=1

Node

Node js version 12 or higher should be installed on your computer

Install and Run

  1. Clone my GitHub repository - https://github.com/smarigowda/discord-bot

  2. Install node modules - npm install

  3. Rename the file .env.example to .env. Copy the bot token into .env file

  4. Compile/ Transpile the Type Script program - npm run compile

  5. Run the program - npm start

  1. Test the program (animated gif below). As you can see the bot program sends a reply if the message has a ping word in it.

Program Overview - Interfaces

Discord provides a node module to interact with its APIs https://www.npmjs.com/package/discord.js. It exposes Client class which can be used to login, listen to messages and send reply.

Our program has a Bot class which encapsulates discord Client. Bot class implemts IBot interface, having listen() method. This way the end user (which is index.ts file) does not need to worry about the internal details, but just use the listen() method.

In order to implement the search functionality we create two more interfaces IPingFinder and IMessageResponder

PingFinder and MessageResponder classes are concrete implementations of interfaces IPingFinder and IMessageResponder

Interface IPingFinder has one method isPing() which returns true if the message contains the word ping

Interface IMessageResponder has one method handle() which is used by the Bot class to handle the message and see if the message contains the word ping

The program gets concrete implementations using inversion of control.

Inversion of Control/ Dependency Injection

Inversify http://inversify.io/ is used to automatically provide dependencies. Inversify is a lightweight container providing inversion of control for JavaScript and Node.js apps powered by TypeScript.

By using inversion of control and interfaces, the program achieves loose coupling. Concrete classes can be replaced without needing any change in the program code where they are used, because the code does not refer to concrete implementation at all, it only refers to the interfaces.

Also, since we are uisng inversion of control, concrete classes need to be updated only at one place, inversify config file.