2016-10-30 3 views
1

делает инъекцию зависимости не позволяет ленивым зависимостям загрузки?Lazy loading невозможно с DI?

из-за того, что вам нужно передать экземпляры в конструктор, вы не можете сделать экземпляры позже

+0

Вы хотите ленивую нагрузку, потому что что-то не всегда необходимо? То есть это не зависимость? –

+0

его зависимость, но его используется в другом методе, который может быть вызван или нет. – xpedobearx

+0

. Тогда вам, вероятно, нужны сеттеры, а не передавать его в конструктор, если есть моменты, когда это не требуется. Затем вы можете загрузить, когда это необходимо. –

ответ

0

Вы найдете пример компонента Symfony DI в http://php.budgegeria.de/flzsbalQV2, где используется отложенная загрузка.

Класс Bar имеет зависимость от Foo, который настроен как служба. Когда Foo instanciated, эхо будет работать. Как вы можете видеть, экземпляр будет создан, когда произойдет первый доступ к методу зависимостей Foo.

Для этого вам нужен пакет композитора ocramius/proxy-manager. Также возможно реализовать это ленивое поведение в других контейнерах DI.

1

Влияет ли инъекция зависимостей от ленивых зависимостей?

Нет, это не делает ленивую загрузку невозможной. Я бы даже возражал против, и я бы даже сказал, что динамические языки (например, PHP и Ruby) делают это еще проще, чем статически типизированные языки (например, Java и C#).

Так как ваша программа для компонентов с абстракциями легко внедряет реализацию для того же контракта, который обертывает реальную реализацию, которая может быть ленивой. Обертка действует как прокси-сервер, и это позволяет потребителю не обращать внимания на то, что любая ленивая загрузка даже продолжается. Это повышает ремонтопригодность.

Мой PHP довольно ржавый, поэтому следующий пример может быть не «компиляцией» (любой PHP-разработчик, пожалуйста, не стесняйтесь обновлять этот пример), но следующее показывает идею.

Здесь мы видим некоторый класс, который реализует некоторую бизнес-логику (ShipOrderHandler) и зависит от регистратора зависимости:

class ShipOrderHandler { 
    private $logger; 

    function __construct($logger) { 
     $this->logger = $logger; 
    } 

    function Handle($command) { 
     $this->logger->Log("shipping order " + $command->OrderId); 
    } 
} 

class DatabaseLogger { 

    function Log($message) { 
     // log the message 
    } 
} 

Это, как мы могли бы построить граф объектов для ShipOrderHandler:

$handler = new ShipOrderHandler(new DatabaseLogger()); 

Не представляйте себе наш DatabaseLogger, чтобы быть действительно тяжелым для инициализации. Используя мощность DI и динамических языков, мы можем просто добавить реализацию прокси для нашего реферата журнала; назовем это LazyLogger. Наш новый LazyLogger может выглядеть следующим образом:

class LazyLogger { 
    private $loggerFactory; 
    private $logger; 
    function __construct($loggerFactory) { 
     $this->loggerFactory = $loggerFactory; 
    } 

    function Log($message) { 
     if (!$this->logger) $logger = $loggerFactory(); 
     $this->logger.Log($message); 
    } 
} 

Теперь мы можем применить это LazyLogger к нашему Composition Root сделать DatabaseLogger создан лениво, без внесения каких-либо изменений в наших программных компонентов

$handler = new ShipOrderHandler(
    new LazyLogger(function() { return new DatabaseLogger() }); 

Здесь мы обернуть создание DatabaseLogger в анонимной функции, которая вводится в LazyLogger. Когда в первый раз вызывается метод LazyLoggerLog, вызывается фабричный метод, создается DatabaseLogger, и LazyLogger будет кэшировать этот экземпляр и будет использовать его до тех пор, пока он не выйдет из области действия.

Как вы можете видеть, ни в коем случае не означает, что зависимость от инъекции фактически ограничивает использование ленивой загрузки; наоборот: он позволяет ленивую загрузку без необходимости внесения радикальных изменений во всем приложении.

Это мощность DI.