Как внедрить массив реализаций в конструктор в PHP - PullRequest
2 голосов
/ 03 февраля 2020

Как внедрить массив реализаций в класс через конструктор. Я делюсь ссылкой, которая c#. Я хочу добиться того же в php.

Как добиться того же в php.

public interface IFoo { }
public class FooA : IFoo {}
public class FooB : IFoo {}

public class Bar
{
    //array injected will contain [ FooA, FooB ] 
    public Bar(IFoo[] foos) { }
}

public class MyModule : NinjectModule
{
    public override void Load()
    {
        Bind<IFoo>().To<FooA>();
        Bind<IFoo>().To<FooB>();
        //etc..
    }
}

{ ссылка }

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 03 февраля 2020

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

Laravel для конфигурации используйте ServiceProvider для выполнения всех видов конфигурации: В классе \App\Providers\AppServiceProvider вы можете настроить создание вашего класса.


    public function register(): void
    {
        // to configure implementation for an interface or abstract class
        // you can only configure one implementation for interface
        $this->app->bind(\App\IFoo::class, \App\FooA::class);

        // or 'tag' several implementation for one string tag.
        $this->app->tag([\App\FooA::class, \App\FooB::class], \App\IFoo::class);

        $this->app->bind(\App\Bar::class, function(\Illuminate\Contracts\Foundation\Application $container){
            // get all tagged implementations
            $foos = $container->tagged(\App\IFoo::class);

            return new \App\Bar($foos);
        });
    }

0 голосов
/ 03 февраля 2020

Возможно, вам понадобится Tagging . Например, возможно, вы создаете агрегатор отчетов, который получает массив из множества различных реализаций интерфейса отчетов. После регистрации реализаций Отчета вы можете назначить им тег с помощью метода тегов:

$this->app->bind('App\Reports\MemoryReportInterface', 'App\Reports\MemoryReportImplementation');       
$this->app->bind('App\Reports\SpeedReportInterface', 'App\Reports\SpeedReportImplementation');  

$this->app->tag(['App\Reports\MemoryReportInterface', 'App\Reports\MemoryReportInterface'], 'reports'); 

После того, как сервисы были помечены, вы можете легко разрешить их все с помощью метода тегов:

$this->app->bind('ReportAggregator', function ($app) {
    return new ReportAggregator($app->tagged('reports'));
});

Использование

<?php 

namespace ...;

/**
 * 
 */
class ReportAggregator
{
    private $reports;

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

    public function getReports() {
        return $this->reports;
    }
    //...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...