dev-mastery / comments-api

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

What is your opinion of Awilix for DI?

grantcarthew opened this issue · comments

Hi Bill @arcdev1,

I just discovered Awilix.

Was interested in your opinion being that dependency injection is a big part of your comments-api example and video, and I respect your opinion.

I like the way is wires up the arguments for you.

Regards,

Grant.

Hello @grantcarthew and thanks for the question. You may be surprised to hear that while I am a big fan of dependency injection in JavaScript to gain some of the advantages that Interfaces provide in other languages, I am not a big fan of DI frameworks in JavaScript. Mainly because I believe it's better to localize our injections and most DI frameworks encourage us to centralize our injections. I also haven't found the need for most of the fancier features, they usually just add overhead and complexity, without too much upside.

Having said that, I know some people like them and if we're disciplined we can still use them in a localized way. For example, we could use Awilix in the various index.js files throughout this repo to localize the injections. Here is src/use-cases/index.js re-written to use Awilix. There's a few less lines of code but it's a bit harder to figure out what depends on what exactly.

import awilix from 'awilix'
import makeAddComment from './add-comment'
import makeEditComment from './edit-comment'
import makeRemoveComment from './remove-comment'
import makeListComments from './list-comments'
import makeHandleModeration from './handle-moderation'
import commentsDb from '../data-access'
import isQuestionable from '../is-questionable/is-questionable'

const { createContainer, asValue, asFunction } = awilix
const container = createContainer()

container.register({
  commentsDb: asValue(commentsDb),
  isQuestionable: asValue(isQuestionable),
  makeAddComment: asFunction(makeAddComment),
  makeEditComment: asFunction(makeEditComment),
  makeRemoveComment: asFunction(makeRemoveComment),
  makeListComments: asFunction(makeListComments),
  makeHandleModeration: asFunction(makeHandleModeration)
})

const commentService = Object.freeze({
  addComment: container.resolve(makeAddComment),
  editComment: container.resolve(makeEditComment),
  handleModeration: container.resolve(handleModeration),
  listComments: container.resolve(makeListComments),
  removeComment: container.resolve(makeHanldeModeration)
})

export default commentService

Agreed. This is why I was interested in your opinion.

I found the code with Awilix a little more difficult to read and I see readability to be a high priority in code.

Thanks for your thorough reply.

It is adding more dependencies to your application though @JamieCorkhill. Adding more APIs to learn. I believe in KISS everywhere possible. It is also why I haven't written projects in Typescript.

Thanks for the comment.

I mean, you can use JSDoc and get typing support using flow-jsdoc (I am considering forking and maintaining this project for personal use, since the maintainer is looking for a successor: facebook/flow#5670 (comment) ).

On the other hand, I think, I should give awilix a spin before I can make a judgement.