ظرف IoC
معرفی
وارونگی کانتینر کنترل لاراول ابزاری قدرتمند برای مدیریت وابستگی های کلاس است. تزریق وابستگی روشی برای حذف وابستگی های کلاس سخت کد شده است. در عوض، وابستگیها در زمان اجرا تزریق میشوند و به انعطافپذیری بیشتری اجازه میدهند زیرا پیادهسازیهای وابستگی ممکن است به راحتی تعویض شوند.
درک کانتینر لاراول IoC برای ساخت یک برنامه قدرتمند و بزرگ و همچنین برای کمک به خود هسته لاراول ضروری است.
استفاده پایه
اتصال یک نوع به ظرف
دو راه وجود دارد که کانتینر IoC میتواند وابستگیها را حل کند: از طریق تماسهای Close یا وضوح خودکار. ابتدا، ما تماس های بسته شدن را بررسی می کنیم. ابتدا، یک "نوع" ممکن است به ظرف متصل شود:
App::bind('foo', function($app){ return new FooBar;});
حل یک نوع از کانتینر
$value = App::make('foo');
هنگامی که
App::make
متد فراخوانی می شود، بازخوانی Closure اجرا می شود و نتیجه برگردانده می
شود.
اتصال یک نوع "به اشتراک گذاشته شده" در ظرف
گاهی اوقات، ممکن است بخواهید چیزی را به کانتینر متصل کنید که فقط یک بار باید حل شود، و همان نمونه باید در تماسهای بعدی به کانتینر برگردانده شود:
App::singleton('foo', function(){ return new FooBar;});
اتصال یک نمونه موجود به کانتینر
همچنین می توانید یک نمونه شی موجود را با استفاده از روش زیر به کانتینر
متصل کنید
instance
:
$foo = new Foo; App::instance('foo', $foo);
محل ثبت صحافی
اتصالهای IoC، مانند کنترلکنندههای رویداد یا فیلترهای مسیر، معمولاً تحت
عنوان «کد بوت استرپ» قرار میگیرند.
به عبارت دیگر، آنها برنامه شما را برای رسیدگی واقعی به درخواستها آماده
میکنند و معمولاً باید قبل از فراخوانی یک مسیر یا کنترلکننده، اجرا شوند.
مانند اکثر کدهای بوت استرپ دیگر،
start
فایل ها همیشه گزینه ای برای ثبت اتصالات IoC هستند.
از طرف دیگر، می توانید یک
app/ioc.php
فایل (نام فایل مهم نیست) ایجاد کنید و آن فایل را از
start
فایل خود بخواهید.
اگر برنامه شما دارای تعداد بسیار زیادی اتصال IoC است، یا به سادگی می خواهید پیوندهای IoC خود را در فایل های جداگانه بر اساس دسته بندی سازماندهی کنید، می توانید پیوندهای خود را در یک ارائه دهنده خدمات ثبت کنید .
وضوح خودکار
حل یک کلاس
کانتینر IoC به اندازه کافی قدرتمند است تا در بسیاری از سناریوها کلاس ها را بدون هیچ گونه پیکربندی حل کند. مثلا:
class FooBar { public function __construct(Baz $baz) { $this->baz = $baz; } } $fooBar = App::make('FooBar');
توجه داشته باشید که با وجود اینکه کلاس FooBar را در کانتینر ثبت نکرده
ایم، کانتینر همچنان می تواند کلاس را حل کند، حتی اگر
Baz
وابستگی را به صورت خودکار تزریق کند!
هنگامی که یک نوع در کانتینر محدود نباشد، از امکانات Reflection PHP برای بازرسی کلاس و خواندن نکات نوع سازنده استفاده می کند. با استفاده از این اطلاعات، کانتینر می تواند به طور خودکار یک نمونه از کلاس بسازد.
اتصال یک رابط به یک پیاده سازی
با این حال، در برخی موارد، یک کلاس ممکن است به پیاده سازی رابط بستگی
داشته باشد، نه یک "نوع بتن".
در این صورت،
App::bind
باید از این روش برای اطلاع دادن به کانتینر استفاده شود که کدام رابط را
تزریق کند:
App::bind('UserRepositoryInterface', 'DbUserRepository');
اکنون کنترلر زیر را در نظر بگیرید:
class UserController extends BaseController { public function __construct(UserRepositoryInterface $users) { $this->users = $users; } }
از آنجایی که ما آن را
UserRepositoryInterface
به یک نوع بتن متصل کرده ایم،
DbUserRepository
پس از ایجاد آن، به طور خودکار به این کنترلر تزریق می شود.
استفاده عملی
لاراول چندین فرصت برای استفاده از کانتینر IoC برای افزایش انعطاف پذیری و آزمایش پذیری برنامه شما فراهم می کند. یکی از مثالهای اصلی، حل کردن کنترلرها است. همه کنترلرها از طریق کانتینر IoC حل می شوند، به این معنی که می توانید وابستگی ها را در سازنده کنترلر تایپ کنید و آنها به طور خودکار تزریق می شوند.
وابستگی های کنترل کننده تایپ
class OrderController extends BaseController { public function __construct(OrderRepository $orders) { $this->orders = $orders; } public function getIndex() { $all = $this->orders->all(); return View::make('orders', compact('all')); } }
در این مثال،
OrderRepository
کلاس به طور خودکار به کنترلر تزریق می شود.
این به این معنی است که هنگام
آزمایش واحد،
ممکن است یک "ملک"
OrderRepository
به ظرف متصل شده و به کنترلر تزریق شود، که اجازه می دهد تا تعامل لایه
پایگاه داده بدون درد ایجاد شود.
نمونه های دیگر استفاده از IoC
فیلترها ، composerها و کنترلکنندههای رویداد نیز ممکن است خارج از ظرف IoC حل شوند. هنگام ثبت نام، به سادگی نام کلاسی که باید استفاده شود را وارد کنید:
Route::filter('foo', 'FooFilter'); View::composer('foo', 'FooComposer'); Event::listen('foo', 'FooHandler');
ارائه دهندگان خدمات
ارائه دهندگان خدمات یک راه عالی برای گروه بندی ثبت های IoC مرتبط در یک مکان واحد هستند. به آنها به عنوان راهی برای بوت استرپ کردن مؤلفه ها در برنامه خود فکر کنید. در یک ارائهدهنده خدمات، ممکن است یک درایور احراز هویت سفارشی ثبت کنید، کلاسهای مخزن برنامه خود را با ظرف IoC ثبت کنید، یا حتی یک دستور Artisan سفارشی را تنظیم کنید.
در واقع، بیشتر اجزای اصلی لاراول شامل ارائه دهندگان خدمات می شود.
همه ارائه دهندگان خدمات ثبت شده برای برنامه شما در
providers
آرایه
app/config/app.php
فایل پیکربندی فهرست شده اند.
تعریف ارائه دهنده خدمات
برای ایجاد یک ارائه دهنده خدمات، به سادگی
Illuminate\Support\ServiceProvider
کلاس را گسترش دهید و یک
register
متد تعریف کنید:
use Illuminate\Support\ServiceProvider; class FooServiceProvider extends ServiceProvider { public function register() { $this->app->bind('foo', function() { return new Foo; }); } }
توجه داشته باشید که در
register
روش، کانتینر IoC اپلیکیشن از طریق ویژگی در دسترس شماست
$this->app
.
هنگامی که یک ارائه دهنده ایجاد کردید و برای ثبت آن در برنامه خود آماده
شدید، به سادگی آن را به
providers
آرایه موجود در
app
فایل پیکربندی خود اضافه کنید.
ثبت یک ارائه دهنده خدمات در زمان اجرا
همچنین می توانید یک ارائه دهنده خدمات را در زمان اجرا با استفاده از
App::register
روش زیر ثبت کنید:
App::register('FooServiceProvider');
رویدادهای کانتینری
ثبت نام شنونده حل و فصل
کانتینر هر بار که یک شی را حل می کند یک رویداد را شلیک می کند.
می توانید با استفاده از
resolving
روش زیر به این رویداد گوش دهید:
App::resolvingAny(function($object){ //}); App::resolving('foo', function($foo){ //});
توجه داشته باشید که شی ای که حل شد به callback ارسال می شود.