Eu entendo que possa dar esta impressão, principalmente pelo fato de que a minha explicação de DI é, de certa forma, simplificada.
Dito isto, cabe observar que, ainda que seja possível usar Strategy
sem DI
, na grande maioria dos casos, DI
faz uso de Strategy
.
Imagine, por exemplo, que temos um use case createUser
que depende de um UsersRepository
e que este, por sua vezes, possui três implementações possíveis:
SqliteUsersRepository
-> Que usa SQLitePostgresUsersRepository
-> Que usa PostgresInMemoryUsersRepository
-> Que faz as operações in-memory
Uma possível implementação pra esse nosso application service é:
export const createUser = async (userDto) => {
const persistenceMechanism = process.env.PERSISTENCE_MECHANISM;
const repositoryMatrix = {
"SQLite": SqliteUsersRepository,
"Postgres": PostgresUsersRepository,
"InMemory": InMemoryUsersRepository
};
const repository = repositoryMatrix[persistenceMechanism];
const createdUser = await repository.createUser(userDto);
return createdUser;
};
E no nosso controller:
app.post("/users", async (req, res) => {
const userDto = req.body;
const createdUser = await createUser(userDto);
res.send(createdUser);
});
Neste caso, estamos usando Strategy, mas não estamos usando DI, dado que não estamos criando uma versão de createUser
com as suas dependências pré-fixadas.
Todavia, se fizermos:
export const makeCreateUser = ({ usersRepository }) => async (userDto) => {
const createdUser = await usersRepository.createUser(userDto);
return createdUser;
};
E no controller (poderiamos ter um container, mas farei no controller pra simplificar):
app.post("/users", async (req, res) => {
const persistenceMechanism = process.env.PERSISTENCE_MECHANISM;
const repositoryMatrix = {
SQLite: SqliteUsersRepository,
Postgres: PostgresUsersRepository,
InMemory: InMemoryUsersRepository,
};
const repository = repositoryMatrix[persistenceMechanism];
const createUser = makeCreateUser({
usersRepository: repository
})
const userDto = req.body;
const createdUser = await createUser(userDto);
res.send(createdUser);
});
Ainda temos Strategy, mas adicionalmente temos DI, dado que o createUser
é criado a partir de uma factory function, onde injetamos a estratégia que queremos usar.
O ponto de "virada" entre Strategy e DI, é que DI envolve sempre alguma aplicação parcial de funções.