This is a design decision that appears to come up quite a lot: how to pass context through a method that doesn't need it to a method that does. Is there a right answer or does it depend on the context.
Sample code that requires a solution
// needs the dependency
function baz(session) {
session('baz');
}
// doesn't care about the dependency
function bar() {
baz();
}
// needs the dependency
function foo(session) {
session('foo')
bar();
}
// creates the dependency
function start() {
let session = new Session();
foo(session);
}
Possible solutions
- threadlocal
- global
- context object
- pass the dependency through
- curry baz and pass it into bar with the dependency set as the first arg
- dependency injection
Examples of where is comes up
HTTP request processing
Context objects in the form of request attributes are often used: see expressjs, Java Servlets or .net's owin.
Logging
For Java logging folk often use globals / singletons. See the typical log4j / commons logging / java logging patterns.
Transactions
Thread locals are often used to keep a transaction or session associated with a chain of method calls to avoid needing to pass them as parameters to all the methods that don't need them.