Dependency injection in der OXID Projektentwicklung

Dependency injection in der OXID Projektentwicklung

Ein Überblick über die features, die OXID Projektentwickler nutzen können, die durch den integrierten Symfony DI Container bereitgestellt werden.

A19a5f306c2ebd6b1bdc378aed928533?s=128

Michael Koltan

November 12, 2019
Tweet

Transcript

  1. DEPENDENCY DEPENDENCY INJECTION INJECTION IN DER OXID IN DER OXID

    PROJEKTENTWICKLUNG PROJEKTENTWICKLUNG Michael Koltan So ware Architect OXID eSales
  2. DAS PRINZIP: DEPENDENCY DAS PRINZIP: DEPENDENCY INVERSION INVERSION vs. class

    foo { public function __construct() { $this->bar = new Bar(); } } class foo { public function __construct(BarInterface $bar) { $this->bar = $bar; } }
  3. DER DI CONTAINER: SYMFONY DI DER DI CONTAINER: SYMFONY DI

    services.yaml services: _defaults: autowire: true public: false OxidEsales\EshopCommunity\Internal\FooInterface: class: OxidEsales\EshopCommunity\Internal\Foo public: true OxidEsales\EshopCommunity\Internal\BarInterface: class: OxidEsales\EshopCommunity\Internal\Bar
  4. DER DER INTERNAL INTERNAL NAMESPACE NAMESPACE Internal/ ├── Container ├──

    Domain ├── Framework ├── README.md ├── services.yaml └── Transition
  5. CONTAINER CONTAINER $container = ContainerFactory::getInstance()->getContainer(); $foo = $container->get(FooInterface::class);

  6. DIE CACHE-DATEI FÜR DEN DIE CACHE-DATEI FÜR DEN CONTAINER CONTAINER

    rm source/tmp/container_cache.php
  7. DOMAIN DOMAIN Data objects vs. services

  8. DATA OBJECTS DATA OBJECTS Repräsentieren Objekte der realen Welt: Kunde,

    Einkaufswagen, Rechnung, ... Haben verschiedene Instanzen: Kunde Müller, Kunde Maier, Kunde Schulz, ... Instanzen sind zustandsbeha et: $customer1->lastName = 'Müller'; $customer2->lastName = 'Maier';
  9. SERVICES SERVICES Repräsentieren Aktionen: speichere Kundendaten, prüfe Rechte, berechne Preis,

    ... Singletons - es gibt nur eine Instanz: CustomerDao, PermissionService, PriceCalculationFacade, ... Die Instanz ist zustandslos (naja, fast)
  10. WEITERE UNTERSCHIEDE WEITERE UNTERSCHIEDE Data objects Services Implementiert kein Interface

    Muss ein Interface implementieren Hat keine äußeren Abhängigkeiten Kann von anderen services und data objects abhängen Instantiierung durch new oder einen factory service Instantiierung durch den DI container
  11. ZUGRIFFSRECHTE ZUGRIFFSRECHTE Facades Bridges Data objects Utilities Data access objects

    Domain services
  12. FRAMEWORK FRAMEWORK Framework/ ├── Config ├── Console ├── Dao ├──

    Database ├── DIContainer ├── Event ├── FileSystem ├── Form ├── FormConfiguration ├── Logger ├── Module ├── services.yaml ├── Smarty ├── Storage ├── Templating └── Theme
  13. TRANSITION TRANSITION Transition/ ├── Adapter ├── ShopEvents └── Utility

  14. MODULE MODULE

  15. EINFACHER EINSTIEGSPUNKT: EINFACHER EINSTIEGSPUNKT: class GraphQL extends WidgetController { public

    function init(): void { ContainerFactory::getInstance() ->getContainer() ->get(GraphQLQueryHandlerInterface::class) ->executeGraphQLQuery(); } }
  16. EIGENE EIGENE SERVICES.YAML SERVICES.YAML DATEI: DATEI: services: _defaults: public: false

    autowire: true OxidEsales\GraphQL\Framework\GraphQLQueryHandlerInterface: class: OxidEsales\GraphQL\Framework\GraphQLQueryHandler public: true OxidEsales\GraphQL\Framework\RequestReaderInterface: class: OxidEsales\GraphQL\Framework\RequestReader ...
  17. WIE KOMMEN DIE SERVICES IN DEN WIE KOMMEN DIE SERVICES

    IN DEN CONTAINER? CONTAINER? var/generated/generated_services.yaml imports: - resource: /shop/source/modules/oe/graphql-base/services.yaml
  18. DAS VAR VERZEICHNIS DAS VAR VERZEICHNIS var/ ├── configuration │

    └── shops │ └── 1.yaml └── generated └── generated_services.yaml
  19. VERWENDUNG VON SERVICES AUS DEM VERWENDUNG VON SERVICES AUS DEM

    CORE CORE class FooDao { private $queryBuilderFactory; public function __construct(QueryBuilderFactoryInterface $fac) { $this->queryBuilderFactory = $fac; } public function getFooById(int $fooId)): Foo { $queryBuilder = $this->queryBuilderFactory->create(); $queryBuilder->select('*')->from('foo') ->where('id = :id')->setParameters(['id' => $fooId]); ... // execute query and build object } }
  20. EIN PAAR WORTE ZUR BACKWARD EIN PAAR WORTE ZUR BACKWARD

    COMPATIBILITY COMPATIBILITY Patch releases sind immer backward compatible Minor und major releases: Keine bc für Implementierungen! Bc nur für Interfaces die mit @stable annotiert sind!
  21. BESTEHENDE FUNKTIONALITÄT ERWEITERN BESTEHENDE FUNKTIONALITÄT ERWEITERN (NEW STYLE) (NEW STYLE)

    class FooEventSubscriber implements EventSubscriberInterface { public function handleFooEvent(FooEvent $event) { $foo = $event->getFoo(); ... // Do something with foo return $event; } public static function getSubscribedEvents() { return [FooEvent::NAME => 'handleFooEvent']; } }
  22. IN DER IN DER SERVICES.YAML SERVICES.YAML: : OxidEsales\FooEventSubscriber: class: OxidEsales\FooEventSubscriber

    tags: ['kernel.event_subscriber']
  23. OXID COMPONENTS OXID COMPONENTS Just a composer package of the

    type oxideshop-component
  24. SHOP AWARE EVENTS SHOP AWARE EVENTS class FooEventSubscriber implements ShopAwareEventSubsciber

    { public function handleFooEvent(FooEvent $event) { $foo = $event->getFoo(); ... // Do something with foo return $event; } public static function getSubscribedEvents() { return [FooEvent::NAME => 'handleFooEvent']; } }
  25. GENERATED_SERVICES.YAML GENERATED_SERVICES.YAML MyProject\FooEventSubscriber: class: MyProject\FooEventSubscriber tags: [kernel.event_subscriber] calls: [{ method:

    setActiveShops, arguments: [[1]] }, { method: setContext, arguments: ['@...\ContextInterface'] }]
  26. COMMAND COMMAND-KLASSEN FÜR DIE SYMFONY -KLASSEN FÜR DIE SYMFONY CONSOLE

    CONSOLE Basisklasse AbstractShopAwareCommand
  27. WAS TUN, WENN ES KEINEN EVENT WAS TUN, WENN ES

    KEINEN EVENT GIBT? GIBT? Mail an productmanagement@oxid-esales.com Eigene Implementierung schreiben, entweder in einem Modul oder eine Komponente Service überschreiben in var/configuration/configurable_services.yaml
  28. NOCH EINMAL DAS NOCH EINMAL DAS VAR VAR-VERZEICHNIS -VERZEICHNIS var

    ├── configuration │ ├── configurable_services.yaml │ └── shops │ └── 1.yaml └── generated └── generated_services.yaml
  29. ZUSAMMENFASSUNG ZUSAMMENFASSUNG Internal namespace mit Schichtenarchitektur Services werden instantiiert durch

    Symfony DI container Container kann auch in Modulen verwendet werden (services.yaml) Funktionalitätserweiterung durch events Neue Erweiterungsmöglichkeit durch OXID Komponenten Eventsubscriber / console commands können shop aware sein System services können in der configurable_services.yaml überschrieben werden