Dependency Injection and Unit of Work pattern
- by sunwukung
I have a dilemma. I've used DI (read: factory) to provide core components for a homebrew ORM.
The container provides database connections, DAO's,Mappers and their resultant Domain Objects on request.
Here's a basic outline of the Mappers and Domain Object classes
class Mapper{
public function __constructor($DAO){
$this->DAO = $DAO;
}
public function load($id){
if(isset(Monitor::members[$id]){
return Monitor::members[$id];
$values = $this->DAO->selectStmt($id);
//field mapping process omitted for brevity
$Object = new Object($values);
return $Object;
}
}
class User(){
public function setName($string){
$this->name = $string;
//mark modified by means fair or foul
}
}
The ORM also contains a class (Monitor) based on the Unit of Work pattern i.e.
class Monitor(){
private static array modified;
private static array dirty;
public function markClean($class);
public function markModified($class);
}
The ORM class itself simply co-ordinates resources extracted from the DI container. So, to instantiate a new User object:
$Container = new DI_Container;
$ORM = new ORM($Container);
$User = $ORM->load('user',1);
//at this point the container instantiates a mapper class
//and passes a database connection to it via the constructor
//the mapper then takes the second argument and loads the user with that id
$User->setName('Rumpelstiltskin');//at this point, User must mark itself as "modified"
My question is this. At the point when a user sets values on a Domain Object class, I need to mark the class as "dirty" in the Monitor class. I have one of three options as I can see it
1: Pass an instance of the Monitor class to the Domain Object. I noticed this gets marked as recursive in FirePHP - i.e.
$this-Monitor-markModified($this)
2: Instantiate the Monitor directly in the Domain Object - does this break DI?
3: Make the Monitor methods static, and call them from inside the Domain Object - this breaks DI too doesn't it?
What would be your recommended course of action (other than use an existing ORM, I'm doing this for fun...)