So I have a controller in my Yii2 powered CMS, named PageController, which makes use of a custom data provider for its actionIndex(), named PageControllerIndexDataProvider. I want this to become a property of the PageController, but want to follow best practices in regards to dependency injection.
Right now, things are working fine as follows:
class PageController extends Controller
{
public $indexDataProvider;
public function init()
{
parent::init();
$this->indexDataProvider = new PageControllerIndexDataProvider();
}
...
public function actionIndex()
{
return $this->render(
'index',
[
'createPageUrl' => Yii::$app->urlManager->createUrl('page/create'),
'pagesDataProvider' => $this->indexDataProvider
]
);
}
...
}
…but I want to remove that "new PageControllerIndexDataProvider()" and replace it with some dependency injection pattern.
In any event, I decided I would try and assign the PageController::$indexDataProvider property with Yii’s service locator. I dont want to clog up my entry script with a bunch of Yii::$app->locator->set(…) (or container->set()) calls, as I might have a lot of these sort of DataProviders, and I certainly dont need them all for each request.
So then I tried to add them to my main config file, in the components section, as such:
array(
'components' => [
'dataProviders' =>[
'PageIndex' => 'backend\dataproviders\PageControllerIndexDataProvider',
...andAnother
...andAnother...
],
]
);
and naturally discovered that all components must have a ‘class’ parameter when set this way - i.e. - I cant have an array of components[dataProviders][someDataProvider] like I used to do with Yii 1. It seems kind of clunky to have to set so many components for the service locator this way, especially if you plan to have a big application with lots of DataProviders and want to follow dependency injection patterns.
I think I may not be approaching this correctly, as it seems like its difficult to implement a DataProvider without violating the dependency injection/container pattern - how do I make use of a DataProvider inside a controller action or model without instantiating a "new MyDataProvider()" ? Note: it seems the section on implementing your own custom DataProviders is TBD still, so I may be missing something here.
Basically, Im looking for a way to dynamically allocate service locator setting of custom DataProviders so that they can be made available inside a Controller::init() method. Is there a way I can do this, without just having to manually add each DataProvider I have to the entry script or config?