MVC, DI (bağımlılık enjeksiyon) ve Denetleyicisi'nden Modeli örneği oluşturma

2 Cevap php

Benim Dispatcher doğru Denetleyicisi "seçimi" olduğunu; sonra (DependencyInjectionContainer Kontrolör kurucu geçirilen) Denetleyicisinin örneğini oluşturarak; sonra bazı Kontrolörün yöntemini çağırarak ...

class UserController extends Controller
{

  public function __construct(DependencyInjectionContainer $injection) {
    $this->container = $injection;
  }

  public function detailsAction() {
    ...
  }

}

DependencyInjectionContainer contains DB adapter object, Config object etc. Now let's see what detailsAction() method contains...

public function detailsAction() {

  $model = new UserModel();
  $model->getDetails(12345);

}

As you see I'm creating new instance of UserModel and calling getDetails methods. Model's getDetails() method should connect to db to get information about user. To connect to DB UserModel should be able to access DB adapter.

What is the right way to pass DependencyInjectionContainer to the UserModel? I think that this way is wrong...

public function detailsAction() {

  $model = new UserModel($this->container);
  $model->getDetails(12345);

}

2 Cevap

Bunun yerine sınıfa tüm DI Konteyner enjekte, sen inject only the dependencies ihtiyacınız olmalıdır.

Sizin UserController DB Adaptörü (Kullanıcı bu arabirim IDBAdapter diyelim) gerektirir. C # bu şöyle olabilir:

public class UserController
{
    private readonly IDBAdapter db;

    public UserController(IDBAdapter db)
    {
        if (db == null)
        {
            throw new ArgumentNullException("db");
        }

        this.db = db;
    }

    public void DetailsAction()
    {
        var model = new UserModel(this.db);
        model.GetDetails(12345);
    }
}

Bu durumda biz UserModel içine bağımlılık injectiing vardır. Çoğu durumda, ancak, ben UserController sadece onu geçmek için bir bağımlılık sürerse ona bir DI koku dikkate eğiliminde olacaktır, bu yüzden daha iyi bir yaklaşım şöyle bir Özet Factory bir bağımlılık almak UserController için olabilir:

public interface IUserModelFactory
{
    UserModel Create();
}

Bu varyasyon, UserController bu gibi görünebilir:

public class UserController
{
    private readonly IUserModelFactory factory;

    public UserController(IUserModelFactory factory)
    {
        if (factory == null)
        {
            throw new ArgumentNullException("factory");
        }

        this.factory = factory;
    }

    public void DetailsAction()
    {
        var model = this.factory.Create();
        model.GetDetails(12345);
    }
}

ve IDBAdapter bir bağımlılık alır somut UserModelFactory tanımlayabilirsiniz:

public class UserModelFactory : IUserModelFactory
{
    private readonly IDBAdapter db;

    public UserModelFactory(IDBAdapter db)
    {
        if (db == null)
        {
            throw new ArgumentNullException("db");
        }

        this.db = db;
    }

    public UserModel Create()
    {
        return new UserModel(this.db);
    }
}

Bu size daha iyi verir separation of concerns.

Birden fazla bağımlılık gerekiyorsa, sadece yapıcı aracılığıyla onları enjekte. Eğer çok fazla almak başladığınızda, bu Single Responsibility Principle ihlal işarettir, ve refactor to Aggregate Services zamanı.

I'd use a singleton object for all config parameters : You set it up in your bootstrap, then choose to use it directly or pass it as parameter in your objects.

Fikir yapılandırma verileri almak için çevresinde bir yöntemi var olmak.

You may then provide an abstract class for db manipulation which uses your config. singleton. DependancyInjection can still be used to override your default data.

Yorumunda yukarıdaki bağlantı (mümkünse 'yinelenen') yapıcı enjeksiyon kullanarak sonuca varıyor: Bu geçerli yöntemine yakındır.

Ben modeli nasıl çalıştığını anlamaya çalışın Ancak, ben "userModel" dışında diğer birçok modeli sınıfları olacak sanırım. Böylece yapılandırma Singleton kullanarak soyut bir sınıf iyi bir çözüm olabilir: tüm sonraki model sınıfları sadece bu soyut sınıf uzatacak, ve size yapılandırma konusunda endişelenmenize gerek yok.

Diğer taraftan, çözüm sürece dependanceInjectionContainer sık ​​değişir olarak benim için iyidir.