You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This Symfony bundle augments [geekcell/php-ddd](https://github.com/geekcell/php-ddd) with framework-specific implementations to enable seamless [domain driven design](https://martinfowler.com/tags/domain%20driven%20design.html) in a familiar environment.
@@ -10,18 +21,62 @@ To use this bundle, require it in Composer
10
21
composer require geekcell/ddd-bundle
11
22
```
12
23
13
-
## Quickstart
24
+
## Generator Commands
25
+
26
+
This bundle adds several [MakerBundle](https://symfony.com/bundles/SymfonyMakerBundle/current/index.html) commands to generate commonly used components.
27
+
28
+
In order to use them in your Symfony project, you need to require it with composer first
29
+
30
+
```bash
31
+
composer require symfony/maker-bundle
32
+
```
33
+
34
+
## Building Blocks
14
35
15
-
-[Aggregate Root](#aggregate-root)
16
-
-[Repositories](#repositories)
17
-
-[Command & Query Bus](#command--query-bus)
18
-
-[Supporting Tools](#supporting-tools)
36
+
### Model & Repository
19
37
20
-
## Aggregate Root
38
+
The **domain model** is a representation of the domain concepts and business logic within your project. The **repository** on the other hand is an abstraction layer that provides a way to access and manipulate domain objects without exposing the details of the underlying data persistence mechanism (such as a database or file system).
21
39
22
-
Extend from `AggregateRoot` to record and commit domain events. Domain events must implement the (marker) interface `DomainEvent`. Events will be dispatched via the currently configured Symfony event dispatcher.
40
+
Since Doctrine is the de-facto persistence layer for Symfony, this bundle also provides an (opinionated) implementation for a Doctrine-based repository.
23
41
24
-
### Example Usage
42
+
#### Generator Command(s)
43
+
44
+
This command can be used to generate:
45
+
46
+
- The domain model class.
47
+
- A repository class for the model.
48
+
- The model's identity class as value object (optional).
49
+
- A Doctrine database entity configuration, either as annotation or separate config file (optional).
50
+
- A custom Doctrine type for the model's identity class (optional).
51
+
52
+
```bash
53
+
Description:
54
+
Creates a new domain model class
55
+
56
+
Usage:
57
+
make:ddd:model [options] [--] [<name>]
58
+
59
+
Arguments:
60
+
name The name of the model class (e.g. Customer)
61
+
62
+
Options:
63
+
--aggregate-root Marks the model as aggregate root
64
+
--entity=ENTITY Use this model as Doctrine entity
65
+
--with-identity=WITH-IDENTITY Whether an identity value object should be created
66
+
--with-suffix Adds the suffix "Model" to the model class name
67
+
```
68
+
69
+
### AggregateRoot & Domain Events
70
+
71
+
Optionally, by inheriting from `AggregateRoot`, you can make a model class an **aggregate root**, which is used to encapsulate a group of related objects, along with the behavior and rules that apply to them. The aggregate root is usually responsible for managing the lifecycle of the objects within the aggregate, and for coordinating any interactions between them.
72
+
73
+
The `AggregateRoot` base class comes with some useful functionality to record and dispatch **domain events**, which represent significant occurrences or state changes within the domain of a software system.
74
+
75
+
#### Generator Command(s)
76
+
77
+
N/A
78
+
79
+
#### Example Usage
25
80
26
81
```php
27
82
use GeekCell\Ddd\Contracts\Domain\Event as DomainEvent;
@@ -56,33 +111,51 @@ _Hint: If you want to dispatch an event directly, use `AggregateRoot::dispatch()
56
111
57
112
If you cannot (or don't want to) extend from `AggregateRoot`, you can alternative use `DispatchableTrait` to add dispatching capabilities to any class. The former is however the recommended way.
58
113
59
-
## Repositories
114
+
### Command & Query
115
+
116
+
You can use `CommandBus` and `QueryBus` as services to implement [CQRS](https://martinfowler.com/bliki/CQRS.html). Internally, both buses will use the [Symfony messenger](https://symfony.com/doc/current/messenger.html) to dispatch commands and queries.
117
+
118
+
#### Generator Command(s)
119
+
120
+
These commands can be used to generate:
121
+
122
+
- A command and command handler class.
123
+
- A query and query handler class.
124
+
125
+
The query / command generated is just an empty class. The handler class is registered as a message handler for the configured [Symfony Messenger](https://symfony.com/doc/current/messenger.html).
60
126
61
-
_coming soon..._
127
+
```bash
128
+
Description:
129
+
Creates a new query|command class and handler
62
130
63
-
## Command & Query Bus
131
+
Usage:
132
+
make:ddd:query|command [<name>]
64
133
65
-
You can use `CommandBus` and `QueryBus` as services to implement [CQRS](https://martinfowler.com/bliki/CQRS.html). Internally, both buses will use the [Symfony messenger](https://symfony.com/doc/current/messenger.html) as "backend".
134
+
Arguments:
135
+
name The name of the query|command class (e.g. Customer)
136
+
```
66
137
67
-
## Example Usage
138
+
####Example Usage
68
139
69
140
```php
70
141
// src/Application/Query/TopRatedBookQuery.php
142
+
71
143
use GeekCell\Ddd\Contracts\Application\Query;
72
144
73
-
class TopRatedBooksQuery implements Query
145
+
readonly class TopRatedBooksQuery implements Query
@@ -124,97 +198,14 @@ class BookController extends AbstractController
124
198
}
125
199
```
126
200
127
-
## Supporting Tools
128
-
129
-
### Facades
130
-
131
-
Facades are heavily inspired by [Laravel's Facades](https://laravel.com/docs/facades) and are more or less singletons on steroids. They are basically a shortcut to services inside the DIC.
132
-
133
-
```php
134
-
use GeekCell\DddBundle\Support\Facades\EventDispatcher;
135
-
136
-
EventDispatcher::dispatch($someEvent);
137
-
138
-
// same as: $container->get('event_dispatcher')->dispatch($someEvent);
139
-
```
140
-
141
-
You can create your own facades by extending from `Facade` and implementing the `Facade::getFacadeAccessor()` method to return the DIC service alias.
142
-
143
-
```php
144
-
use GeekCell\DddBundle\Support\Facades\Facade;
145
-
146
-
class Logger extends Facade
147
-
{
148
-
protected static function getFacadeAccessor(): string
149
-
{
150
-
return 'logger';
151
-
}
152
-
}
153
-
```
154
-
155
-
Although facades are better testable than regular singletons, it is highly recommended to only use them sparringly and always prefer normal dependency injection when possible.
156
-
157
-
## Generator Commands
158
-
159
-
This bundle adds several [maker bundle](https://symfony.com/bundles/SymfonyMakerBundle/current/index.html) commands to generate commonly used components.
160
-
161
-
### Model / Repository
162
-
163
-
This command can be used to generate:
164
-
165
-
- The domain model class.
166
-
- A repository class for the model.
167
-
- The model's identity class as value object (optional).
168
-
- A Doctrine database entity configuration, either as annotation or separate config file (optional).
169
-
- A custom Doctrine type for the model's identity class (optional).
170
-
171
-
#### Command Output
172
-
173
-
```bash
174
-
Description:
175
-
Creates a new domain model class
176
-
177
-
Usage:
178
-
make:ddd:model [options] [--] [<name>]
179
-
180
-
Arguments:
181
-
name The name of the model class (e.g. Customer)
182
-
183
-
Options:
184
-
--aggregate-root Marks the model as aggregate root
185
-
--entity=ENTITY Use this model as Doctrine entity
186
-
--with-identity=WITH-IDENTITY Whether an identity value object should be created
187
-
--with-suffix Adds the suffix "Model" to the model class name
188
-
```
189
-
190
-
### Query / Command
191
-
192
-
These commands can be used to generate:
193
-
194
-
- A query and query handler class.
195
-
- A command and command handler class.
196
-
197
-
The query / command generated is just an empty class. The handler class is registered as a message handler for the configured [Symfony Messenger](https://symfony.com/doc/current/messenger.html).
198
-
199
-
#### Command Output
200
-
201
-
```bash
202
-
Description:
203
-
Creates a new query|command class and handler
204
-
205
-
Usage:
206
-
make:ddd:query|command [<name>]
201
+
### Controller
207
202
208
-
Arguments:
209
-
name The name of the query|command class (e.g. Customer)
210
-
```
203
+
A standard Symfony controller, but augmented with command and query bus(es).
211
204
212
-
###Controller
205
+
#### Generator Command
213
206
214
207
This command can be used to generate a controller with optional `QueryBus` and `CommandBus` dependencies.
215
208
216
-
#### Command Output
217
-
218
209
```bash
219
210
Description:
220
211
Creates a new controller class
@@ -232,9 +223,11 @@ Options:
232
223
233
224
### Resource
234
225
235
-
This command can be used to generate an [Api Platform](https://api-platform.com/) resource. Minimum required version is [2.7](https://api-platform.com/docs/core/upgrade-guide/#api-platform-2730) for the PHP attributes support.
226
+
An [API Platform](https://api-platform.com/) resource, but instead of using the standard approach of using a combined entity/resource approach, it is preferred to separate model (domain layer) and API Platform specific resource (infrastructure layer)
227
+
228
+
#### Generator Command
236
229
237
-
#### Command Output
230
+
Minimum required API Platform version is [2.7](https://api-platform.com/docs/core/upgrade-guide/#api-platform-2730) for the [new metadata system](https://api-platform.com/docs/core/upgrade-guide/#apiresource-metadata).
0 commit comments