Getting started - maartenba/phpmef GitHub Wiki

Getting started

What is PHPMEF about?

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 situation

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 @imports with defined @exports:


$calculator = new Calculator();

$compositionInitializer = new MEF_CompositionInitializer(new MEF_Container_Default());
$compositionInitializer->satisfyImports($calculator);

$result = $calculator->calculate('+', 1, 2);
⚠️ **GitHub.com Fallback** ⚠️