Hizmet Tanımları
Yapılandırma, özel hizmetlerin tanımlarını yerleştirdiğimiz yerdir. Bu services
bölümünde
yapılır.
Örneğin, PDO
sınıfının bir örneği olacak olan database
adlı bir hizmeti bu şekilde
oluşturuyoruz:
services:
database: PDO('sqlite::memory:')
Hizmetlerin isimlendirilmesi, onlara referans vermemizi sağlamak için kullanılır. Bir hizmete referans verilmiyorsa, onu adlandırmaya gerek yoktur. Bu yüzden isim yerine sadece bir madde işareti kullanırız:
services:
- PDO('sqlite::memory:') # anonymous service
Tek satırlık bir giriş, kurulum gibi ek anahtarların eklenmesine izin vermek için birden fazla
satıra bölünebilir. create:
tuşu için takma ad factory:
şeklindedir.
services:
database:
create: PDO('sqlite::memory:')
setup: ...
Daha sonra getService()
yöntemini isme göre ya da daha iyisi getByType()
yöntemini türe göre
kullanarak hizmeti DI konteynerinden alırız:
$database = $container->getService('database');
$database = $container->getByType(PDO::class);
Hizmet Oluşturma
Çoğu zaman, sadece bir sınıfın örneğini oluşturarak bir hizmet yaratırız:
services:
database: PDO('mysql:host=127.0.0.1;dbname=test', root, secret)
Bu da DI konteynerinde bir fabrika yöntemi oluşturacaktır:
public function createServiceDatabase(): PDO
{
return new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'secret');
}
Alternatif olarak, argümanları iletmek için bir anahtar arguments
kullanılabilir:
services:
database:
create: PDO
arguments: ['mysql:host=127.0.0.1;dbname=test', root, secret]
Statik bir yöntem de bir hizmet oluşturabilir:
services:
database: My\Database::create(root, secret)
PHP koduna karşılık gelir:
public function createServiceDatabase(): PDO
{
return My\Database::create('root', 'secret');
}
Statik bir yöntemin My\Database::create()
DI konteynerinin bilmesi gereken tanımlı bir dönüş değerine sahip
olduğu varsayılır. Eğer yoksa, türü yapılandırmaya yazarız:
services:
database:
create: My\Database::create(root, secret)
type: PDO
Nette DI size neredeyse her şeyi yazmanız için son derece güçlü ifade olanakları sunar. Örneğin, başka bir servise başvurmak ve onun metodunu çağırmak için. Basitlik için ->
yerine
::
kullanılır.
services:
routerFactory: App\Router\Factory
router: @routerFactory::create()
PHP koduna karşılık gelir:
public function createServiceRouterFactory(): App\Router\Factory
{
return new App\Router\Factory;
}
public function createServiceRouter(): Router
{
return $this->getService('routerFactory')->create();
}
PHP'de olduğu gibi yöntem çağrıları zincirleme olarak birbirine eklenebilir:
services:
foo: FooFactory::build()::get()
PHP koduna karşılık gelir:
public function createServiceFoo()
{
return FooFactory::build()->get();
}
Argümanlar
Adlandırılmış parametreler argümanları iletmek için de kullanılabilir:
services:
database: PDO(
'mysql:host=127.0.0.1;dbname=test' # konumsal
username: root # named
password: secret # named
)
Argümanları birden fazla satıra bölerken virgül kullanımı isteğe bağlıdır.
Elbette, diğer hizmetleri veya parametreleri de argüman olarak kullanabiliriz:
services:
- Foo(@anotherService, %appDir%)
PHP koduna karşılık gelir:
public function createService01(): Foo
{
return new Foo($this->getService('anotherService'), '...');
}
İlk bağımsız değişken otomatik olarak
bağlanmışsa ve ikincisini belirtmek istiyorsanız, ilkini _
character, for example
Foo(_, %appDir%)
ile atlayın. Ya da daha iyisi, yalnızca ikinci bağımsız değişkeni adlandırılmış bir parametre olarak iletin, örneğin
Foo(path: %appDir%)
.
Nette DI ve NEON formatı size neredeyse her şeyi yazmanız için son derece güçlü ifade olanakları sağlar. Böylece bir argüman yeni oluşturulmuş bir nesne olabilir, statik metotları, diğer servislerin metotlarını ve hatta özel gösterim kullanarak global fonksiyonları çağırabilirsiniz:
services:
analyser: My\Analyser(
FilesystemIterator(%appDir%) # nesne oluştur
DateTime::createFromFormat('Y-m-d') # statik yöntemi çağırın
@anotherService # başka bir hizmet geçirme
@http.request::getRemoteAddress() # başka bir hizmet yöntemini çağırma
::getenv(NetteMode) # global bir fonksiyon çağırın
)
PHP koduna karşılık gelir:
public function createServiceAnalyser(): My\Analyser
{
return new My\Analyser(
new FilesystemIterator('...'),
DateTime::createFromFormat('Y-m-d'),
$this->getService('anotherService'),
$this->getService('http.request')->getRemoteAddress(),
getenv('NetteMode')
);
}
Özel Fonksiyonlar
Değerleri atamak veya olumsuzlamak için argümanlarda özel fonksiyonlar da kullanabilirsiniz:
not(%arg%)
olumsuzlamabool(%arg%)
bool'a kayıpsız dökümint(%arg%)
int'e kayıpsız dökümfloat(%arg%)
float'a kayıpsız dökümstring(%arg%)
dizeye kayıpsız döküm
services:
- Foo(
id: int(::getenv('ProjectId'))
productionMode: not(%debugMode%)
)
Kayıpsız yeniden yazım, normal PHP yeniden yazımından farklıdır, örneğin (int)
, sayısal olmayan
değerler için bir istisna atar.
Birden fazla hizmet argüman olarak aktarılabilir. Belirli bir türdeki (yani, sınıf veya arayüz) tüm hizmetlerin bir
dizisi typed()
işlevi tarafından oluşturulur. İşlev, otomatik kablolamanın devre dışı bırakıldığı
hizmetleri atlar ve virgülle ayrılmış birden fazla tür belirtilebilir.
services:
- BarsDependent( typed(Bar) )
Otomatik kablolamayı kullanarak bir dizi hizmeti otomatik olarak da geçirebilirsiniz.
Belirli bir etikete sahip tüm hizmetlerin bir dizisi tagged()
işlevi tarafından
oluşturulur. Virgülle ayrılmış birden fazla etiket belirtilebilir.
services:
- LoggersDependent( tagged(logger) )
Referanslama Hizmetleri
Bireysel hizmetlere @
and name, so for example @database
karakteri kullanılarak atıfta
bulunulur:
services:
- create: Foo(@database)
setup:
- setCacheStorage(@cache.storage)
PHP koduna karşılık gelir:
public function createService01(): Foo
{
$service = new Foo($this->getService('database'));
$service->setCacheStorage($this->getService('cache.storage'));
return $service;
}
Anonim hizmetlere bile bir geri arama kullanılarak başvurulabilir, sadece adları yerine türlerini (sınıf veya arayüz) belirtin. Ancak, otomatik bağlantı nedeniyle bu genellikle gerekli değildir.
services:
- create: Foo(@Nette\Database\Connection)
setup:
- setCacheStorage(@cache.storage)
Kurulum
Kurulum bölümünde, hizmet oluşturulurken çağrılacak yöntemleri listeliyoruz:
services:
database:
create: PDO(%dsn%, %user%, %password%)
setup:
- setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)
PHP koduna karşılık gelir:
public function createServiceDatabase(): PDO
{
$service = new PDO('...', '...', '...');
$service->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $service;
}
Özellikler de ayarlanabilir. Bir diziye eleman eklemek de desteklenir ve NEON sözdizimiyle çakışmaması için tırnak içinde yazılmalıdır:
services:
foo:
create: Foo
setup:
- $value = 123
- '$onClick[]' = [@bar, clickHandler]
PHP koduna karşılık gelir:
public function createServiceFoo(): Foo
{
$service = new Foo;
$service->value = 123;
$service->onClick[] = [$this->getService('bar'), 'clickHandler'];
return $service;
}
Ancak, statik yöntemler veya diğer hizmetlerin yöntemleri de kurulumda çağrılabilir. Onlara asıl servisi
@self
olarak iletiyoruz:
services:
foo:
create: Foo
setup:
- My\Helpers::initializeFoo(@self)
- @anotherService::setFoo(@self)
PHP koduna karşılık gelir:
public function createServiceFoo(): Foo
{
$service = new Foo;
My\Helpers::initializeFoo($service);
$this->getService('anotherService')->setFoo($service);
return $service;
}
Otomatik Kablolama
Otomatik bağlama anahtarı, bir hizmeti otomatik bağlamanın dışında tutmak veya davranışını etkilemek için kullanılabilir. Daha fazla bilgi için otomatik kablolama bölümüne bakın.
services:
foo:
create: Foo
autowired: false # foo otomatik bağlantıdan kaldırılır
Etiketler
Kullanıcı bilgileri tek tek hizmetlere etiket şeklinde eklenebilir:
services:
foo:
create: Foo
tags:
- cached
Etiketler bir değere de sahip olabilir:
services:
foo:
create: Foo
tags:
logger: monolog.logger.event
Belirli etiketlere sahip bir dizi hizmet, tagged()
işlevi kullanılarak argüman olarak aktarılabilir. Virgülle
ayrılmış birden fazla etiket de belirtilebilir.
services:
- LoggersDependent( tagged(logger) )
Hizmet adları findByTag()
yöntemi kullanılarak DI konteynerinden elde edilebilir:
$names = $container->findByTag('logger');
// $names, hizmet adını ve etiket değerini içeren bir dizidir
// i.e. ['foo' => 'monolog.logger.event', ...]
Enjeksiyon Modu
inject: true
bayrağı, bağımlılıkların inject ek açıklaması ve inject*() yöntemleri ile genel
değişkenler aracılığıyla aktarılmasını etkinleştirmek için kullanılır.
services:
articles:
create: App\Model\Articles
inject: true
Varsayılan olarak, inject
yalnızca sunum yapanlar için etkinleştirilir.
Hizmetlerin Değiştirilmesi
DI konteynerinde yerleşik veya uzantınız tarafından eklenen bir dizi hizmet vardır. Bu
hizmetlerin tanımları yapılandırmada değiştirilebilir. Örneğin, varsayılan olarak bir nesne olan
application.application
hizmeti için Nette\Application\Application
sınıfını değiştirebiliriz:
services:
application.application:
create: MyApplication
alteration: true
alteration
bayrağı bilgilendiricidir ve sadece mevcut bir hizmeti değiştirdiğimizi söyler.
Ayrıca bir kurulum da ekleyebiliriz:
services:
application.application:
create: MyApplication
alteration: true
setup:
- '$onStartup[]' = [@resource, init]
Bir hizmeti yeniden yazarken, orijinal argümanları, kurulum öğelerini veya etiketleri kaldırmak isteyebiliriz,
reset
bunun içindir:
services:
application.application:
create: MyApplication
alteration: true
reset:
- arguments
- setup
- tags
Uzantı ile eklenen bir hizmet konteynerden de kaldırılabilir:
services:
cache.journal: false