The following is the example of a hidden dependency:
class Foo
{
void doSomething() //a visible method signature
{
//the body of this method is an implementation detail
//and is thus hidden
new Bar().doSomething();
}
}
In the above example, Bar
is a dependency for Foo
because Foo
relies on the collaboration of Bar
.
It is hidden because the dependency on Bar
is not explicit in the constructor of Foo
or method signatures for Foo
.
Think of a class as defining a visible contract exposed to collaborators. The methods and constructor signatures are part of that contract. The body of the method doSomething()
is hidden because it is an internal implementation detail of the class that is not exposed in the contract. All that we know from the signature is that there is a method called doSomething()
that is of return type void
.
For a counterexample, we could refactor the class to make the dependencies manifest:
class Foo
{
private readonly Bar bar;
Foo(Bar bar) //the constructor signature is visible
{
this.bar = bar;
}
void doSomething()
{
bar.doSomething();
}
}
In the above example, Bar
is explicitly defined as a dependency in the exposed signature for the constructor.
Alternatively we could do:
class Foo
{
void doSomething(Bar bar) //method signature is visible
{
bar.doSomething();
}
}
Now the dependency on Bar
for the method doSomething
is visible as it is included in the method signature for doSomething
.