First of all, you have not two injecting dependencies, but three. The answer is: not only two dependencies are not tightly coupled, but there is no coupling issue at all. You probably think that two instances are coupled via common
IAccountInfo
, but… there is nothing like that. You have, generally, too different instances of this interface, and these two instances could be even of different types. Let's see.
Your problem is just not seeing what you are doing. Perhaps this is the problem of not seeing amazingly simple thing behind a lot of unrelated code. Perhaps all you need is to shorten up the code to see at the root of the problem. Scratch all unrelated code, and you will see:
interface IA { }
interface IB { }
class AGood : IA { }
class ABetter : IA { }
class B : IB {
public B(IA a) { this.a = a; }
IA a;
}
class C {
public C(IB b, IA a) { this.b = b; this.a = a; }
IA a;
IB b;
}
Note that the fact that your top level injection container (client)
TestCallFlowApplication
implement some application, it totally irrelevant to the problem. In my sample, this is
C
, the interface is scratched out. I intentionally provided two different implementations of
IA
(analog of
IAccountInfo
of your sample), just to justify my point. Here how you can use all those implementations:
IA a1 = new AGood();
IA a2 = new ABetter();
IB b = new B(a1);
C c = new C(b, a2);
Note that you have two injected
IA
instances. Not only they are two independent objects, but they also could be of two different and even unrelated (not bound by inheritance relationship except to the one with this interface) types. Where do you see tightness? :-)
My second point… is harder to explain. You have to see the application behind the abstract design. Often, it requires more abstract thinking than just looking at the code construct structurally. If you think of a single interface, understanding of its purpose and qualities requires you to imagine simultaneously all possible implementations of it, from this standpoint a theoretically infinite number of them. But, to many, it would be easier to imagine some implementations related to a particular set of application goal. Seemingly, you behave like you feel your responsibility for "implementing the design pattern right". But this is not your real responsibility. It's the author of design pattern is responsible for proposing something potentially useful for some application. It's not your goal to "please" the author of some pattern or a principle. If you go from the application goals, it may help you to gain clear vision. On this topic, for some food for though, please see my past answer:
Please suggest me some basic C++ project with design patters.
As to your "
What I have tried" section, please see my comment to the question. It's a good idea to explain what you
really tried; in this case, it would be some modified variant of your code.
—SA