Skip to content

Instantly share code, notes, and snippets.

@ardeshireshghi
Created October 18, 2022 16:29
Show Gist options
  • Save ardeshireshghi/19f7bb2e84521ae2c64ee63a764e12ba to your computer and use it in GitHub Desktop.
Save ardeshireshghi/19f7bb2e84521ae2c64ee63a764e12ba to your computer and use it in GitHub Desktop.
A very naive solution for Dependency Injection
function createAppContainer() {
const bindingsMap = new Map();
const appContainer = {
bind(abstractClass, concreteClassOrFn) {
bindingsMap.set(abstractClass, concreteClassOrFn);
},
make(ClassToCreate, ...constructorArgs) {
const argTypes = ClassToCreate.argTypes || [];
// For now naively just use the args and don't inject
if (constructorArgs.length > 0) {
return new ClassToCreate(...constructorArgs);
} else {
const injectedArgs = argTypes.map((ArgClass) => {
const ClassToInjectOrFn = bindingsMap.get(ArgClass);
if (ClassToInjectOrFn) {
return Object.getPrototypeOf(ClassToInjectOrFn) === ArgClass
? make(ClassToInjectOrFn)
: ClassToInjectOrFn(appContainer);
} else {
if (ArgClass.argTypes) {
return make(ArgClass);
} else {
return new ArgClass();
}
}
});
return new ClassToCreate(...injectedArgs);
}
},
};
return appContainer;
}
const { bind, make } = createAppContainer();
class Bar {
getName() {
throw new Error('Bar should be implemented');
}
}
class CoolBar extends Bar {
getName() {
return 'really cool bar';
}
}
class Foo {
static get argTypes() {
return [Bar];
}
constructor(bar) {
this.bar = bar;
}
getBar() {
return this.bar;
}
}
class NiceFoo extends Foo {
getName() {
return 'nice foo';
}
}
class Pet {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
class Cat extends Pet {
constructor() {
super('cat')
}
}
class Consumer {
constructor(foo, pet) {
this.foo = foo;
this.pet = pet;
}
showFooNameAndBarName() {
console.log(this.foo.getName());
console.log(this.foo.getBar().getName());
}
showPetName() {
console.log(this.pet.getName())
}
}
Consumer.argTypes = [Foo, Pet]
bind(Foo, NiceFoo);
bind(Bar, CoolBar);
bind(Pet, (appContainer) => appContainer.make(Cat));
const consumer = make(Consumer);
console.log(consumer.showFooNameAndBarName());
console.log(consumer.showPetName());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment