Are there other way to solve the external dependency issue?
DynamoDB is tightly coupled to Amazon. Amazon built it. Unless you can identify a higher level of abstraction, just leave your class as it is. Identifying a higher level of abstraction involves analyzing all of the consumers of InternalDataStorageClient and possibly eliminating all references to ...
Correcly done dependency injection (IMNSHO) basically means "Instantiation is good, service containers are bad". Don't get strayed from correct path because of some convenience (eg. use being in language, container library existing).
For more about this issue, see my question of years ago, dealing with similar problem, when looking at root cause, ...
I found it! Well, at least for PHP. I'll go into great detail to explain my thought process, what I needed, my constraints and exactly how I found this piece of code.
So, as in my question, I needed a way to proxy a call to a service I created. That service is an API of some sorts to my module, the "I wrote all you'd possibly want to do with this module ...
The Other Option
Dependency via a reasonably defaulted property.
private Kitchen _kitchen;
public Kitchen Kitchen
return _kitchen ?? (_kitchen = new Kitchen(/*reasonable defaults*/);
//an validation logic here
There is no one-size fits all answer here. Context is key.
First option: hardcoded private dependency
The main issue here is that you're hardcoding (and hiding) the Kitchen dependency of Restaurant. If you want to be able to unit test them separately, then you can't do that as you're now unable to test Restaurant without using Kitchen. In other words, any ...
I'd go for dependency injection via constructor and/or parameter passing.
Let's debunk the cons:
App now has to know how to instantiate Kitchen.
There's no problem with that, as long as instantiation of concrete classes happen only in a factory class of factory methods (abstract factories, builders or any creational pattern that is suitable). Somewhere in ...
You can achieve very easily the feature to register types from a configuration file:
"A.Namespace.IServiceType1, A.Dll": "Another.Namespace.ImplementationType1, Another.Dll",
"Still.Different.Namespace.IServiceType2, Still.Different.Dll": "Namespace....
identify some value in it for our practical purposes.
Consider a class that knows just where to find what it needs to work. It needs 5 different things and reaches out into the rest of the code base to find them.
Consider a class that knows it needs 5 things and doesn't care where they come from.
Now, make a random change to your code base. Which class do ...
what limits developers from misusing those dependencies in inappropriate spots?
But nothing stops developers from misusing anything else in your code. DI isn't a tool to protect you from bad developers, it's a tool to make things easier to manage and to test. If you have developers who can't write well structured code, then you have bigger problems ...
Should A, B, C, know you have an application D where B and C are always BImpl and CImpl? I don't think so. That is a concern of D and no one else.
What need is a factory method.
Have a method that encapsulates that default logic for the D application, and leave that out of the actual interfaces and implementations.
One of the benefits of dependency injections is that you can compile, test, and use A without "knowledge" of BImpl or CImpl, but by adding them as defaults, you lose that benefit. You can still use dependency injection in your edge-cases (though Philip makes a good case about transitive dependencies), but you will always be paying the price for ...