Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitec1e7ca

Browse files
committed
[DependencyInjection] added a way to automatically update scoped services
A service can now be marked as synchronized; when set, all method callsinvolving this service will be called each time this service is set.When in a scope, methods are also called to restore the previous version of theservice.
1 parent469330d commitec1e7ca

22 files changed

+366
-24
lines changed

‎src/Symfony/Component/DependencyInjection/Container.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,10 @@ public function set($id, $service, $scope = self::SCOPE_CONTAINER)
206206
}
207207

208208
$this->services[$id] =$service;
209+
210+
if (method_exists($this,$method ='synchronize'.strtr($id,array('_' =>'','.' =>'_')).'Service')) {
211+
$this->$method();
212+
}
209213
}
210214

211215
/**
@@ -221,7 +225,7 @@ public function has($id)
221225
{
222226
$id =strtolower($id);
223227

224-
returnisset($this->services[$id]) ||method_exists($this,'get'.strtr($id,array('_' =>'','.' =>'_')).'Service');
228+
returnarray_key_exists($id,$this->services) ||method_exists($this,'get'.strtr($id,array('_' =>'','.' =>'_')).'Service');
225229
}
226230

227231
/**
@@ -247,7 +251,7 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE
247251
{
248252
$id =strtolower($id);
249253

250-
if (isset($this->services[$id])) {
254+
if (array_key_exists($id,$this->services)) {
251255
return$this->services[$id];
252256
}
253257

@@ -263,7 +267,7 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE
263267
}catch (\Exception$e) {
264268
unset($this->loading[$id]);
265269

266-
if (isset($this->services[$id])) {
270+
if (array_key_exists($id,$this->services)) {
267271
unset($this->services[$id]);
268272
}
269273

@@ -289,7 +293,7 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE
289293
*/
290294
publicfunctioninitialized($id)
291295
{
292-
returnisset($this->services[strtolower($id)]);
296+
returnarray_key_exists(strtolower($id),$this->services);
293297
}
294298

295299
/**
@@ -393,8 +397,11 @@ public function leaveScope($name)
393397
$services =$this->scopeStacks[$name]->pop();
394398
$this->scopedServices +=$services;
395399

396-
array_unshift($services,$this->services);
397-
$this->services =call_user_func_array('array_merge',$services);
400+
foreach ($servicesas$array) {
401+
foreach ($arrayas$id =>$service) {
402+
$this->set($id,$service,$name);
403+
}
404+
}
398405
}
399406
}
400407

‎src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
4646
*/
4747
private$definitions =array();
4848

49+
/**
50+
* @var Definition[]
51+
*/
52+
private$obsoleteDefinitions =array();
53+
4954
/**
5055
* @var Alias[]
5156
*/
@@ -351,14 +356,28 @@ public function set($id, $service, $scope = self::SCOPE_CONTAINER)
351356

352357
if ($this->isFrozen()) {
353358
// setting a synthetic service on a frozen container is alright
354-
if (!isset($this->definitions[$id]) || !$this->definitions[$id]->isSynthetic()) {
359+
if (
360+
(!isset($this->definitions[$id]) && !isset($this->obsoleteDefinitions[$id]))
361+
||
362+
(isset($this->definitions[$id]) && !$this->definitions[$id]->isSynthetic())
363+
||
364+
(isset($this->obsoleteDefinitions[$id]) && !$this->obsoleteDefinitions[$id]->isSynthetic())
365+
) {
355366
thrownewBadMethodCallException(sprintf('Setting service "%s" on a frozen container is not allowed.',$id));
356367
}
357368
}
358369

370+
if (isset($this->definitions[$id])) {
371+
$this->obsoleteDefinitions[$id] =$this->definitions[$id];
372+
}
373+
359374
unset($this->definitions[$id],$this->aliases[$id]);
360375

361376
parent::set($id,$service,$scope);
377+
378+
if (isset($this->obsoleteDefinitions[$id]) &&$this->obsoleteDefinitions[$id]->isSynchronized()) {
379+
$this->synchronize($id);
380+
}
362381
}
363382

364383
/**
@@ -885,19 +904,7 @@ private function createService(Definition $definition, $id)
885904
}
886905

887906
foreach ($definition->getMethodCalls()as$call) {
888-
$services =self::getServiceConditionals($call[1]);
889-
890-
$ok =true;
891-
foreach ($servicesas$s) {
892-
if (!$this->has($s)) {
893-
$ok =false;
894-
break;
895-
}
896-
}
897-
898-
if ($ok) {
899-
call_user_func_array(array($service,$call[0]),$this->resolveServices($parameterBag->resolveValue($call[1])));
900-
}
907+
$this->callMethod($service,$call);
901908
}
902909

903910
$properties =$this->resolveServices($parameterBag->resolveValue($definition->getProperties()));
@@ -999,4 +1006,43 @@ public static function getServiceConditionals($value)
9991006

10001007
return$services;
10011008
}
1009+
1010+
/**
1011+
* Synchronizes a service change.
1012+
*
1013+
* This method updates all services that depend on the given
1014+
* service by calling all methods referencing it.
1015+
*
1016+
* @param string $id A service id
1017+
*/
1018+
privatefunctionsynchronize($id)
1019+
{
1020+
foreach ($this->definitionsas$definitionId =>$definition) {
1021+
// only check initialized services
1022+
if (!$this->initialized($definitionId)) {
1023+
continue;
1024+
}
1025+
1026+
foreach ($definition->getMethodCalls()as$call) {
1027+
foreach ($call[1]as$argument) {
1028+
if ($argumentinstanceof Reference &&$id == (string)$argument) {
1029+
$this->callMethod($this->get($definitionId),$call);
1030+
}
1031+
}
1032+
}
1033+
}
1034+
}
1035+
1036+
privatefunctioncallMethod($service,$call)
1037+
{
1038+
$services =self::getServiceConditionals($call[1]);
1039+
1040+
foreach ($servicesas$s) {
1041+
if (!$this->has($s)) {
1042+
return;
1043+
}
1044+
}
1045+
1046+
call_user_func_array(array($service,$call[0]),$this->resolveServices($this->getParameterBag()->resolveValue($call[1])));
1047+
}
10021048
}

‎src/Symfony/Component/DependencyInjection/Definition.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class Definition
3636
private$public;
3737
private$synthetic;
3838
private$abstract;
39+
private$synchronized;
3940

4041
protected$arguments;
4142

@@ -56,6 +57,7 @@ public function __construct($class = null, array $arguments = array())
5657
$this->tags =array();
5758
$this->public =true;
5859
$this->synthetic =false;
60+
$this->synchronized =false;
5961
$this->abstract =false;
6062
$this->properties =array();
6163
}
@@ -569,6 +571,34 @@ public function isPublic()
569571
return$this->public;
570572
}
571573

574+
/**
575+
* Sets the synchronized flag of this service.
576+
*
577+
* @param Boolean $boolean
578+
*
579+
* @return Definition The current instance
580+
*
581+
* @api
582+
*/
583+
publicfunctionsetSynchronized($boolean)
584+
{
585+
$this->synchronized = (Boolean)$boolean;
586+
587+
return$this;
588+
}
589+
590+
/**
591+
* Whether this service is synchronized.
592+
*
593+
* @return Boolean
594+
*
595+
* @api
596+
*/
597+
publicfunctionisSynchronized()
598+
{
599+
return$this->synchronized;
600+
}
601+
572602
/**
573603
* Sets whether this definition is synthetic, that is not constructed by the
574604
* container, but dynamically injected.

‎src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ protected function get{$name}Service()
567567
*/
568568
privatefunctionaddServices()
569569
{
570-
$publicServices =$privateServices =$aliasServices ='';
570+
$publicServices =$privateServices =$aliasServices =$synchronizers ='';
571571
$definitions =$this->container->getDefinitions();
572572
ksort($definitions);
573573
foreach ($definitionsas$id =>$definition) {
@@ -576,6 +576,8 @@ private function addServices()
576576
}else {
577577
$privateServices .=$this->addService($id,$definition);
578578
}
579+
580+
$synchronizers .=$this->addServiceSynchronizer($id,$definition);
579581
}
580582

581583
$aliases =$this->container->getAliases();
@@ -584,7 +586,60 @@ private function addServices()
584586
$aliasServices .=$this->addServiceAlias($alias,$id);
585587
}
586588

587-
return$publicServices.$aliasServices.$privateServices;
589+
return$publicServices.$aliasServices.$synchronizers.$privateServices;
590+
}
591+
592+
/**
593+
* Adds synchronizer methods.
594+
*
595+
* @param string $id A service identifier
596+
* @param Definition $definition A Definition instance
597+
*/
598+
privatefunctionaddServiceSynchronizer($id,Definition$definition)
599+
{
600+
if (!$definition->isSynchronized()) {
601+
return;
602+
}
603+
604+
$code ='';
605+
foreach ($this->container->getDefinitions()as$definitionId =>$definition) {
606+
foreach ($definition->getMethodCalls()as$call) {
607+
foreach ($call[1]as$argument) {
608+
if ($argumentinstanceof Reference &&$id == (string)$argument) {
609+
$arguments =array();
610+
foreach ($call[1]as$value) {
611+
$arguments[] =$this->dumpValue($value);
612+
}
613+
614+
$call =$this->wrapServiceConditionals($call[1],sprintf("\$this->get('%s')->%s(%s);",$definitionId,$call[0],implode(',',$arguments)));
615+
616+
$code .=<<<EOF
617+
if (\$this->initialized('$definitionId')) {
618+
$call
619+
}
620+
621+
EOF;
622+
}
623+
}
624+
}
625+
}
626+
627+
if (!$code) {
628+
return;
629+
}
630+
631+
$name = Container::camelize($id);
632+
633+
return<<<EOF
634+
635+
/**
636+
* Updates the '$id' service.
637+
*/
638+
protected function synchronize{$name}Service()
639+
{
640+
$code }
641+
642+
EOF;
588643
}
589644

590645
privatefunctionaddNewInstance($id,Definition$definition,$return,$instantiation)

‎src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,12 @@ private function addService($definition, $id, \DOMElement $parent)
127127
if (!$definition->isPublic()) {
128128
$service->setAttribute('public','false');
129129
}
130+
if ($definition->isSynthetic()) {
131+
$service->setAttribute('synthetic','true');
132+
}
133+
if ($definition->isSynchronized()) {
134+
$service->setAttribute('synchronized','true');
135+
}
130136

131137
foreach ($definition->getTags()as$name =>$tags) {
132138
foreach ($tagsas$attributes) {
@@ -239,6 +245,9 @@ private function convertParameters($parameters, $type, \DOMElement $parent, $key
239245
}elseif ($behaviour == ContainerInterface::IGNORE_ON_INVALID_REFERENCE) {
240246
$element->setAttribute('on-invalid','ignore');
241247
}
248+
if (!$value->isStrict()) {
249+
$element->setAttribute('strict','false');
250+
}
242251
}elseif ($valueinstanceof Definition) {
243252
$element->setAttribute('type','service');
244253
$this->addService($value,null,$element);

‎src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ private function addService($id, $definition)
9494
$code .=sprintf(" file: %s\n",$definition->getFile());
9595
}
9696

97+
if ($definition->isSynthetic()) {
98+
$code .=sprintf(" synthetic: true\n");
99+
}
100+
101+
if ($definition->isSynchronized()) {
102+
$code .=sprintf(" synchronized: true\n");
103+
}
104+
97105
if ($definition->getFactoryMethod()) {
98106
$code .=sprintf(" factory_method: %s\n",$definition->getFactoryMethod());
99107
}

‎src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ private function parseDefinition($id, $service, $file)
148148
$definition =newDefinition();
149149
}
150150

151-
foreach (array('class','scope','public','factory-class','factory-method','factory-service','synthetic','abstract')as$key) {
151+
foreach (array('class','scope','public','factory-class','factory-method','factory-service','synthetic','synchronized','abstract')as$key) {
152152
if (isset($service[$key])) {
153153
$method ='set'.str_replace('-','',$key);
154154
$definition->$method((string)$service->getAttributeAsPhp($key));

‎src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ private function parseDefinition($id, $service, $file)
153153
$definition->setSynthetic($service['synthetic']);
154154
}
155155

156+
if (isset($service['synchronized'])) {
157+
$definition->setSynchronized($service['synchronized']);
158+
}
159+
156160
if (isset($service['public'])) {
157161
$definition->setPublic($service['public']);
158162
}

‎src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
<xsd:attributename="scope"type="xsd:string" />
8787
<xsd:attributename="public"type="boolean" />
8888
<xsd:attributename="synthetic"type="boolean" />
89+
<xsd:attributename="synchronized"type="boolean" />
8990
<xsd:attributename="abstract"type="boolean" />
9091
<xsd:attributename="factory-class"type="xsd:string" />
9192
<xsd:attributename="factory-method"type="xsd:string" />

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp