۱۳۹۹/۰۴/۱۹

آموزش autowiring در فریم ورک سیمفونی

Symfony's autowiring ۱۳۹۸/۰۵/۳۰

سرویس ها یکی از ابزار بسیار کاربردی در سیفونی است که روند توسعه نرم افزار در سیمفونی را سریعتر میکند در این این پست در مورد سرویس ها در سیمفونی توضیح داده شده است .

بوسیله autowiring شما میتتوانید سرویس های خود را در سیمفونی پیکر بندی کنید.بطور مثال هنگام تعریف سرویس اگر بخواهیم مقادیر را به سرویس مورد نظر تزریق کنیم با استفاده از autowiring این کار انجام میشود.

autowiring قابلیت های بیشماری را  برای کار با سرویس ها در اختیار شما قرار میدهد که در این مقاله به برخی از این ویژگی ها میپردازیم.

تعریف سرویس

.برای تعریف سرویس در ابتدا ما نام سرویس و کلاس مربوط به ان را در فایل services.yml مشخص  میکنیم.در واقع در این فایل لیستی از سرویس ها به همراه نام کلاس های مربوط به هر سرویس مشخص شده است..

هنگامیکه یک سرویس در برنامه فراخوانی میشود.سیمفونی تلاش میکند نام کللاس سرویس را در فایل services.yml پیدا و اجرا کند.

# services.yml
mailer:
    class: AppBundle\Service\MailerService

renderer:
    class: AppBundle\Service\RenderService

 

فرض کنید شما یک سرویس دارید که نیاز به یک سرویس دیگر دارد.بعنوان مثال  سرویس mail که را برای اراسل ایمیل استفاده میکنید.نیاز  یه یک سرویس دیگر برای رندر کردن قالب ایمیل  نیاز دارد.سیمفونی به شما اجازه میدهد سرویس قالب را به سرویس mail تزریق کنیم.

class MailerService {
	  protected $renderer;
  	
	  function __construct(RenderService $renderer) {
	    $this->renderer = $renderer;
	  }
  	
	  function sendMailing(string $template, array $data) {
	    $mail = $this->renderer->render($template, $data);
	    $this->send($mail);
	  }
	}

در این مثال سرویس render به عنوان یک وابستگی به سرویس mail تزریق میشود.سرویس mail از نوع سرویسی که تزریق شده اگاه نیست.ممکن است یک قالب twig و یا یک کلاس ساده برای چاپ مقادیر باشد.

 

در این مثال ، سرویس رندر به عنوان یک وابستگی به سرویس پستی تزریق می شود. سرویس نامه پستی خود از این نوع ارائه دهنده چیست آگاه نیست: ممکن است این یک ارائه دهنده قالب Twig ، یک موتور قالب هوشمند و یا حتی یک ارائه دهنده ساده PHP باشد. این امکان را برای جدا کردن خدمات فراهم می کند.کلیه وابستگی ها در فایل services.yml تعریف و مشخص میشود.

# services.yml
mailer:
    class: AppBundle\Service\MailerService
    arguments: [ "@renderer" ]

renderer:
    class: AppBundle\Service\RenderService

گزینه arguments در services.yml سرویسی که باید یه سرویس مورد نظر تزریق شود را مشخص میکند.سیمفونی در واقع حواسش به همه چیز است در مثال بالا ابتدا یک نمونه از کلاس render ساخته میشود قبل از اینکه کلاس mail ساخته شود.

Automatic generation of services

حالا میدانیم که چطور از سرویس ها در سیمفونی استفاده کنیم .در ادامه در مورد autowiring صحبت میکنیم.اولین نکته در مورد autowiring این است که بدانید.Symfony بطور خودکار سرویس را ایجاد میکند از classes automatically  بدون اینکه فایل service.yml را برای پیدا کردن کلاس سرویس بررسی کند.

بدیهی است سیمفونی نمیداند شما دوست دارید از چه سرویسی در برنامه خود استفاده کنید.و فقط  از این قابلیت برای سرویس های استفاده میشود که  (fully qualified class name (FQCN باشند.سرویس mail در مثال بالا AppBundle\Service\MailerService بطور خودکار ثبت میشود.

اینکار بطور خودکار برای همه سرویس های شما انجام نمیشود.شما باید بعد از ساختن کلاس namespace به همرا نام کلاس را در فایل services.yml مشخص کنید.

services:

    AppBundle\Service\:
        resource: '../../src/AppBundle/Service'

بوسیله کد بالا ما مشخص کردیم تمام کلاس هایی که در پوشه service هستند در برنامه در هنگام فرخوانی تزریق شوند.برای مثال اگر دو سرویس \AppBundle\Service\MailerService و \AppBundle\Service\RenderService در پوشه service باشند.بطور خودکار ایجاد میشوند.

اگر ما نیاز به arguments در سرویس خود بری پردازش داشته باشیم ارگومنت ها را به طریق زیر در سرویس تزریق میکنیم.

services:

    AppBundle\Service\:
        resource: '../../src/AppBundle/Service'
        
    mailer:
        class: AppBundle\Service\MailerService
        arguments: [ "@AppBundle\Service\RenderService" ]

در کد بالا سرویس mailer تعرف شده است که وابستگی RenderService  به ان تزریق شده است.

 

سرویس های در سیمفونی

Autowiring dependencies

اگر به مثال قبلی نگاه کنید میبینید که constructor  کلاس mail از یک وابستگی استفاده میکند

function __construct(RenderService $renderer) {

همانطور که میبینید کلاس mailer نیاز به یک typehint دارد.سیمفونی به شما اجازه میدهد که \AppBundle\Service\RenderService را به constructor  تزریق کنید.

در زمان autowiring سیمفونی service container را بررسی میکند.تا ببیند چنین service تعریف شده است یا خیر.در اینصورت این سرویس را به بصورت خودکار به constructor تزریق میکند.حتی اگر این سرویس را شما پیکربندی نکرده باشید  و از تنظیمات arguments  استفاده نکرده باشید.

این یکی از ویژگی های autowiring در سیفونی است :که تمام وابستگی های برنامه را که بر پایه fully qualified class name به هم ربط میدهد.

برای اینکه سیفمونی بتواند تمام وابستگی ها را بطور خودکار مرتبط کند باید انرا صریحا در service.yml تعریف کنید.

    services:
        AppBundle\Service\:
            resource: '../../src/AppBundle/Service'
            autowire: true

بوسیله کد بالا تمام service های موجود در پوشه  AppBundle\Service بصورت خودکار autowired میشوند.

چه زمانی autowiring  کار نمیکند؟

 این امکان وجود دارد که autowiring  همیشه کار نکند.این زمانی اتفاق می افتد که شما کلاسی را به سرویس تزریق کنید که در  service container شما وجود نداشته باشد.یا ممکن است چندیدن سرویس از نوع سرویس مورد نیاز شما وجو داشته باشد.و یا typehint  شما از نمونه ای از یک interfaces باشد.و یا زمانی که کلاس شما extend شده باشد از چندین subclasses.

با یک مثال مسائل بالا را روشنتر میکنیم.فرض کنید نیاز داریم کلاس interface به نام  ImageLoaderInterface را صدا بزنیم.این کلاس سه concrete classes به نام های JpgLoader , GifLoaderو PngLoader دارد.الان نیاز داریم یک کلاس ImageProcessor  را بسازیم که وابستگی به یکی از این لودرها دارد.

 class ImageProcessor {
    	function __construct(ImageLoaderInterface $loader) {
	    	// ...
    	}    
    }

اگر ما از autowiring استفاده کرده باشیم.سیمفونی نمیداند که کدام یک از لودرها باید autowiring شوند.و از شما میخواهد که در فایل service.yml دقیقا مشخص کنید به کدام یک از لودرها در سرویس نیاز دارید.

services:
    AppBundle\Service\:
        resource: '../../src/AppBundle/Service'
        autowire: true
        
    AppBundle\Service\ImageLoaderInterface: '@AppBundle\Service\JpgLoader'

در کد بالا هر بار که سیمفونی تایپ هینتtypehint ImageLoaderInterface را پیدا کند.میداند که باید به JpgLoader متصل شود.

هر زمان که سیموفنی نتواند سرویس ها را تنظیم خودکار یا autowire کند .با پرتاب یک استثنا این امکان را به شما میدهد که بصورت دستی مشکل را در service.yml برطرف کنید.

Autoconfiguration در فریم ورک سیمفونی

Autoconfiguration رابطه نزدیکی با autowiring دارند.در autowiring هر گونه وابستگی به service ها متصل میشود.autoconfiguration در واقع آن service ها را پیکربندی میکند.این همیشه لازم نیست.اما شما در بعضی موارد نیاز دارید با autoconfiguration  برچسب ها را به سرویس ها اضافه کنید.

معمولا زمانی که ما چیزهایی مثل  twig extensions,سفارشی form types, یا  Event Subscriber نیاز داریم باید به انها تگ هایی مثل  twig.extensionform.typekernel.subscriber اضافه کنیم.این کار به container اجازه میدهد تا سرویس های برچسب گذاری شده را در حین کامپایل برنامه پیدا کند.بعنوان مثل سرویس twig سعی میکند تمام سرویس ها با برچسب  twig.extension را پیدا کند.و تمام ان سرویس ها را به twig extensions اضافه میکند.تا بطور خوکار بتوانید از extensions خود در twig  استفاده کنید.

   services:
        my.twig.extension:
            class: AppBundle\Twig\Extension\MyExtension
            tags:
              - { name: twig.extension }

زمانیکه از autowiring استفاده میکنید.بسیاری از service بطور خود کار میتوان فراخوانی کرد.مگر اینکه پیشفرضautowiring  در service.yml را در خاموش کنید .در اینصورت کلیه سرویس ها را باید در فایل service.yml بصورت دستی تعریف کنید.و بعد از ان نمیتوانید از قابلیت های autowiring استفاده کنید.

php-1 آموزش سیفونی

با استفاده از تنظیمات autoconfiguration میتوانید بصورت خودکار این تنطیمات را پیکربندی کنید.برای هر سرویس که با یک کلاس خاص یا کلاس والد مطابقتداشته باشد میتوانید از autoconfiguration برای سرویس های خود  استفاده کنید.

برای مثال هر twig extension که ایجاد میکنید.باید implement باشد از یک کلاس Twig_ExtensionInterface.در سرویس اصلی twig  باید هر سرویسی که از این انترفیس implements  میشود را پیاده سازی کنیم.با اینکار تمام این سرویس ها با تگ  twig.extension برچسب گزاری میشوند.اینکار را باید در فایل TwigExtension.php انجام بدهیم.

$container
		->registerForAutoconfiguration(\Twig_ExtensionInterface::class)
		->addTag('twig.extension')
	;

با این کد autoconfigures هر سرویسی که نمونه ای از کلاس Twig_Extension باشد را برچسب گزاری میکند با تگ twig.extension

بیشتر  autoconfigurations  را می توانید در فایل FrameworkBundle پیدا کنید.

        $container->registerForAutoconfiguration(Command::class)
            ->addTag('console.command');
        $container->registerForAutoconfiguration(ResourceCheckerInterface::class)
            ->addTag('config_cache.resource_checker');
        $container->registerForAutoconfiguration(ServiceSubscriberInterface::class)
            ->addTag('container.service_subscriber');
        $container->registerForAutoconfiguration(AbstractController::class)
            ->addTag('controller.service_arguments');
        $container->registerForAutoconfiguration(Controller::class)
            ->addTag('controller.service_arguments');
        $container->registerForAutoconfiguration(DataCollectorInterface::class)
            ->addTag('data_collector');
        $container->registerForAutoconfiguration(FormTypeInterface::class)
            ->addTag('form.type');
        $container->registerForAutoconfiguration(FormTypeGuesserInterface::class)
            ->addTag('form.type_guesser');

کد های بالا بطور خودکار تمام   tags commands, controllers, form types و...برچسب گذاری میکنند.

Autoconfiguration در سرویس 

علاوه بر استفاده از روش registerForAutoConfiguration  در  service container .شما میتوانید autoconfiguration  مستقیم در فایل services.yml تعریف کنید.

برای نمونه فرض کنید فرض می کنیم شما می خواهیدautoconfigure کنید . هر  نمونه ای از ImageLoaderInterface را با برچسب image.loader 

services:
    ....

     _instanceof:
        AppBundle\ImageLoaderInterface:
            tags: ['image.loader']
            public: false

با کد بالا هر سرویسی که از کلاسImageLoaderInterface پیاده سازی یا implements  باشد.بطور خودکار با برچسب image.loader برچسب گذاری میشود.گزینه های دیگر هم برای autoconfiguration وجود دارد .ولی اغلب از این موارد برای برچسب کذاری سرویس ها استفاده میشود.


رای :

Symfony's autowiring

سرویس در سیمفونی

سیفونی فریم ورک

Autoconfiguration

ارسال نظر
Copyright © All right reserved.