DI kabı erişme

3 Cevap php

Ben yeni bir proje başlangıç ​​ve üzerinde çalışmak için üs kuruyorum. Birkaç soru arttı ve ben muhtemelen umarım bazı cevaplar bulacaksınız, burada epeyce soran olacak.

İlk adım nesneler için bağımlılıkları idare etmektir. Ben uygulama için tüm bu işlemek için ben biraz yeniyim hangi bağımlılık enjeksiyon tasarım deseni, birlikte gitmeye karar verdik.

Aslında kodlama zaman ben bir sorun geldi. Bir sınıfın birden bağımlılıkları vardır ve (onlar nesne örneğini sonra değiştirilemez böylece) yapıcısı aracılığıyla çoklu bağımlılıkları geçmek istiyorum.

Bunu nasıl) (call_user_func_array kullanarak, bağımlılıkları dizisi geçirerek olmadan yapacağız, eval () veya yansıma? Bu benim aradığım budur:

<?php

class DI
{
    public function getClass($classname)
    {
        if(!$this->pool[$classname]) {
            # Load dependencies
            $deps = $this->loadDependencies($classname);

            # Here is where the magic should happen
            $instance = new $classname($dep1, $dep2, $dep3);

            # Add to pool
            $this->pool[$classname] = $instance;

            return $instance;
        } else {
                return $this->pool[$classname];
        }
    }
}

Yine, ben sınıf aramak için en pahalı yöntemleri önlemek istiyorum. Başka bir öneriniz?

Ayrıca, nasıl farklı modeller erişmek için gereken kontrolörleri, örneğin, sınıfları içinde DI sınıf erişmek mi? Ben statik onu aramak ya da gerektirecek her sınıfta bunu iletmekten mıyım? Ben son fikir mümkün olduğunu sanmıyorum.

Herkese teşekkürler.

3 Cevap

Ben başlamadan önce [, beni çoğunlukla bir Java programcısı olduğumu diyelim - PHP bilginin sadece biraz ile. Ama ben sadece dil özellikleriyle olmadan genelinde en önemli kavramları almaya çalışacağım.]

Bağımlılık Enjeksiyon iki kod parçaları dayanır:

  1. İnşaat
  2. Infaz

En aşırı şekli, Yürütme kısmında bulunan hiçbir new operatörleri vardır. Bunların hepsi, Yapı kısmı içine taşınır. (Uygulamada, bu tonda olacaktır.)

Inşaat tüm olur - İnşaat parçası. Bu Yürütme aşağıdan yukarıya için gerekli nesnelerin grafik oluşturur. Diyelim ki, bu A oluşturmalıdır:

  • A B bağlıdır, ve
  • B C bağlıdır

O zaman

  • C ilk olarak inşa edilmiştir.
  • O zaman B is constructed with C as a parameter.
  • O zaman A is constructed with B as a parameter.

Yani C bu oldukça küçük bir sayı etrafında geçirilecek olan nesnelerin miktarını azaltır ne kadar, Bu küçük örnek, yeterince güçlü göstermek değil A. yapıcı parametre olarak geçirilmesi gerekmez.

Bağımlılık Enjektör kendisi Yürütme parçası haline geçirilmemelidir. Bu (kendim dahil) temel hatalar herkesin biri de ilk DI ile temas ettiğinde, yapmak için çalışır. Sorun bu tamamen İnşaat ve İcra arasındaki çizgiler bulanıklık olacağını, olduğunu. Bunu söylemek için başka bir yolu Law of Demeter ihlal edecek olmasıdır. Veya desen konuşuyoruz: Sonunda Hizmet Bulma desen Bağımlılık Enjeksiyon deseni "aşağılamak" olacaktır. Bu gerçekten bir bozulma olup olmadığını, tartışılabilir, ama her durumda it's usually not a good idea to misuse the Dependency Injector as a Service Locator.

Eğer inşa nesnelerden birini, yürütülmesi sırasında diğer nesneleri üretmek yerine Bağımlılık Enjektör geçme, yalnızca basit Sağlayıcıları geçerdi yeteneği vermek gerekir, böylece zaman (Java DI çerçevesi tarafından kullanılan bir terim Guice) . Bunlar sadece nesnenin belirli bir tür oluşturmak oldukça basit sınıflardır. Onlar bir fabrika ile benzerlikleri var.

İlk kurucusuna doğrudan gerekli bağımlılıkları geçmek deneyin.

Yani özetlemek gerekirse:

  • Nesneleri aşağıdan yukarıya inşa.
  • Bir nesne oluşturmak için gerekli olarak sadece birkaç bağımlılıkları geçmektedir.
  • Senin bitmiş kez çalıştırmaya başlayabilirsiniz.
  • Icrası sırasında, yine Sağlayıcıları kullanarak yeni oluşturulan nesneler getirebilir.

Ancak bunu çok fazla almayın: Basit nesneleri hala Sağlayıcı :-) olmadan oluşturulabilir

Ve şimdi, yapmanız gerekecek tüm kalite koduna bu şeyleri tercüme etmektir. Belki diğerleri birkaç PHP örnekler size yardımcı olabilir.

Addendum: A little bit more about Providers

Yukarıda belirtildiği gibi, kavramı "Provider" (özel bir fabrika) Java DI çerçevesinde Guice biraz özeldir. Bu çerçeve otomatik olarak herhangi bir nesne türü için Sağlayıcı oluşturabilirsiniz. Ancak, kavram genel olarak DI için yararlıdır. Tek fark Guice veya benzer bir çerçeve yardımı olmadan, Sağlayıcıları kendiniz yazmak gerekir ki, - ama oldukça kolaydır:

Diyelim, B C bağlıdır

  • B sadece C bir sabit örneğini ihtiyacı varsa, o zaman bir Provider gerekmez - sadece yapıcı argüman C. ile B oluşturabiliriz
  • If B needs to create more instances of C during execution, then just write a class called CProvider with a get() method, that can create a new instance of C. O zaman pass an instance of CProvider into the constructor of B, and store the Provider in an instance field of B. Now B can call cProvider.get() when it needs a new instance of C.

Sağlayıcıları İnşaat kod parçası, bu nedenle kullanmak için izin konum new C(...)! Öte yandan, onlar Yürütme kod parçası değiliz, bu yüzden orada herhangi bir yürütme mantığı olmamalıdır.

CProvider Tabii birden yapıcıları içine aktarılabilir. Ayrıca birden sürümlerini yazabilirsiniz CProvider1, CProvider2, ... - her biri farklı özelliklere sahip C nesnelerin farklı sürümlerini oluşturmak nerede. Yoksa basit instantiate farklı argümanlarla CProvider birden çok kez.

Eğer sizin için bağımlılıkları yönetmek için IOC kabını kullanarak içine bakmak gerekir. İyi bir IOC konteyner sizin için bağımlı Müteahhitler arasındaki bağımlılıkları geçen özen.

Varolan question PHP için IOC konteyner seçenekleri hakkında soran var.

Kendi bağımlılık enjeksiyon konteyner yaygınlaştırmaya çalışıyor gibi görünüyor. Neden zaten Symfony, Crafty veya Sphicy gibi, var olanı kullanmak değil mi?