Skip to content

Commit

Permalink
readme.md: updated code
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Feb 6, 2024
1 parent 48af411 commit 9a698fe
Showing 1 changed file with 43 additions and 42 deletions.
85 changes: 43 additions & 42 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ We have the object representing email:
```php
class Mail
{
public $subject;
public $message;
public string $subject;
public string $message;
}
```

Expand All @@ -60,7 +60,7 @@ An object which can send emails:
```php
interface Mailer
{
function send(Mail $mail, $to);
function send(Mail $mail, string $to): void;
}
```

Expand All @@ -69,7 +69,7 @@ A support for logging:
```php
interface Logger
{
function log($message);
function log(string $message): void;
}
```

Expand All @@ -78,23 +78,25 @@ And finally, a class that provides sending newsletters:
```php
class NewsletterManager
{
private $mailer;
private $logger;
private Mailer $mailer;
private Logger $logger;

function __construct(Mailer $mailer, Logger $logger)
public function __construct(Mailer $mailer, Logger $logger)
{
$this->mailer = $mailer;
$this->logger = $logger;
}

function distribute(array $recipients)
public function distribute(array $recipients): void
{
$mail = new Mail;
...
$mail->subject = '...';
$mail->message = '...';

foreach ($recipients as $recipient) {
$this->mailer->send($mail, $recipient);
}
$this->logger->log(...);
$this->logger->log('...');
}
}
```
Expand All @@ -106,22 +108,22 @@ Also, we have a ability to implement own `Logger` or `Mailer`, like this:
```php
class SendMailMailer implements Mailer
{
function send(Mail $mail, $to)
public function send(Mail $mail, string $to): void
{
mail($to, $mail->subject, $mail->message);
}
}

class FileLogger implements Logger
{
private $file;
private string $file;

function __construct($file)
public function __construct(string $file)
{
$this->file = $file;
}

function log($message)
public function log(string $message): void
{
file_put_contents($this->file, $message . "\n", FILE_APPEND);
}
Expand All @@ -135,26 +137,26 @@ Container for our application might look like this:
```php
class Container
{
private $logger;
private $mailer;
private ?Logger $logger;
private ?Mailer $mailer;

function getLogger()
public function getLogger(): Logger
{
if (!$this->logger) {
if (!isset($this->logger)) {
$this->logger = new FileLogger('log.txt');
}
return $this->logger;
}

function getMailer()
public function getMailer(): Mailer
{
if (!$this->mailer) {
if (!isset($this->mailer)) {
$this->mailer = new SendMailMailer;
}
return $this->mailer;
}

function createNewsletterManager()
public function createNewsletterManager(): NewsletterManager
{
return new NewsletterManager($this->getMailer(), $this->getLogger());
}
Expand Down Expand Up @@ -213,7 +215,7 @@ The container will be generated only once and the code is stored in cache (in di
During development it is useful to activate auto-refresh mode which automatically regenerate the container when any class or configuration file is changed. Just in the constructor `ContainerLoader` append `true` as the second argument:

```php
$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp', true);
$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp', autoRebuild: true);
```


Expand Down Expand Up @@ -244,17 +246,17 @@ Class of the service:
```php
class NewsletterManager
{
private $anotherService;
private AnotherService $anotherService;

public function setAnotherService(AnotherService $service)
public function setAnotherService(AnotherService $service): void
{
$this->anotherService = $service;
}

...
```

We can also add the `inject: yes` directive. This directive will enable automatic call of `inject*` methods and passing dependencies to public variables with `@inject` annotations:
We can also add the `inject: yes` directive. This directive will enable automatic call of `inject*` methods and passing dependencies to public variables with #[Inject] attribute:

```neon
services:
Expand All @@ -266,21 +268,23 @@ services:
Dependency `Service1` will be passed by calling the `inject*` method, dependency `Service2` will be assigned to the `$service2` variable:

```php
use Nette\DI\Attributes\Inject;

class FooClass
{
private $service1;
private Service1 $service1;

// 1) inject* method:

public function injectService1(Service1 $service)
public function injectService1(Service1 $service): void
{
$this->service1 = $service1;
}

// 2) Assign to the variable with the @inject annotation:
// 2) Assign to the variable with the #[Inject] attribute:

/** @inject @var Service2 */
public $service2;
#[Inject]
public Service2 $service2;
}
```

Expand All @@ -291,17 +295,14 @@ However, this method is not ideal, because the variable must be declared as publ
Factories
---------

We can use factories generated from an interface. The interface must declare the returning type in the `@return` annotation of the method. Nette will generate a proper implementation of the interface.
We can use factories generated from an interface. The interface must declare the returning type of the method. Nette will generate a proper implementation of the interface.

The interface must have exactly one method named `create`. Our factory interface could be declared in the following way:

```php
interface IBarFactory
interface BarFactory
{
/**
* @return Bar
*/
public function create();
function create(): Bar;
}
```

Expand All @@ -310,7 +311,7 @@ The `create` method will instantiate an `Bar` with the following definition:
```php
class Bar
{
private $logger;
private Logger $logger;

public function __construct(Logger $logger)
{
Expand All @@ -323,15 +324,15 @@ The factory will be registered in the `config.neon` file:

```neon
services:
- IBarFactory
- BarFactory
```

Nette will check if the declared service is an interface. If yes, it will also generate the corresponding implementation of the factory. The definition can be also written in a more verbose form:

```neon
services:
barFactory:
implement: IBarFactory
implement: BarFactory
```

This full definition allows us to declare additional configuration of the object using the `arguments` and `setup` sections, similarly as for all other services.
Expand All @@ -341,14 +342,14 @@ In our code, we only have to obtain the factory instance and call the `create` m
```php
class Foo
{
private $barFactory;
private BarFactory $barFactory;

function __construct(IBarFactory $barFactory)
function __construct(BarFactory $barFactory)
{
$this->barFactory = $barFactory;
}

function bar()
function bar(): void
{
$bar = $this->barFactory->create();
}
Expand Down

0 comments on commit 9a698fe

Please sign in to comment.