Getting started - maartenba/phpmef GitHub Wiki
PHPMEF is based on a .NET library, MEF, targeting extensibility of projects. It allows you to declaratively extend your application instead of requiring you to do a lot of plumbing. All this is done with three concepts in mind: export, import and compose. PHPMEF uses the same concepts in order to provide this extensibility features.
An example would be a Calculator
class, using a collection of IOperation
instances to do its work. Here's how you would build this + without+ PHPMEF:
class Calculator {
private $_operations = array();
public function __construct() {
$this->_operations[] = new AddOperation();
$this->_operations[] = new MultiplyOperation();
// ...
}
public function calculate($operationName, $a, $b) {
// ...
}
}
interface IOperation {
function getName();
function execute($a, $b);
}
class AddOperation implements IOperation {
public function getName() {
return '+';
}
public function execute($a, $b) {
return $a + $b;
}
}
class MultiplyOperation implements IOperation {
public function getName() {
return '*';
}
public function execute($a, $b) {
return $a * $b;
}
}
Imagine you would have to add extra IOperation
implementations: you would have to edit the Calculator
's constructor and instantiate new operations, add them to the internal operations array, ... There's a smell here: adding a new operation should not necessarily require you to modify the Calculator
class. Instead, adding a new IOperation
to the project should be enough.
Now let's try the above example using PHPMEF, adding some @import
and @export
attributes:
class Calculator {
/**
* @import-many IOperation
*/
public $_operations = array();
public function calculate($operationName, $a, $b) {
// ...
}
}
interface IOperation {
function getName();
function execute($a, $b);
}
/**
* @export IOperation
*/
class AddOperation implements IOperation {
public function getName() {
return '+';
}
public function execute($a, $b) {
return $a + $b;
}
}
/**
* @export IOperation
*/
class MultiplyOperation implements IOperation {
public function getName() {
return '*';
}
public function execute($a, $b) {
return $a * $b;
}
}
See that? There's absolutely no dependencies in the Calculator
class on a concrete IOperation
implementation. The only thing left to do is composing a new Calculator
using PHPMEF, matching defined @import
s with defined @export
s:
$calculator = new Calculator();
$compositionInitializer = new MEF_CompositionInitializer(new MEF_Container_Default());
$compositionInitializer->satisfyImports($calculator);
$result = $calculator->calculate('+', 1, 2);