Many people come from frameworks that implement Dependency Injection and IoC containers for everything (in my case Angular 2+), so, this group of people will try to use dependency injection and IoC containers in everything even outside those frameworks.
But, most of the implementation using DI is not using it to implement the Dependency inversion principle from SOLID (which is kind of impossible to implement without DI), they are just using it as a way of making the class easily testable doing something like this:
class Dependency {}
class SomeClass {
constructor(private dependency: Dependency) {}
}
But why not this:
class Dependency {
static global = new Dependency();
}
class SomeClass {
protected dependency = Dependency.global;
}
We can easily mock/stub this dependecy only by extending it:
class TestSomeClass extends SomeClass {
protected dependency = mock<Dependency>();
}
Is there any problem we could face by doing this instead of dependency injection?
1 Answer 1
It will be easier (and avoids the unneccessary usage of inheritance) by using an optional constructor parameter with a default value:
class SomeClass {
constructor(private dependency = new Dependency()) {}
}
This is known as Bastard Injection - and as you see from that former link, even Mark Seemann (author of several well-known books about DI) thinks this is ok as long as "Dependency" is not a foreign dependency. It does not cause more or less dependencies than your proposed solution, requires less code and is simpler. For testing, you can stay with
SomeClass objectUnderTest = new SomeClass(mock<Dependency>())
just as suggest by Filip Milovanović in a comment. And no, you don't need an IoC container for this.
Disclaimer: I am not a Typescript guy, I had to lookup the docs if Typescript supports this, it seems it does. If I made a syntactical error, feel free to fix it.
Explore related questions
See similar questions with these tags.
SomeClass objectUnderTest = new SomeClass(mock<Dependency>())
?