1.
class XApi implements ApiInterface {}
class YApi implements ApiInterface {}
// Controller içerisinde kullanırken...
public function index(ApiInterface $api) {}
// Service container'a eklerken...
// ApiInterface arayüzü enjekte edilirse XApi sınıfını ver:
$this->app>bind(ApiInterface::class, XApi::class);
XApi ve YApi aynı işi ve sonucu (mesela bir data transformer aracılığıyla) döndüren iki farklı servisin Api sınıfları. ApiInterface arayüzü ile kontrat yapmışlar. Service container sayesine ApiInterface arayüzünü enjekte ettiğimde bana XApi sınıfını veriyor. Eğer olurda ileride XApi'den vazgeçip YApi (ya da yeni eklenecek bir ZApi) kullanmam gerekirse sadece binding bölümünü değiştirmem yeterli olacak.
2.
$this->app->bind(Foo::class, function ($app) {
return new Foo($app->config['foo.username'], $app->config['foo.secret']);
});
Sınıf enjekte edilirken binding sayesinde constructor parametreleri belirleme gibi enjekte öncesi işlemleri yaptırabiliyorum. Öteki türlü sınıfı new Foo şeklinde manuel yüklemek zorunda kalabilirsiniz. (Bu şekilde arayüz (interface) bağlayamazsınız çünkü arayüz örneklenebilir (instantiable) bir obje değil. O yüzden duruma göre arayüzü kullanıp gerekli işlemleri yapan bir Manager yazılır ve o bağlanır)
3.
// HomeController içerisinde ApiInterface enjekte edilirse YApi sınıfını ver.
$this->app->when(HomeController::class)->needs(ApiInterface::class)->give(YApi::class);
Service container kullanmak SOLID prensiplerine uymanızı kolaylaştırır. Sanırım bu üçü en çok kullanılan sebepler. Dokümanlarda güzel örnekler var:
https://laravel.com/docs/6.0/container