Можно ли передавать DI Contantainer как зависимость через длинную цепочку классов, если только последний класс нуждается в этом точно?

Я пытаюсь реализовать маршрутизатор в моем приложении, используя DI-контейнер.

Итак, у меня есть класс Application, который загружает конфигурацию и имеет экземпляр контейнера DI. Приложение имеет Маршрутизатор как класс обслуживания, созданный DI. Маршрутизатор имеет массив классов Route, Route имеет Action, а Action имеет Target. Цель — Закрытие или имя класса контроллера + имя метода контроллера. Я хочу создать контроллер с помощью DI-контейнера, потому что я хочу внедрить некоторые сервисы.

Вот пример структуры.

Приложение класса {

приватный $ контейнер;

приватный роутер;

публичная функция __construct () {
$ this-> container = new DIContainer ();
$ this-> container-> add (SomeService :: class, function () {
вернуть новый SomeService ($ someConfigParams);
})
$ this-> router = $ this-> container-> get (Router :: class);
}

дескриптор публичной функции ($ uri) {
вернуть $ this-> router-> handle ($ uri);
}

}

class Router {

приватный $ контейнер;

частные $ маршруты; // Массив класса Route, заполненный addRoute

публичная функция __construct (контейнер $ контейнер) {
$ this-> container = $ container;
}

публичная функция addRoute ($ uri) {
$ маршруты [] = $ this-> container-> make (Route :: class, ['uri' => $ uri]);
}

дескриптор публичной функции ($ uri) {
$ route = $ this-> findRoute ($ uri) -> getAction () -> run ()
}

}

class Route {

приватный $ контейнер;

личное $ action; // экземпляр класса Action, заполненный setAction

публичная функция __construct (контейнер $ контейнер) {
$ this-> container = $ container;
}

публичная функция setAction ($ params) {
$ this-> action = $ this-> container-> make (Action :: class, $ params);
}

публичная функция getAction () {
вернуть $ this-> action ();
}
}

действие класса {

приватный $ контейнер;

частный $ target; // Экземпляр класса Target, заполненный setTarget

публичная функция __construct (контейнер $ контейнер) {
$ this-> container = $ container;
}

публичная функция setTarget () {
$ this-> target = $ this-> container-> make (Targer :: class)
}

публичная функция run () {
return $ this-> target-> run ();
}
}

class Target {
приватный $ контейнер;

private $ controllerClass;

приватный $ controllerMethod;

публичная функция __construct (контейнер $ контейнер, $ класс, $ метод) {
$ this-> container = $ container;
$ this-> controllerClass = $ class;
$ this-> controllerMethod = $ method;
}

публичная функция run () {
return $ this-> container-> make ($ this-> controllerClass) -> {$ this-> controllerMethod} ();
}
}

//И наконец!

Контроллер класса {

private $ someService;

публичная функция __construct (SomeService $ someService) {
$ this-> someService = $ someService;
}

проверка публичной функции () {
return $ this-> someService-> sayHello ();
}

}

новое приложение () -> дескриптор ('/ controller / test /');

Извините за такой большой пример кода. Но мне действительно интересно, нормально ли, что все классы в цепочке зависят от $ container только потому, что контроллеру нужен сервис. Или я должен просто сделать свой класс Container глобальным (например, singleton) и вызвать его на последнем шаге? Как это:

...
// Целевой класс
публичная функция run () {
return Container :: getInstance () -> make ($ this-> controllerClass) -> {$ this-> controllerMethod} ()
}
...

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]