Adds a GameBuilder to allow better dependency injection

This commit is contained in:
Vassyli
2017-06-14 11:39:14 +02:00
parent 329430c547
commit 867843dddd
5 changed files with 217 additions and 15 deletions
+6 -1
View File
@@ -64,7 +64,12 @@ class Bootstrap
$pdo = $this->connectToDatabase($dsn, $user, $password);
$entityManager = $this->createEntityManager($pdo);
$this->game = new Game($config, $this->logger, $entityManager, $cwd);
$this->game = (new GameBuilder())
->withConfiguration($config)
->withLogger($this->logger)
->withEntityManager($entityManager)
->withCwd($cwd)
->create();
return $this->game;
}
+12
View File
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* Exception if a builder is missing an argument
*/
class BuilderException extends CoreException
{
}
+36 -12
View File
@@ -85,24 +85,36 @@ class Game
*/
public function getModuleManager(): ModuleManager
{
if ($this->moduleManager === null) {
$this->moduleManager = new ModuleManager($this);
}
return $this->moduleManager;
}
/**
* Sets the game's module manager.
* @param ModuleManager $moduleManager
*/
public function setModuleManager(ModuleManager $moduleManager): void
{
$this->moduleManager = $moduleManager;
}
/**
* Returns the game's composer manager.
* @return ComposerManager The game's composer manager.
*/
public function getComposerManager(): ComposerManager
{
if ($this->composerManager === null) {
$this->composerManager = new ComposerManager($this->cwd);
}
return $this->composerManager;
}
/**
* Sets the game's composer manager.
* @param ComposerManager $composerManager
*/
public function setComposerManager(ComposerManager $composerManager): void
{
$this->composerManager = $composerManager;
}
/**
* Returns the game's entity manager.
* @return EntityManagerInterface The game's database entity manager.
@@ -118,24 +130,36 @@ class Game
*/
public function getEventManager(): EventManager
{
if ($this->eventManager === null) {
$this->eventManager = new EventManager($this);
}
return $this->eventManager;
}
/**
* Sets the game's event manager.
* @param EventManager $eventManager
*/
public function setEventManager(EventManager $eventManager): void
{
$this->eventManager = $eventManager;
}
/**
* Returns the game's dice bag.
* @return DiceBag
*/
public function getDiceBag(): DiceBag
{
if ($this->diceBag === null) {
$this->diceBag = new DiceBag();
}
return $this->diceBag;
}
/**
* Sets the game's dice bag.
* @param DiceBag $diceBag
*/
public function setDiceBag(DiceBag $diceBag): void
{
$this->diceBag = $diceBag;
}
/**
* Returns the logger instance to write logs.
* @return Logger
+156
View File
@@ -0,0 +1,156 @@
<?php
declare(strict_types=1);
namespace LotGD\Core;
use Doctrine\ORM\EntityManagerInterface;
use Monolog\Logger;
use LotGD\Core\Exceptions\BuilderException;
/**
* The GameBuilder class is used to build a Game object with all dependencies that are needed.
*
* You must provide $cwd, $configuration, $entityManager and a logger instance using the with* methods.
* You can provide additional class *names* for additional dependency injections using the use* methods.
* @package LotGD\Core
*/
class GameBuilder
{
private $cwd;
private $configuration;
private $entityManager;
private $logger;
private $moduleManagerClass;
private $composerManagerClass;
private $eventManagerClass;
private $diceBagClass;
/**
* Creates the game instance with the prepared parameters.
* @return Game
* @throws BuilderException if at least one of cwd, configuration, entityManager or logger as not been set.
*/
public function create(): Game
{
if (isset($this->cwd, $this->configuration, $this->entityManager, $this->logger) === false) {
throw new BuilderException(
"For creating a game, you must set at least: cwd, configuration, entityManager and logger."
);
}
// construct the game
$game = new Game(
$this->configuration,
$this->logger,
$this->entityManager,
$this->cwd
);
// add additional managers to it
$moduleManager = $this->moduleManagerClass ?? ModuleManager::class;
$game->setModuleManager(new $moduleManager($game));
$composerManager = $this->composerManagerClass ?? ComposerManager::class;
$game->setComposerManager(new $composerManager($this->cwd));
$eventManager = $this->eventManagerClass ?? EventManager::class;
$game->setEventManager(new $eventManager($game));
$diceBag = $this->diceBagClass ?? DiceBag::class;
$game->setDiceBag(new $diceBag());
return $game;
}
/**
* Adds current working directory argument
* @param string $cwd
* @return self
*/
public function withCwd(string $cwd): self
{
$this->cwd = $cwd;
return $this;
}
/**
* Configuration
* @param Configuration $conf
* @return self
*/
public function withConfiguration(Configuration $conf): self
{
$this->configuration = $conf;
return $this;
}
/**
* Sets the logger for the game instance.
* @param EntityManagerInterface $em
* @return self
*/
public function withEntityManager(EntityManagerInterface $em): self
{
$this->entityManager = $em;
return $this;
}
/**
* Sets the logger for the game instance.
* @param Logger $logger
* @return self
*/
public function withLogger(Logger $logger): self
{
$this->logger = $logger;
return $this;
}
/**
* Sets the fqcn for the module manager to be used.
* @param string $moduleManagerFqcn
* @return self
*/
public function useModuleManager(string $moduleManagerFqcn): self
{
$this->moduleManagerClass = $moduleManagerFqcn;
return $this;
}
/**
* Sets the fqcn for the composer manager to be used.
* @param string $composerManagerFqcn
* @return self
*/
public function useComposerManager(string $composerManagerFqcn): self
{
$this->composerManagerClass = $composerManagerFqcn;
return $this;
}
/**
* Sets the fqcn for the event manager to be used.
* @param string $eventManagerFqcn
* @return GameBuilder
*/
public function useEventManager(string $eventManagerFqcn): self
{
$this->eventManagerClass = $eventManagerFqcn;
return $this;
}
/**
* Sets the fqcn for the dice bag to be used.
* @param string $diceBagFqcn
* @return GameBuilder
*/
public function useDiceBag(string $diceBagFqcn): self
{
$this->diceBagClass = $diceBagFqcn;
return $this;
}
}
+7 -2
View File
@@ -9,7 +9,7 @@ use Monolog\Logger;
use Monolog\Handler\NullHandler;
use LotGD\Core\{
Action, ActionGroup, Bootstrap, Configuration, ComposerManager, DiceBag, EventHandler, EventManager, Events\NewViewpointData, Game, TimeKeeper, ModuleManager
Action, ActionGroup, Bootstrap, Configuration, ComposerManager, DiceBag, EventHandler, EventManager, Events\NewViewpointData, Game, GameBuilder, TimeKeeper, ModuleManager
};
use LotGD\Core\Models\{
Character, Viewpoint, Scene
@@ -85,7 +85,12 @@ class GameTest extends CoreModelTestCase
$logger = new Logger('test');
$logger->pushHandler(new NullHandler());
$this->g = new Game(new Configuration(getenv('LOTGD_TESTS_CONFIG_PATH')), $logger, $this->getEntityManager(), implode(DIRECTORY_SEPARATOR, [__DIR__, '..']));
$this->g = (new GameBuilder())
->withConfiguration(new Configuration(getenv('LOTGD_TESTS_CONFIG_PATH')))
->withLogger($logger)
->withEntityManager($this->getEntityManager())
->withCwd(implode(DIRECTORY_SEPARATOR, [__DIR__, '..']))
->create();
}
public function testBasicInjection()