Skip to content
This repository was archived by the owner on Jan 29, 2020. It is now read-only.

Commit 6a7663b

Browse files
committed
Remove (at|de)tachAggregate() methods from EventManagerInterface
This patch removes the `attachAggregate()` and `detachAggregate()` methods from the `EventManagerInterface`. Since they simply proxied to the `attach()` and `detach()` methods of the provided `ListenerAggregateInterface` implementation, it was simply a redundant way to attach aggregate listeners that resulted in performance overhead. Migration documentation has been updated, as have all examples using aggregates.
1 parent 46b5607 commit 6a7663b

File tree

10 files changed

+86
-157
lines changed

10 files changed

+86
-157
lines changed

doc/book/aggregates.md

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,9 @@ attach(EventManagerInterface $events, $priority = 1);
1313
detach(EventManagerInterface $events);
1414
```
1515

16-
You can attach them to the event manager in one of two ways:
17-
18-
- By passing an instance of `Zend\EventManager\EventManager` to your listener's
19-
`attach()` method.
20-
- By passing the aggregate to `Zend\EventManager\EventManager::attachAggregate()`
21-
22-
The latter essentially passes the event manager instance to the aggregate's
23-
`attach()` method.
16+
To attach an aggregate to an event manager, you pass the event manager to the
17+
aggregate's `attach()` method; in that method, you will then attach listeners to
18+
the events you are interested in.
2419

2520
## Implementation
2621

@@ -82,23 +77,15 @@ we provide two facilities for implementing this:
8277
## Usage
8378

8479
To use an aggregate listener, you need to attach it to the event manager. As
85-
noted in the intro to this section, you can either pass it to the event
86-
manager's `attachAggregate()` method, or pass the event manager to the
87-
aggregate's `attach()` method.
80+
noted in the intro to this section, you do so by passing the event
81+
manager to the aggregate's `attach()` method:
8882

8983
```php
9084
// Assume $events is an EventManager instance, and $aggregate is an instance of
9185
// the Aggregate class defined earlier.
92-
93-
// Passing the aggregate to the EventManager:
94-
$events->attachAggregate($aggregate);
95-
96-
// Passing the EventManager to the aggregate:
9786
$aggregate->attach($events);
9887
```
9988

100-
Both approaches accomplish the same thing.
101-
10289
## Recommendations
10390

10491
- We recommend using listener aggregates when you have several listeners that are

doc/book/api.md

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -169,26 +169,6 @@ method will detach the listener from that event only (or, if the event does not
169169
exist in the event manager, nothing will occur). If no event is provided, or the
170170
wildcard event is provided, the listener will be detached from all events.
171171

172-
### attachAggregate()
173-
174-
```php
175-
attachAggregate(ListenerAggregateInterface $aggregate, $priority = 1) : void
176-
```
177-
178-
Provided an aggregate, this method will then call the aggregate's `attach()`
179-
method, passing the event manager instance and the provided priority (if any).
180-
See the [section on aggregates](aggregates.md) for more information.
181-
182-
### detachAggregate()
183-
184-
```php
185-
detachAggregate(ListenerAggregateInterface $aggregate) : void
186-
```
187-
188-
Provided an aggregate, this method will then call the aggregate's `detach()`
189-
method, passing the event manager instance. See the
190-
[section on aggregates](aggregates.md) for more information.
191-
192172
### clearListeners()
193173

194174
```php

doc/book/examples.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,12 +204,12 @@ class CacheListener implements ListenerAggregateInterface
204204
}
205205
```
206206

207-
We can then attach the aggregate to an instance.
207+
We can then attach the aggregate to an event manager instance.
208208

209209
```
210210
$value = new SomeValueObject();
211211
$cacheListener = new CacheListener($cache);
212-
$value->getEventManager()->attachAggregate($cacheListener);
212+
$cacheListener->attach($value->getEventManager());
213213
```
214214

215215
Now, as we call `get()`, if we have a cached entry, it will be returned

doc/book/lazy-listeners/lazy-listener-aggregate.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ $aggregate = new LazyListenerAggregate(
4444
$definitions,
4545
$container
4646
);
47-
$events->attachAggregate($aggregate);
47+
$aggregate->attach($events);
4848
```
4949

5050
Internally, the `LazyListenerAggregate` will create `LazyEventListener`
@@ -81,7 +81,7 @@ $aggregate = new LazyListenerAggregate(
8181
$definitions,
8282
$container
8383
);
84-
$events->attachAggregate($aggregate);
84+
$aggregate->attach($events);
8585
```
8686

8787
## Recommendations

doc/book/migration/changed.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,11 @@ In order to migrate to version 3, you will need to make a few changes to your
173173
application.
174174

175175
First, if you are attaching or detaching aggregate listeners using `attach()`
176-
and `detach()`, you should change them to use `attachAggregate()` and
177-
`detachAggregate()` instead. These methods already exist in version 2, giving
178-
clear forwards compatibility.
176+
and `detach()`, you should change such calls to instead pass the event manager
177+
to the relevant `ListenerAggregateInterface` method, as detailed in the
178+
[removed functionality](removed.md#eventmanagerinterfaceattachaggregate-and-detachaggregate)
179+
documentation. These methods have existed in all released versions, giving
180+
perfect forwards compatibility.
179181

180182
Second, if you are manually creating `CallbackHandler` instances to attach to an
181183
event manager, stop doing so, and attach the callable listener itself instead.

doc/book/migration/removed.md

Lines changed: 69 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,75 @@ option from the framework entirely.
1515
The trait `Zend\EventManager\ProvidesEvents` has been deprecated for most of
1616
the 2.0 series; use `Zend\EventManager\EventManagerAwareTrait` instead.
1717

18+
## EventManagerInterface::setSharedManager()
19+
20+
We have removed `EventManagerInterface::setSharedManager()`, and also removed it
21+
from the `EventManager` implementation. The `SharedEventManager` should be
22+
injected during instantiation now.
23+
24+
## EventManagerInterface::getEvents() and getListeners()
25+
26+
We have removed both `EventManagerInterface::getEvents()` and `getListeners()`,
27+
as we did not have a stated use case for the methods. The event manager should
28+
be something that aggregates listeners and triggers events; the details of what
29+
listeners or events are attached is largely irrelevant.
30+
31+
The primary use case for `getListeners()` is often to determine if a listener is
32+
attached before detaching it. Since `detach()` acts as a no-op if the provided
33+
listener is not present, checking for presence first is not necessary.
34+
35+
## EventManagerInterface::setEventClass()
36+
37+
The method `EventManagerInterface::setEventClass()` was removed and replaced
38+
with `EventManagerInterface::setEventPrototype()`, which has the following
39+
signature:
40+
41+
```php
42+
setEventPrototype(EventInterface $event);
43+
```
44+
45+
This was done to prevent errors that occurred when invalid event class names
46+
were provided. Additionally, internally, event managers will clone the
47+
instance any time `trigger()` or `triggerUntil()` are called — which is
48+
typically faster and less resource intensive than instantiating a new instance.
49+
50+
## EventManagerInterface::attachAggregate() and detachAggregate()
51+
52+
The methods `attachAggregate()` and `detachAggregate()` were removed from the
53+
`EventManagerInterface` and concrete `EventManager` implementation. Furthermore,
54+
`attach()` and `detach()` no longer handle aggregates.
55+
56+
The reason they were removed is because they simply proxied to the `attach()`
57+
and `detach()` methods of the `ListenerAggregateInterface`. As such, to
58+
forward-proof your applications, you can alter statements that attach aggregates
59+
to an event manager reading as follows:
60+
61+
```php
62+
$events->attach($aggregate); // or
63+
$events->attachAggregate($aggregate);
64+
```
65+
66+
to:
67+
68+
```php
69+
$aggregate->attach($events);
70+
```
71+
72+
Similarly, for detaching an aggregate, migrate from:
73+
74+
```php
75+
$events->detach($aggregate); // or
76+
$events->detachAggregate($aggregate);
77+
```
78+
79+
to:
80+
81+
```php
82+
$aggregate->detach($events);
83+
```
84+
85+
The above works in all released versions of the component.
86+
1887
## SharedEventAggregateAwareInterface, SharedListenerAggregateInterface
1988

2089
The interfaces `Zend\EventManager\SharedEventAggregateAwareInterface` and
@@ -135,38 +204,6 @@ To migrate, you have the following options:
135204
Alternately, if you control instantiation of the instance, consider injection
136205
at instantiation, or within the factory used to create your instance.
137206

138-
## EventManagerInterface::setSharedManager()
139-
140-
We have removed `EventManagerInterface::setSharedManager()`, and also removed it
141-
from the `EventManager` implementation. The `SharedEventManager` should be
142-
injected during instantiation now.
143-
144-
## EventManagerInterface::getEvents() and getListeners()
145-
146-
We have removed both `EventManagerInterface::getEvents()` and `getListeners()`,
147-
as we did not have a stated use case for the methods. The event manager should
148-
be something that aggregates listeners and triggers events; the details of what
149-
listeners or events are attached is largely irrelevant.
150-
151-
The primary use case for `getListeners()` is often to determine if a listener is
152-
attached before detaching it. Since `detach()` acts as a no-op if the provided
153-
listener is not present, checking for presence first is not necessary.
154-
155-
## EventManagerInterface::setEventClass()
156-
157-
The method `EventManagerInterface::setEventClass()` was removed and replaced
158-
with `EventManagerInterface::setEventPrototype()`, which has the following
159-
signature:
160-
161-
```php
162-
setEventPrototype(EventInterface $event);
163-
```
164-
165-
This was done to prevent errors that occurred when invalid event class names
166-
were provided. Additionally, internally, event managers will clone the
167-
instance any time `trigger()` or `triggerUntil()` are called — which is
168-
typically faster and less resource intensive than instantiating a new instance.
169-
170207
## SharedEventManagerInterface::getEvents()
171208

172209
The method `SharedEventManagerInterface::getEvents()` was removed. The method

doc/book/tutorial.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,11 +308,12 @@ class LogEvents implements ListenerAggregateInterface
308308
> implement `ListenerAggregateInterface`; it defines the `$listeners` property,
309309
> and the `detach()` logic as demostrated above.
310310
311-
You can attach this using the event manager's `attachAggregate()` method:
311+
You can attach this by passing the event manager to the aggregate's `attach()`
312+
method:
312313

313314
```php
314315
$logListener = new LogEvents($logger);
315-
$events->attachAggregate($logListener);
316+
$logListener->attach($events);
316317
```
317318

318319
Any events the aggregate attaches to will then be notified when triggered.

src/EventManager.php

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -220,22 +220,6 @@ public function detach(callable $listener, $eventName = null, $force = false)
220220
}
221221
}
222222

223-
/**
224-
* @inheritDoc
225-
*/
226-
public function attachAggregate(ListenerAggregateInterface $aggregate, $priority = 1)
227-
{
228-
$aggregate->attach($this, $priority);
229-
}
230-
231-
/**
232-
* @inheritDoc
233-
*/
234-
public function detachAggregate(ListenerAggregateInterface $aggregate)
235-
{
236-
$aggregate->detach($this);
237-
}
238-
239223
/**
240224
* @inheritDoc
241225
*/

src/EventManagerInterface.php

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -161,22 +161,4 @@ public function setIdentifiers(array $identifiers);
161161
* @return void
162162
*/
163163
public function addIdentifiers(array $identifiers);
164-
165-
/**
166-
* Attach a listener aggregate
167-
*
168-
* @param ListenerAggregateInterface $aggregate
169-
* @param int $priority If provided, a suggested priority for the aggregate to use
170-
* @return mixed return value of {@link ListenerAggregateInterface::attach()}
171-
*/
172-
public function attachAggregate(ListenerAggregateInterface $aggregate, $priority = 1);
173-
174-
/**
175-
* Detach a listener aggregate.
176-
*
177-
* Should delegate to the aggregate's detach() method.
178-
*
179-
* @param ListenerAggregateInterface $aggregate
180-
*/
181-
public function detachAggregate(ListenerAggregateInterface $aggregate);
182164
}

test/EventManagerTest.php

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -224,30 +224,6 @@ public function testResponseCollectionIsNotStoppedWhenNoCallbackMatchedByTrigger
224224
$this->assertEquals('zero', $responses->last());
225225
}
226226

227-
public function testCanAttachListenerAggregate()
228-
{
229-
$aggregate = new TestAsset\MockAggregate();
230-
$this->events->attachAggregate($aggregate);
231-
$events = $this->getEventListFromManager($this->events);
232-
foreach (['foo.bar', 'foo.baz'] as $event) {
233-
$this->assertContains($event, $events);
234-
}
235-
}
236-
237-
public function testAttachAggregateAcceptsOptionalPriorityValue()
238-
{
239-
$aggregate = new TestAsset\MockAggregate();
240-
$this->events->attachAggregate($aggregate, 1);
241-
$this->assertEquals(1, $aggregate->priority);
242-
}
243-
244-
public function testAttachAggregateAcceptsOptionalPriorityValueViaAttachCallbackArgument()
245-
{
246-
$aggregate = new TestAsset\MockAggregate();
247-
$this->events->attachAggregate($aggregate, 1);
248-
$this->assertEquals(1, $aggregate->priority);
249-
}
250-
251227
public function testCallingEventsStopPropagationMethodHaltsEventEmission()
252228
{
253229
// @codingStandardsIgnoreStart
@@ -738,26 +714,6 @@ public function testDetachRemovesAllOccurrencesOfListenerForEvent()
738714
$this->assertNotContains($listener, $listeners);
739715
}
740716

741-
public function testCanDetachAnAggregate()
742-
{
743-
$events = $this->events;
744-
$aggregate = $this->prophesize(ListenerAggregateInterface::class);
745-
$aggregate->attach(Argument::is($events), 1)->shouldBeCalled();
746-
$aggregate->detach(Argument::is($events))->shouldBeCalled();
747-
748-
$events->attachAggregate($aggregate->reveal());
749-
$events->detachAggregate($aggregate->reveal());
750-
}
751-
752-
public function testCanAttachAggregateWithPriority()
753-
{
754-
$events = $this->events;
755-
$aggregate = $this->prophesize(ListenerAggregateInterface::class);
756-
$aggregate->attach(Argument::is($events), 5)->shouldBeCalled();
757-
758-
$events->attachAggregate($aggregate->reveal(), 5);
759-
}
760-
761717
public function eventsMissingNames()
762718
{
763719
$event = $this->prophesize(EventInterface::class);

0 commit comments

Comments
 (0)