Possible Duplicate:
Dependency Hell — how does one pass dependencies to deeply nested objects?
In a system built around strong dependency injection, I'm wondering how to deal with a contrived situation like this:
<?php
class LogWriter
{
public function write(Log $log)
{
echo $log->getMessage();
}
}
class Log
{
private $message;
public function setMessage($message)
{
$this->message = $message;
}
public function getMessage()
{
return $this->message;
}
}
class Logger
{
private $writer;
public function __construct(LogWriter $writer)
{
$this->writer = $writer;
}
public function write($message)
{
// Here is the dependency
$log = new Log();
$log->setMessage($message);
$this->writer->write($log);
}
}
The Logger::write() method creates an instance of Log, and passes it to the log writer. My gut tells me that's a bad approach, and a month from now I'm going to be tracking down a bug related to it, and I might want to switch the Log class for something else during testing.
But how to avoid it? The only thing that comes to mind is passing a Log type to the Logger constructor, and changing my Logger class to this:
class Logger
{
private $writer;
private $log_type;
public function __construct(LogWriter $writer, $log_type)
{
$this->writer = $writer;
$this->log_type = $log_type;
}
public function write($message)
{
$log = new $this->log_type();
$log->setMessage($message);
$this->writer->write($log);
}
}
And then creating a new Logger instance like this:
$log_writer = new LogWriter();
$logger = new Logger($log_writer, "Log");
But that feels a bit hackish. So how do you deal with micro-dependencies like this?
Note: I'm using the logging classes as an example, and I'm not looking for a solution to this exact problem. I would probably just use an array instead of the Log class.
Edit: In a more complex situation, I might pass a dependency injection container to the Logger class, and use that to create an instance of Log, but that seems overly complicated for a simple logger class.