@harrasteblogi JUURI NYT
--:--

Tilaa uutiskirje

Saat tuoreimmat 10 uusinta artikkelia kerran viikossa sähköpostiisi.

Tilaa uutiskirje

Kuinka käyttää dependency injection containeria WordPress-pluginissaDependency Injection Container eli DI-container tekee WordPress-pluginista huomattavasti modulaarisemman, testattavamman ja helpommin ylläpidettävän. Vaikka WordPress perustuu pitkälti globaaleihin funktioihin ja hookeihin, moderni plugin-kehitys hyötyy selkeästä service-rakenteesta ja dependency injection -mallista.

Tiivistelmä
Mikä DI-container tekee

Container hallitsee servicejä:...

Miksi DI-container kannattaa WordPressissä

WordPressissä ongelmat usein johtuvat:...

2. Service registration

$container->set('mailer', function() { return new Mailer(); }); 3. Dependency resolution $container->set('order_service', function($c) { return new OrderService( $c->get('mailer') ); }); 4. Plugin bootstrap Tyypillinen rakenne:...

3. Dependency resolution

$container->set('order_service', function($c) { return new OrderService( $c->get('mailer') ); }); 4. Plugin bootstrap Tyypillinen rakenne:...

4. Plugin bootstrap

Tyypillinen rakenne:...

6. Hook service containerissa

$container->set('user_hooks', function() { return new UserHooks(); }); Bootissa:...

7. Lazy loading

Container voi luoda servicet vasta tarvittaessa....

8. Singleton vs shared services

Moni container tukee shared servicejä:...

10. Testattavuus

DI tekee mockauksen helpoksi:...

11. Autowiring

Modernit containerit tukevat reflection-pohjaista autowiringia....

12. WordPress + PHP-DI

Suosittu ratkaisu:...

13. Service provider -malli

Hyvä rakenne isoihin plugineihin:...

15. Event-driven plugin architecture

DI-container toimii hyvin yhdessä event-driven mallin kanssa:...

16. Anti-patternit

Huonoja käytäntöjä:...

17. Performance huomioitavaa

Liian raskas container voi hidastaa bootstrapia....

18. Paras plugin-rakenne

Moderni WordPress-plugin:...

Yhteenveto

Dependency injection container tuo WordPress-plugin-kehitykseen modernin sovellusarkkitehtuurin. Sen avulla pluginit voidaan rakentaa modulaarisesti, testattavasti ja ilman globaalia spagettia....

Ilman DI-containeria pluginit muuttuvat helposti:

  • vaikeasti testattaviksi
  • tiukasti kytketyiksi
  • sekaviksi singleton-rakenteiksi
  • hankaliksi laajentaa

Hyvin rakennettu container taas mahdollistaa:

  • service registrationin
  • automaattisen dependency resolutionin
  • lazy loadingin
  • paremman arkkitehtuurin

Mitä dependency injection tarkoittaa

Huono tapa:

class OrderService {

    public function create() {

        $mailer = new Mailer();
    }
}

Ongelma:

  • luokka luo omat riippuvuutensa
  • vaikea testata
  • vaikea vaihtaa implementaatiota

Parempi:

class OrderService {

    public function __construct(Mailer $mailer) {

        $this->mailer = $mailer;
    }
}

Nyt riippuvuus injektoidaan ulkopuolelta.

Mikä DI-container tekee

Container hallitsee servicejä:

Container
├── Mailer
├── Logger
├── API Client
└── OrderService

Container:

  • luo objektit
  • ratkaisee riippuvuudet
  • hallitsee lifecycleä

Miksi DI-container kannattaa WordPressissä

WordPressissä ongelmat usein johtuvat:

  • globaalista tilasta
  • singleton-spagetista
  • hookien hajautumisesta

DI-container auttaa rakentamaan:

  • modulaarisen pluginin
  • service-pohjaisen arkkitehtuurin
  • testattavan koodin

1. Yksinkertainen custom container

Perusmalli:

class Container {

    protected $services = [];

    public function set($key, $resolver) {

        $this->services[$key] = $resolver;
    }

    public function get($key) {

        return $this->services[$key]($this);
    }
}

2. Service registration

$container->set('mailer', function() {

    return new Mailer();
});

3. Dependency resolution

$container->set('order_service', function($c) {

    return new OrderService(
        $c->get('mailer')
    );
});

4. Plugin bootstrap

Tyypillinen rakenne:

plugin.php
src/
services/
container/

Bootstrap:

$container = new Container();

require 'services.php';

$app = $container->get('app');
$app->boot();

5. Hook registration serviceinä

Huono:

add_action(...);
add_action(...);
add_action(...);

ripoteltuna kaikkialle.

Parempi:

class UserHooks {

    public function register() {

        add_action('init', [$this, 'boot']);
    }
}

6. Hook service containerissa

$container->set('user_hooks', function() {

    return new UserHooks();
});

Bootissa:

$container->get('user_hooks')->register();

7. Lazy loading

Container voi luoda servicet vasta tarvittaessa.

Hyöty:

  • pienempi memory footprint
  • nopeampi bootstrap

8. Singleton vs shared services

Moni container tukee shared servicejä:

$container->singleton('logger', function() {

    return new Logger();
});

Tällöin sama instanssi palautetaan aina.

9. Interface-pohjainen arkkitehtuuri

Paras käytäntö:

interface MailerInterface {}

Implementaatio:

class SMTPMailer implements MailerInterface {}

Container:

$container->set(
    MailerInterface::class,
    fn() => new SMTPMailer()
);

10. Testattavuus

DI tekee mockauksen helpoksi:

$mailer = $this->createMock(MailerInterface::class);

Ilman dependency injectionia tämä on vaikeaa.

11. Autowiring

Modernit containerit tukevat reflection-pohjaista autowiringia.

Esimerkkejä:

  • PHP-DI
  • Symfony Container
  • Laravel Container
$container->get(OrderService::class);

Container ratkaisee dependencyt automaattisesti.

12. WordPress + PHP-DI

Suosittu ratkaisu:

composer require php-di/php-di

Käyttö:

$container = new \DI\Container();

13. Service provider -malli

Hyvä rakenne isoihin plugineihin:

AuthServiceProvider
APIServiceProvider
AdminServiceProvider

Jokainen rekisteröi omat servicensä.

14. Configuration injection

Älä käytä:

get_option() kaikkialla

Parempi:

new APIClient($config);

15. Event-driven plugin architecture

DI-container toimii hyvin yhdessä event-driven mallin kanssa:

Event Dispatcher
↓
Subscribers
↓
Services

16. Anti-patternit

Huonoja käytäntöjä:

  • globaali $container kaikkialla
  • service locator abuse
  • liian monimutkainen container pienessä pluginissa
  • singleton-spagetti
  • WordPress-funktiot business logicassa

17. Performance huomioitavaa

Liian raskas container voi hidastaa bootstrapia.

Optimoi:

  • lazy loading
  • cached definitions
  • ei reflectionia productionissa tarvittaessa

18. Paras plugin-rakenne

Moderni WordPress-plugin:

src/
├── Application
├── Services
├── Infrastructure
├── Hooks
├── API
├── Domain
└── Container

19. Milloin DI-container kannattaa

Hyvä idea kun:

  • plugin kasvaa suureksi
  • useita servicejä
  • paljon integraatioita
  • testattavuus tärkeää
  • useita kehittäjiä

Ei välttämättä tarpeen:

  • pienissä utility plugineissa

Yhteenveto

Dependency injection container tuo WordPress-plugin-kehitykseen modernin sovellusarkkitehtuurin. Sen avulla pluginit voidaan rakentaa modulaarisesti, testattavasti ja ilman globaalia spagettia.

Kun servicet, hookit ja integraatiot erotetaan selkeiksi dependencyiksi, WordPress-pluginista tulee huomattavasti helpompi ylläpitää ja skaalata pitkällä aikavälillä.

🍪