Reputation: 999
Main goal is to make core classes (instantiated with params) available from any place in application - in controllers, mappers, models, helpers etc.
For example, we have mapper which depends on Database object:
class Foo_Mapper
{
private $database;
public function __construct(Database $database)
{
$this->database = $database;
}
public function getFoo(array $criteria)
{
// ...
}
}
Variant 1: Basic dependency injection. The problem is that every time when I need to create mapper, I also need to instantiate a database object (with params).
$database = new Database($params);
$foo_mapper = new Foo_Mapper($database);
Variant 2: Registry. Core objects are instantiated and put into registry so every other object can easily access them.
// Somewhere in bootstrap...
$registry = Registry::getInstance();
$registry->database = new Database($params));
// Usage
$registry = Registry::getInstance();
$foo_mapper = new Foo_Mapper($registry->database);
Is there a better way to do what I want? Any drawbacks?
Upvotes: 1
Views: 480
Reputation: 40800
You could make this a Singleton. Like this:
class Database
{
private static $instance = null;
public static getInstance()
{
if (self::$instance == null) self::$instance = new Database();
return self::$instance;
}
// ... METHODS ... //
// ... METHODS ... //
// ..... //
}
Then you can use new Foo_Mapper(Database::getInstance()); It looks like you did this with your registry. Then you don't really need your registry anymore. Though if your classes are coded by someone else you would still have to use something like a registry or make a helper class/function for every of those classes that do not use the singleton pattern.
I think the way you illustrated it seems ok to me. It would be bad if you call your registry from within Foo_Mapper, because that class should probably not know about the existence of the registry, but this way looks ok.
Upvotes: 0
Reputation: 18859
Variant 1: Basic dependency injection. The problem is that every time when I need to create mapper, I also need to instantiate a database object (with params).
or passing it along. If you use a Dependency Injection Container, you would even have to do that manually: you simply add that you need to retrieve a Database, and a Database will be created (or reused) for you. Ask the Container to create a controller, and make sure you list your dependencies in the constructor. There are a few decent Dependency Injection containers for PHP, to wit:
For full disclosure: I wrote the last one.
Variant 2: Registry. Core objects are instantiated and put into registry so every other object can easily access them.
You could make the registry non-static, but if you're going to rely on a Registry object in your application, you might as well leave it static. This is a perfectly viable solution, with one obvious drawback: you don't know what objects are used by what objects by looking at the API. You'll have to dig into the code.
Upvotes: 1