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%) olumsuzlama
  • bool(%arg%) bool'a kayıpsız döküm
  • int(%arg%) int'e kayıpsız döküm
  • float(%arg%) float'a kayıpsız döküm
  • string(%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
versiyon: 3.x