I'm learning DI with tsyringe. I'm also totally new to the concept of DI.
The following snippet works and the container.resolve(Foo)
properly instantiate the dependencies.
import "reflect-metadata";
import { injectable, container } from "tsyringe";
class Database {
get() {
return "got-stuff-from-database";
}
}
@injectable()
class Foo {
constructor(private database: Database) {}
checkDb() {
return this.database.get();
}
}
const fooInstance = container.resolve(Foo);
console.log(fooInstance.checkDb());
//=> got-stuff-from-database
This is understandable. But the snippet below (mostly taken from their readme) is neither working for me nor I can understand, and nor I can understand why we need inject
when we have the above injectable
decorator. I'm sorry I searched online and found everyone is using it like everyone already know about it.
interface Database {}
@injectable()
class Foo {
constructor(@inject("Database") private database?: Database) {}
checkDb() {
return 'stuff';
}
}
const fooInstance = container.resolve(Foo);
console.log(fooInstance.checkDb());
So the main thing to keep in mind is that tsyringe is a Typescript library. When Typescript gets compiled to Javascript the interfaces are basically not there anymore (like the Database
interface in your example) so the DI magic that happens with the classes can't be done as usual. The documentation explains it like so:
Interfaces don't have type information at runtime, so we need to decorate them with @inject(...) so the container knows how to resolve them.
The reason it's still not working for you is because you have only told the DI framework that it has to look for an instance of something registered under the token "Database"
but there is actually nothing registered there. So to make it work you still need to tell tsyringe that "Database"
has a class or instance associated to it like so:
container.register("Database", {
useClass: SomeDatabaseImplementation
});
Note that you still would have to create said implementation because you can't instantiate interfaces. For deeper understanding I would recommend having a look at the source code of the library, it's fairly simple to understand and gives you a much better understanding of the inner workings.