/
model-definition.texy
128 lines (93 loc) · 3.96 KB
/
model-definition.texy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
Model Definition
################
Model is the central manager for ORM repositories, it provides them and manages their loading. Model requires a repository loader. Orm comes with `OrmExtension` that will help you integrate all needed services with "Nette\DI":http://doc.nette.org/en/dependency-injection component.
PhpDoc repository definition
============================
The most common usecase is to define available repositories as PhpDoc annotations of your model class. Orm extension will take care of your repositories and automatically creates their definition for DI container. Also, a lazy loader will be injected into model. The loader will provide repositories directly from your DI container.
To define model repository use PhpDoc `@property-read` annotation:
/--php
namespace MyApp;
/**
* @property-read PostsRepository $posts
* @property-read UsersRepository $users
* @property-read TagsRepository $tags
*/
class Orm extends \Nextras\Orm\Model\Model
{
}
\--
Then configure Orm extension in your application `config.neon`:
/--neon
extensions:
nextras.orm: Nextras\Orm\Bridges\NetteDI\OrmExtension
nextras.orm:
model: MyApp\Orm
services:
nextras.orm.metadataParserFactory: MyApp\MyMetadataParserFactory
nextras.orm.dependencyProvider: MyApp\DependencyProvider
\--
The key `model` accepts class name of your project's model. Optionally, you may redefine other orm's services, such as metadata parser factory or dependency provider.
You can easily inject the model class into your services and use property access to get needed repositories:
/--php
namespace MyApp;
class MyService
{
/** @var Orm */
private $orm;
public function __construct(Orm $orm)
{
$this->orm = $orm;
}
public function doSomething(int $postId)
{
$post = $this->orm->posts->getById($postId);
// ...
}
}
\--
DI Repository Definition
========================
You may want to define all your repositories (dynamically) in your DI config. Orm provides different repository finder for such usecase. Orm will not create any other DIC's repository definitions and will reuse all `IRepository` instances in your DIC config.
/--neon
extensions:
nextras.orm: Nextras\Orm\Bridges\NetteDI\OrmExtension
nextras.orm:
repositoryFinder: Nextras\Orm\Bridges\NetteDI\DIRepositoryFinder
services:
- MyApp\PostsRepository(MyApp\PostsMapper(..., @nextras.orm.cache))
\--
/--php
namespace MyApp;
class MyService
{
/** @var Orm */
private $orm;
public function __construct(Orm $orm)
{
$this->orm = $orm;
}
public function doSomething($postId)
{
$post = $this->orm->getRepository(PostsRepository::class)->getById($postId);
// ...
}
}
\--
Repositories are registed also with their names that are generated from the repository classname. If you want a different behavior, you may override `DIRepositoryFinder::getRepositoryName()` method.
-----
Model with simple loader
========================
If you do not use Nette\DI, you can use predefined SimpleRepositoryLoader. This loader requires already instantiated array of repositories. For creating the stack easily, you can use SimpleLoaderFactory. You have to create instances of repositories and mappers on your own.
/--php
$cache = new Nette\Caching\Cache(...);
$connection = new Nextras\Dbal\Connection(...);
$mapperCoordinator = new Nextras\Orm\Mapper\Dbal\DbalMapperCoordinator($connection);
$metadataParserFactory = new Nextras\Orm\Entity\Reflection\MetadataParserFactory();
$simpleModelFactory = new SimpleModelFactory($cache, [
'posts' => new MyApp\PostsRepository(new MyApp\PostsMapper($connection, $mapperCoordinator, $cache)),
'users' => new MyApp\UsersRepository(new MyApp\UsersMapper($connection, $mapperCoordinator, $cache)),
'tags' => new MyApp\TagsRepository(new MyApp\TagsMapper($connection, $mapperCoordinator, $cache)),
], $metadataParserFactory);
$model = $simpleModelFactory->create();
\--
Of course, you can create your own repository loader by implementing `Nextras\Orm\Model\IRepositoryLoader` interface. Metadata parser factory optional dependency.