2

私は供給する必要がある可変非静的パラメータを持っているときに依存性注入コンテナを使用する方法?可変パラメータを必要とするクラスをDependency Injectionコンテナに配置する方法は?

私は自分のコードにしたいことはこれです:

$staff = $container->get(Staff::class); 

私が今持っていることはこれです:ユーザ名を変更することができます

$staff = new Staff("my_great_username"); 

注意と実行時に供給され、 。

私はDIコンテナにStaffを入れることができません。そこには可変パラメータを指定する方法がないためです。

私の問題は、私は工場出荷ベースのコンテナ、すなわちZend\ServiceManager\ServiceManager .Thisを使用しています...

である私は、インスタンスの詳細を隠すために使用する工場です:私は設定

class StaffFactory 
{ 
    function __invoke(ContainerInterface $container): Staff 
    { 
     /* 
     * I do not seem to know how to get my username here 
     * nor if it is the place to do so here 
     */ 
     $staff = new Staff(????????); 
     return $staff; 
    } 
} 

方法

'factories' => [ 
    Staff::class => StaffFactory::class 
] 

注:パラメータが「変数」であっても、私はが欲しいです。は不変です。つまり、いったん作成されると、それはそのままです。だから私は特にそうでないときに、クラスが変更可能であることを暗示するので、ユーザ名のためにsetterメソッドを作ることは望ましくありません。

あなたはどう思いますか?

+0

これはあなたにも悩まされている場合、この質問をアップしてくださいxD – Dennis

+0

私は混乱しています - なぜIOCコンテナをサービスロケータとして使用していますか?特にコンクリートクラスでは、 ' – Steve

+0

どこにサービスロケータとしてのIoCの使用がありますか?私が理解しているように、自分のクラスに '$ container'を挿入すると、サービスロケータになります。ここで、必要なものを引き出すことができます。'ServiceManager'は工場ベースのIoCであり、' $ container'をブートストラップの一部として使う限り、それはIoCのままです。 「$ container」をFactoryに注入することは、IoCの受け入れられた使用事例であり、その注入はその工場に限定されたままであり、自分のクラスに流出せず、それによりサービスロケータのパターンが回避される。 – Dennis

答えて

1

私の問題は、私のStaffクラスのコンストラクタに渡された可変パラメータがあることでした。

溶液は、コンストラクタに可変パラメータを有していないStaffCreatorクラスを作成し、可変パラメータを受け取るStaffCreator::create方法を書き込むことです。その後、代わりにStaffを注入する代わりに、Staffが必要なクラスにStaffCreatorを注入し、それを使用してStaffインスタンスを作成します。信用と

すなわち

//Inject this wherever you need Staff 
$staffCreator = $container->get(StaffCreator::class); 

//use it: 
$staff = $this->staffCreator->create("my_great_username"); 

//code: 
class StaffCreatorFactory 
{  
    function __invoke(ContainerInterface $container) 
    { 
     return new StaffCreator(); 
    } 
} 

class StaffCreator 
{ 
    function __construct() 
    { 
     //additional creation parameters possible here 
    } 

    function create(string $username): Staff 
    { 
     return new Staff($username); 
    } 
} 

Steve

注:あなたはDIを再利用可能にするために作成し、上記のコードにInterfacesを追加することができます。すなわちStaffCreatorInterface,StaffInterface。私の場合は、インターフェイスを再利用するための強力なユースケースはありません(まだ)。

関連する問題