Skip to content

thecodingmachine/common-container-definitions

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Scrutinizer Code Quality Build Status Coverage Status

Common container definitions for compiler-interop

This package contains common classes that implement the interfaces defined in compiler-interop

Installation

You can install this package through Composer:

{
    "require": {
        "mouf/common-container-definitions": "dev-master"
    }
}

The packages adheres to the SemVer specification, and there will be full backward compatibility between minor versions.

Usage

Classes in this package represent definitions of entries that can be put in a container. Those definitions needs to be passed to a compiler that will generate a container PHP class.

All the definitions in this package are implementing the Interop\Container\Compiler\DefinitionInterface. This means they can be fed to any compiler compatible with compiler-interop.

Creating a typical container entry

The typical container entry is an instance of a class that is passed some constructor arguments, with a few method calls (typically setters).

use Mouf\Container\Definition\InstanceDefinition;

$instanceDefinition = new InstanceDefinition("instanceName", "My\\Class");
$instanceDefinition->addConstructorArgument("foo");
$instanceDefinition->addConstructorArgument(["bar"]);

return $instanceDefinition->toPhpCode('$container', []);

will return an InlineEntry object containing:

  • expression: new My\Class("foo", ["bar"])
  • statements: empty
  • usedVariables: empty

You can pass references to other entries in the container by passing another object implementing the DefinitionInterface:

use Mouf\Container\Definition\InstanceDefinition;

$dependencyDefinition = new InstanceDefinition("dependency", "My\\Dependency");

$instanceDefinition = new InstanceDefinition("instanceName", "My\\Class");
$instanceDefinition->addConstructorArgument($dependencyDefinition);

return $instanceDefinition->toPhpCode('$container', []);

will return an InlineEntry object containing:

  • expression: new My\Class($container->get("dependency"))
  • statements: empty
  • usedVariables: empty

Method calls

You can add method calls on your entry using the "addMethodCall" method:

use Mouf\Container\Definition\InstanceDefinition;

$instanceDefinition = new InstanceDefinition("instanceName", "My\\Class");
$methodCall = $instanceDefinition->addMethodCall("setFoo");
$methodCall->addArgument(42);

return $instanceDefinition->toPhpCode('$container', []);

will return an InlineEntry object containing:

  • statements:
    $instanceName = new My\Class();
    $instanceName->setFoo(42);
  • expression: $instanceName
  • usedVariables: [ '$instanceName' ]

Setting public properties

You can add method calls on your entry using the "setProperty" method:

use Mouf\Container\Definition\InstanceDefinition;

$instanceDefinition = new InstanceDefinition("instanceName", "My\\Class");
$instanceDefinition->setProperty("foo", 42);

return $instanceDefinition->toPhpCode('$container', []);

will return an InlineEntry object containing:

  • statements:
    $instanceName = new My\Class();
    $instanceName->foo = 42;
  • expression: $instanceName
  • usedVariables: [ '$instanceName' ]

Inlining dependencies

If you perfectly know that a dependency will be used only by a given entry, you can inline the code of the dependency into the code generating the main entry. To do this, you just need to put null as the identifier for your instance.

use Mouf\Container\Definition\InstanceDefinition;

// null is passed as the identifier
$dependencyDefinition = new InstanceDefinition(null, "My\\Dependency");

$instanceDefinition = new InstanceDefinition("instanceName", "My\\Class");
$instanceDefinition->addConstructorArgument($dependencyDefinition);

return $instanceDefinition->toPhpCode('$container', []);

will return an InlineEntry object containing:

  • statements:
    $myDependency = new My\Dependency();
    $instanceName = new My\Class($myDependency);
  • expression: $instanceName
  • usedVariables: [ '$instanceName', '$myDependency' ]

Creating a parameter entry

A container does not store only objects. It can also store raw values. These values typically do not need to be stored in callbacks as resolving the callback would be an unnecessary burden. If you want to store a raw value, you can use the ParameterDefinition and directly pass the value of the parameter to this class.

use Mouf\Container\Definition\ParameterDefinition;

$parameterDefinition = new ParameterDefinition("parameterName", "value");

return $parameterDefinition->toPhpCode('$container', []);

will return an InlineEntry object containing:

  • statements: empty
  • expression: "value"
  • usedVariables: empty
  • lazilyEvaluated: false

This code will generate an entry "parameterName" in your container whose value is "value". You can pass any kind of scalar or array values to ParameterDefinition.

Creating a parameter entry that references a constant

If you want your parameter entry to actually point to a constant (declared with define) or a class constant (declared with const), you can use the ConstParameterDefinition.

use Mouf\Container\Definition\ConstParameterDefinition;

$parameterDefinition = new ConstParameterDefinition("parameterName", "My\\Class::CONSTANT");
return $parameterDefinition->toPhpCode('$container', []);

will return an InlineEntry object containing:

  • statements: empty
  • expression: My\\Class::CONSTANT
  • usedVariables: empty
  • lazilyEvaluated: false

This code will generate an entry "parameterName" in your container that directly points to My\\Class::CONSTANT.

Creating an alias

A container can store aliases to other container's entries. You can create an alias to another entry using the AliasDefinition class.

use Mouf\Container\Definition\ParameterDefinition;

$aliasDefinition = new AliasDefinition("alias", "aliased_entry");

When calling $container->get('alias'), you will be given the entry stored in aliased_entry. Generated code is:

  • expression: $container->get('aliased_entry')
  • statements: empty
  • usedVariables: empty

Creating a definition from a closure

You can define container entries using closures. When the entry is retrieved, the closure will be evaluated and the entry will be the return value of the closure.

use Mouf\Container\Definition\ClosureDefinition;
use Interop\Container\ContainerInterface;

$closureDefinition = new ClosureDefinition("closureDef", function(ContainerInterface $container) {
    return new My\Service();
});

Please note:

  • The closure should accept one parameter: the container on which dependencies will be fetched
  • The closure cannot use the $this keyword
  • The closure cannot use context (the use keyword in the closure declaration)
  • The code of the closure will actually be copied, not referenced

About

This package contains common classes that implement the interfaces defined in container-interop/compiler-interop

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages