官术网_书友最值得收藏!

Service with dependencies

A service with dependencies has dependencies in the constructor that we need help resolving. Without this resolution process, we can't create the service. Such a service may look like this:

export class Service {
constructor(
Logger logger: Logger,
repository:Repository
) {}
}

In this code, our service has two dependencies. Upon constructing a service, we need one Logger instance and one Repository instance. It would be entirely possible for us to find the Logger instance and Repository instance by typing something like this:

import { Service } from './service'
import logger from './logger';
import { Repository } from './repository';

// create the service
let service = new Service( logger, new Repository() )

This is absolutely possible to do. However, the code is a bit tedious to write every time I want a service instance. When you start to have 100s of classes with deep object dependencies, a DI system quickly pays off.

This is one thing a Dependency Injection library helps you with, even if it is not the main motivator behind its existence. The main motivator for a DI system is to create loose coupling between different parts of the system and rely on contracts rather than concrete implementations. Take our example with the service. There are two things a DI can help us with:

  • Switch out one concrete implementation for another 
  • Easily test our construct

To show what I mean, let's first assume Logger and Repository are interfaces. Interfaces may be implemented differently by different concrete classes, like so:

import { Service } from './service'
import logger from './logger';
import { Repository } from './repository';

class FileLogger implements Logger {
log(message: string) {
// write to a file
}
}

class ConsoleLogger implements Logger {
log(message: string) {
console.log('message', message);
}
}

// create the service
let service = new Service( new FileLogger(), new Repository() )

This code shows how easy it is to switch out the implementation of Logger by just choosing FileLogger over ConsoleLogger or vice versa. The test case is also made a lot easier if you only rely on dependencies coming from the outside, so that everything can therefore be mocked.

主站蜘蛛池模板: 九龙县| 清流县| 陕西省| 珠海市| 青河县| 来安县| 鹰潭市| 安义县| 藁城市| 沧源| 铜鼓县| 哈尔滨市| 迁西县| 蕲春县| 曲周县| 宝丰县| 天祝| 台州市| 昌平区| 商丘市| 航空| 永春县| 北流市| 翁牛特旗| 塔城市| 安康市| 闸北区| 赣州市| 图木舒克市| 修文县| 金昌市| 昂仁县| 松桃| 磐安县| 鸡东县| 津市市| 恩平市| 潜江市| 石台县| 柘荣县| 大石桥市|