<?php
namespace Codeages\Biz\Framework\Context;
use Codeages\Biz\Framework\Cache\CacheManager;
use Codeages\Biz\Framework\Dao\Annotation\MetadataReader;
use Codeages\Biz\Framework\Dao\ArrayStorage;
use Codeages\Biz\Framework\Dao\CacheStrategy;
use Codeages\Biz\Framework\Dao\DaoProxy;
use Codeages\Biz\Framework\Dao\FieldSerializer;
use Codeages\Biz\Framework\Dao\RedisCache;
use Codeages\Biz\Framework\Service\ServiceProxy;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class Biz extends Container
{
protected $providers = [];
protected $booted = false;
public function __construct(array $values = [])
{
parent::__construct();
$biz = $this;
$biz['debug'] = false;
$biz['logger'] = null;
$biz['interceptors'] = new \ArrayObject();
$biz['migration.directories'] = new \ArrayObject();
$biz['console.commands'] = new \ArrayObject();
$biz['console.commands'][] = function () {
return new \Codeages\Biz\Framework\Command\EnvWriteCommand();
};
$biz['autoload.aliases'] = new \ArrayObject(['' => 'Biz']);
$biz['dispatcher'] = function () {
return new EventDispatcher();
};
$biz['callback_resolver'] = function ($biz) {
return new CallbackResolver($biz);
};
$biz['autoloader'] = function ($biz) {
return new ContainerAutoloader(
$biz,
$biz['autoload.aliases'],
[
'service' => $biz['autoload.object_maker.service'],
'dao' => $biz['autoload.object_maker.dao'],
]
);
};
$biz['autoload.object_maker.service'] = function ($biz) {
return function ($namespace, $name) use ($biz) {
$className = "{$namespace}\\Service\\Impl\\{$name}Impl";
if (!empty($biz['service_proxy_enabled'])) {
return new ServiceProxy($biz, $className);
}
return new $className($biz);
};
};
$biz['autoload.object_maker.dao'] = function ($biz) {
return function ($namespace, $name) use ($biz) {
$class = "{$namespace}\\Dao\\Impl\\{$name}Impl";
return new DaoProxy($biz, new $class($biz), $biz['dao.metadata_reader'], $biz['dao.serializer'], $biz['dao.cache.array_storage']);
};
};
$biz['array_storage'] = function () {
return new ArrayStorage();
};
$biz['dao.metadata_reader'] = function ($biz) {
if ($biz['debug']) {
$cacheDirectory = null;
} else {
$cacheDirectory = $biz['cache_directory'].DIRECTORY_SEPARATOR.'dao_metadata';
}
return new MetadataReader($cacheDirectory);
};
$biz['dao.serializer'] = function () {
return new FieldSerializer();
};
$biz['dao.cache.redis_wrapper'] = function ($biz) {
return new RedisCache($biz['redis'], $biz['dispatcher']);
};
$biz['dao.cache.array_storage'] = null;
$biz['dao.cache.enabled'] = false;
$biz['dao.cache.strategy.default'] = function ($biz) {
return $biz['dao.cache.strategy.table'];
};
$biz['dao.cache.strategy.table'] = function ($biz) {
return new CacheStrategy\TableStrategy($biz['dao.cache.redis_wrapper'], $biz['dao.cache.array_storage']);
};
$biz['dao.cache.strategy.row'] = function ($biz) {
return new CacheStrategy\RowStrategy($biz['dao.cache.redis_wrapper'], $biz['dao.metadata_reader']);
};
$biz['lock.flock.directory'] = function ($biz) {
return $biz['run_dir'];
};
$biz['lock.store'] = function ($biz) {
return new \Symfony\Component\Lock\Store\FlockStore($biz['lock.flock.directory']);
};
$biz['lock.factory'] = function ($biz) {
return new \Symfony\Component\Lock\LockFactory($biz['lock.store']);
};
$biz['cache.enabled'] = true;
$biz['cache.default_ttl'] = 3600 * 2; // 2 小时
$biz['cache'] = function ($biz) {
if (isset($biz['redis'])) {
return new CacheManager($biz['redis'], [
'enabled' => $biz['cache.enabled'],
'ttl' => $biz['cache.default_ttl'],
]);
} else {
return new CacheManager(null, ['enabled' => false]);
}
};
foreach ($values as $key => $value) {
$this->offsetSet($key, $value);
}
}
public function register(ServiceProviderInterface $provider, array $values = [])
{
$this->providers[] = $provider;
parent::register($provider, $values);
return $this;
}
public function boot()
{
if (true === $this->booted) {
return;
}
foreach ($this->providers as $provider) {
if ($provider instanceof EventListenerProviderInterface) {
$provider->subscribe($this, $this['dispatcher']);
}
if ($provider instanceof BootableProviderInterface) {
$provider->boot($this);
}
}
$this->booted = true;
}
public function on($eventName, $callback, $priority = 0)
{
if ($this->booted) {
$this['dispatcher']->addListener($eventName, $this['callback_resolver']->resolveCallback($callback), $priority);
return;
}
$this->extend('dispatcher', function (EventDispatcherInterface $dispatcher, $app) use ($callback, $priority, $eventName) {
$dispatcher->addListener($eventName, $app['callback_resolver']->resolveCallback($callback), $priority);
return $dispatcher;
});
}
public function service($alias)
{
return $this['autoloader']->autoload('service', $alias);
}
public function dao($alias)
{
return $this['autoloader']->autoload('dao', $alias);
}
}