Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Builder functions bindings #1640

Open
1 task done
alexis-valois opened this issue Nov 16, 2024 · 0 comments
Open
1 task done

Support for Builder functions bindings #1640

alexis-valois opened this issue Nov 16, 2024 · 0 comments
Assignees

Comments

@alexis-valois
Copy link

Is there an existing proposal similar to this?

  • I have searched the existing proposals

What are you proposing?

My idea is to make it possible to bind an object implementing the Builder Function pattern, in addition to typical JS "class" object.

Is there any specific group of users that will benefit from this?

Some JavaScript developpers dislike the use of the "class" and "this" keywords. It has to do with the fact that "this" could lead to some difficult to debug behaviours when passing an instance method to a callback without binding "this" to the class in the constructor, beforehand. Linters has rules to prevent the use of "this", and Whole books has been written with that in mind.

What problems are you trying to solve?

There's other ways to create Object that would not need the use of those keywords.

It is sometimes refered as the "Builder" pattern.

Here's an example :

// LiteralConsumer.ts

import { SomeService } from "./SomeService"
import { Consumer } from "./Consumer"

// no "class" or "implements" required
export default function(someService: SomeService ): Consumer { 
  function somePrivateStuff() {
   ...
  }
  return {
    consume: (): Promise<string> => {
         // no "this"
          somePrivateStuff();
          return someService.doSomething();
    }
  }
}

// usage

import LiteralConsumer from ./LiteralConsumer";

const service = ...;
// no "new" required
const instance = LiteralConsumer(service); 

Here, the function's argument serves as the object's construction dependencies injection hook, and the TypeScript type "Consumer" refers to its interface.

(Note the absence of "new")

The JavaScript closure mechanism makes it possible to use the returned method "consume" anywhere, even if it references the "someService" variable, as it is accessible in its declaration scope.

(Note the absence of "this")

Also, the "return" statement gives us an elegent solution to export only public stuff, making the prive ones "actually private", even at runtime.

At the moment, i don't think inversify's able to bind such "function object", because the binding interfaces expects "newable" arguments.

Ex :

container.bind<Consumer>(TYPES.Consumer).to(LiteralConsumer ).inSingletonScope();

The above line would lead to "Argument of type '(someService: SomeService) =>Consumer' is not assignable to parameter of type 'Newable'."

Do you have any references or examples that can illustrate your idea?

I have seen this feature in Awilix "asFunction" registration type.

What type of idea is this?

Copy of existing idea: Similar idea exists and this is a copy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants