php dependency-injection zend-framework2 zend-framework3

php - ZF2 obsoleto: ServiceManagerAwareInterface



dependency-injection zend-framework2 (1)

Hoy actualicé mi proyecto y recibí esta advertencia:

Obsoleto: ServiceManagerAwareInterface está en desuso y se eliminará en la versión 3.0, junto con el ServiceManagerAwareInitializer. Actualice su clase X para eliminar la implementación y comience a inyectar sus dependencias a través de fábrica.

Tengo algunas clases Base principales que implementan ServiceManagerAwareInterface y múltiples clases que amplían estas clases base.

Entonces, ¿es una buena práctica crear clases de fábrica adicionales para cada una de estas clases? o ¿es mejor usar 1 AbstractFactory para cada módulo e iniciar las clases allí?

¿Dosis usando el rendimiento de impacto de AbstractFactory?

¿Cuál es la mejor práctica para inyectar una única (o 2) dependencia compartida en muchas clases?

ACTUALIZACIÓN: Incluso aunque acepté la respuesta de @ AlexP, tengo algunas preocupaciones sobre la provisión de dependencias throw constructor. Imagine este escenario: Tengo un controlador con algunas acciones, por ejemplo, decir que ActionA necesita ServiceZ y ActionB necesita ServiceY y ServiceX, y ServiceX también depende de ServiceM y ServiceN. Ahora, cada vez que llamo ActionA mi controlador se inicia con todos estos servicios, pero ActionA solo necesita 1 servicio donde mi controlador está cargado con 5 servicios ... ¿es esta una buena práctica? ¿Es esta la manera correcta de hacerlo? ¿No tendría esto un mal rendimiento, ya que en cada solicitud se están iniciando servicios que no utilizaremos en absoluto durante esa solicitud?

En este momento, estoy permitiendo que cada servicio / controlador se haga cargo de sus propias necesidades y cargue los servicios cuando los necesite.

De esta forma no tendré que iniciar múltiples servicios que no usaré y no necesito saber las dependencias de los servicios para usarlos. Sé que esto no se acepta como la mejor práctica, pero el código está limpio y prefiero sacrificar "Mejores prácticas" para tener un mejor rendimiento.

Apreciar la opinión de cualquier persona sobre esto.


Una fábrica por servicio es normalmente un objetivo ideal; sin embargo, hay muchos casos en los que tienes clases similares que tienen dependencias similares y crear ese número de fábricas para cada una sería innecesario y difícil de mantener.

Una fábrica abstracta resuelve el problema de las fábricas múltiples haciendo coincidir cada servicio que puede crear por nombre y luego devuelve una nueva instancia usando alguna configuración personalizada.

Esto introduce algunos problemas.

  • Las llamadas a $serviceManager->get() o $serviceManager->has() requerirán que la fábrica abstracta compruebe que puede crear el servicio utilizando su método canCreateServiceWithName() ; con múltiples fábricas abstractas esto podría agregar una sobrecarga de rendimiento considerable.

  • La fábrica abstracta no tiene concepto de un ''alias'' de servicio; funcionalidad ofrecida por el administrador del servicio. La implementación requiere que coincida con el $requestedName del servicio. Este es un problema si tiene llamadas para servicios utilizando tanto el nombre completo del servicio como un alias.

  • Las fábricas abstractas están estrechamente relacionadas con el marco ZF2.

La hoja de ruta para el marco está muy enfocada en abordar estos problemas, ZF3 todavía ofrece las fábricas abstractas, sin embargo, también introduce algunas mejoras en el diseño de fábrica para fomentar la reutilización, que ya puede aprovechar.

Tenga en cuenta que la fábrica ahora acepta un argumento adicional requerido, $requestedName ; v2 ya pasó este argumento, pero no se especificó en la interfaz en sí. Debido a que las fábricas ahora pueden esperar recibir el nombre del servicio, pueden reutilizarse para múltiples servicios, reemplazando en gran medida las fábricas abstractas en la versión 3 .

Así que ya podemos usar fábricas estándar varias veces para servicios similares (en ZF2).

Un ejemplo muy simple sobre cómo crear un servicio similar con una fábrica.

''service_manager'' => [ ''factories'' => [ ''My/Service/Foo'' => ''My/Factory/SharedFactory'', ''My/Service/Bar'' => ''My/Factory/SharedFactory'', ''My/Service/Baz'' => ''My/Factory/SharedFactory'', ], ], namespace My/Factory; class SharedFactory { public function __invoke($serviceLocator, $name, $requestedName) { if (! class_exists($requestedName)) { throw new ServiceNotCreatedException("$requestedName could not be found!"); } return new $requestedName( $serviceLocator->get(''SomeDependacy1''), $serviceLocator->get(''SomeDependacy2'') ); } }

Podría extender esto fácilmente para cargar la configuración del servicio personalizado usando el argumento $requestedName para agregar aún mayor flexibilidad.