Laravel: injecting a dependency into an extended class - php

I'm using the Sentinel bundle for Laravel.
The vendor class UserController has a constructor that injects a bunch of dependencies into it that looks like this:
<?php namespace Sentinel;
use Sentinel\Repo\User\UserInterface;
use Sentinel\Repo\Group\GroupInterface;
use Sentinel\Service\Form\Register\RegisterForm;
use Sentinel\Service\Form\User\UserForm;
use Sentinel\Service\Form\ResendActivation\ResendActivationForm;
use Sentinel\Service\Form\ForgotPassword\ForgotPasswordForm;
use Sentinel\Service\Form\ChangePassword\ChangePasswordForm;
use Sentinel\Service\Form\SuspendUser\SuspendUserForm;
use BaseController, View, Input, Event, Redirect, Session, Config;
class UserController extends BaseController {
protected $user;
protected $group;
protected $registerForm;
protected $userForm;
protected $resendActivationForm;
protected $forgotPasswordForm;
protected $changePasswordForm;
protected $suspendUserForm;
/**
* Instantiate a new UserController
*/
public function __construct(
UserInterface $user,
GroupInterface $group,
RegisterForm $registerForm,
UserForm $userForm,
ResendActivationForm $resendActivationForm,
ForgotPasswordForm $forgotPasswordForm,
ChangePasswordForm $changePasswordForm,
SuspendUserForm $suspendUserForm)
{
$this->user = $user;
$this->group = $group;
$this->registerForm = $registerForm;
$this->userForm = $userForm;
$this->resendActivationForm = $resendActivationForm;
$this->forgotPasswordForm = $forgotPasswordForm;
$this->changePasswordForm = $changePasswordForm;
$this->suspendUserForm = $suspendUserForm;
//Check CSRF token on POST
$this->beforeFilter('Sentinel\csrf', array('on' => array('post', 'put', 'delete')));
// Set up Auth Filters
$this->beforeFilter('Sentinel\auth', array('only' => array('change')));
$this->beforeFilter('Sentinel\inGroup:Admins', array('only' => array('show', 'index', 'create', 'destroy', 'suspend', 'unsuspend', 'ban', 'unban', 'edit', 'update')));
//array('except' => array('create', 'store', 'activate', 'resend', 'forgot', 'reset')));
}
// The rest of the class code...
I've created model class in my app called ExtendedUserController so that I can add functionality to the existing controller. My controller class looks like this currently:
<?php
use Sentinel\UserController;
use Sentinel\Repo\Group\SentryGroup;
class ExtendedUserController extends UserController {
// The rest of the class code...
I don't have a constructor in my class because I'm letting the parent class construct when I extend it.
I have a new model that I would like to add to my controller class. My plan was to inject the dependency in a constructor for the ExtendedUserController and then call `parent::__construct()' to allow the parent class to be extended.
I'm running into errors when loading the class and I'm still green enough to laravel and dependency injection that I'm not exactly sure how to fix it or if this is even the proper way of accomplishing the task:
<?php
use Sentinel\UserController;
use Sentinel\Repo\Group\SentryGroup;
use CustomerLinks;
class ExtendedUserController extends UserController {
protected $customerLinks;
public function __construct(CustomerLinks $customerLinksClass){
$this->customerLinks = $customerLinksClass;
parent::__construct();
}
I'm running into the error:
Argument 1 passed to Sentinel\UserController::__construct() must be an
instance of Sentinel\Repo\User\UserInterface, none given, called in
/var/www/app/controllers/ExtendedUserController.php on line 15 and
defined
If I run the parent constructor, shouldn't the parent's code automatically pass in it's dependencies as outlined in the parent class' code?
Is this not the proper way to add the dependency? Any help and explanation would be greatly appreciated.

I realize the error now and I wanted to add it in rather than deleting the question.
I found an earlier stackoverflow post on this issue when searching with different criteria.
I needed to
Add the parent class' dependencies to my extended class, pass them into my extended classes
Inject the dependencies into my extended class' constructor
Pass those injected variables into the parent::__construct() call
Here's what the working code looks like:
<?php
use Sentinel\UserController;
use Sentinel\Repo\Group\SentryGroup;
use CustomerLinks;
// Parent class' dependencies
use Sentinel\Repo\User\UserInterface;
use Sentinel\Repo\Group\GroupInterface;
use Sentinel\Service\Form\Register\RegisterForm;
use Sentinel\Service\Form\User\UserForm;
use Sentinel\Service\Form\ResendActivation\ResendActivationForm;
use Sentinel\Service\Form\ForgotPassword\ForgotPasswordForm;
use Sentinel\Service\Form\ChangePassword\ChangePasswordForm;
use Sentinel\Service\Form\SuspendUser\SuspendUserForm;
use BaseController, View, Input, Event, Redirect, Session, Config;
class ExtendedUserController extends UserController {
protected $customerLinks;
// Injecting both the parent class' dependencies and my new dependency into the constructor
public function __construct(CustomerLinks $customerLinksClass,UserInterface $user, GroupInterface $group, RegisterForm $registerForm, UserForm $userForm,ResendActivationForm $resendActivationForm,ForgotPasswordForm $forgotPasswordForm,ChangePasswordForm $changePasswordForm,
SuspendUserForm $suspendUserForm){
// passing the injected variables to the parent constructor call
parent::__construct($user, $group, $registerForm, $userForm,$resendActivationForm,$forgotPasswordForm,$changePasswordForm,$suspendUserForm);
// Adding my new injected class into the controller class
$this->customerLinks = $customerLinksClass;
}
//The rest of the class code...
It was a pretty big face-palm moment. Hopefully this will help someone out in the future.

Related

Why's my interface not instantiable even though I have what appears to be the correct files/implementation?

I'm not sure why I'm getting this error that says Illuminate\Contracts\Container\BindingResolutionException: Target [App\Dal\Interfaces\IUploadsRepository] is not instantiable while building [App\Http\Controllers\FileUploadController]. in file /var/www/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 1093 despite having (to my knowledge) everything set up correctly. The spelling and everything else is correct but I'm still not sure what the issue is.
I've tried everything under the sun to make this work but I'm not sure what I'm doing wrong.
What am I missing?
Note: I need to declare the UploadsRepository.php class as abstract because if I don't, then I get a red squiggly line underneath the class name with a warning that says:
Class must be declared abstract or implement methods 'resetScope', 'hidden', 'syncWithoutDetaching', 'update', 'paginate', 'delete', 'findWhereBetween', 'whereHas', 'withCount', 'find', 'getFieldsSearchable', 'create', 'findWhereNotIn', 'setPresenter', 'skipPresenter', 'all', '__callStatic', 'findWhere', 'visible', 'simplePaginate', 'firstOrNew', 'orderBy', 'sync', 'scopeQuery', 'findWhereIn', 'findByField', 'with', 'lists', 'firstOrCreate', 'updateOrCreate', '__call', 'pluck'
I'm not sure if this is the root of the issue but just want to provide as much info as I possibly can.
Here's FileUploadController.php:
<?php
namespace App\Http\Controllers;
use App\Dal\Interfaces\IUploadsRepository;
Use App\Dal\Repositories\UploadsRepository;
class FileUploadController extends Controller
{
protected $__uploadsRepository;
public function __construct(IUploadsRepository $uploadsRepository)
{
$this->__uploadsRepository = $uploadsRepository;
}
public function getUploads(): string
{
return $this->__uploadsRepository->getUploads();
}
}
Here's IUploadsRepository.php (interface):
<?php
namespace App\Dal\Interfaces;
use Prettus\Repository\Contracts\RepositoryInterface;
interface IUploadsRepository extends RepositoryInterface
{
public function getUploads();
}
Here's UploadsRepository.php:
<?php
namespace App\Dal\Repositories;
use App\Dal\Interfaces\IUploadsRepository;
abstract class UploadsRepository implements IUploadsRepository
{
/**
* #return string
*/
public function getUploads(): string
{
return "test";
}
}
Here's RepositoryServiceProvider.php:
<?php
namespace App\Providers;
use App\Dal\Interfaces\IUploadsRepository;
use App\Dal\Repositories\UploadsRepository;
use Illuminate\Support\ServiceProvider;
class RepositoryServiceProvider extends ServiceProvider
{
public function register() {
$this->app->bind(IUploadsRepository::class,UploadsRepository::class);
}
}
Here's config/app.php:
'providers' => [
Prettus\Repository\Providers\RepositoryServiceProvider::class,
\App\Providers\RepositoryServiceProvider::class,
]
The RepositoryInterface you are extending defines all those methods you see in the error: "'resetScope', 'hidden', 'syncWithoutDetaching', 'update'...". Your concrete implementation UploadsRepository is only implementing getUploads(). To fulfill the contract defined by the RepositoryInterface your concrete implementation needs to implement also the other methods. My recommendation would be to rather than implementing that interface, have your UploadsRepository extends from the Prettus\Repository\Eloquent\BaseRepository class which offers a default implementation for those methods. You can declare like this.
First IUploadsRepository does not need to extend RepositoryInterface, so the declaration would be:
<?php
namespace App\Dal\Interfaces;
interface IUploadsRepository
{
public function getUploads();
}
And the concrete implementation then goes like this:
<?php
namespace App\Dal\Repositories;
use App\Dal\Interfaces\IUploadsRepository;
use Prettus\Repository\Eloquent\BaseRepository
class UploadsRepository extends BaseRepository implements IUploadsRepository
{
/**
* #return string
*/
public function getUploads(): string
{
return "test";
}
}
You now have a default implementation for the missing methods and can use IUploadsRepository interface to handle the dependency injection via the RepositoryServiceProvider.

Is the new way of dependency injection in ZF2 without serviceLocator->get() way more inefficient?

Since version 2.7.0 of zend-mvc the ServiceLocatorAwareInterface is depricated, so are $this->serviceLocator->get() calls inside controllers.
Thats why some days ago I did a huge refactoring of all my modules to inject the needed services/objects through constructors using factories for mostly everything.
Sure, I understand why this is the better/cleaner way to do things, because dependendies are much more visible now. But on the other side:
This leads to a heavy overhead and much more never-used class instances, doesn't it?
Let's look to an example:
Because all my controllers having dependencies, I've created factories for all of them.
CustomerControllerFactory.php
namespace Admin\Factory\Controller;
class CustomerControllerFactory implements FactoryInterface {
public function createService(ServiceLocatorInterface $controllerManager) {
$serviceLocator = $controllerManager->getServiceLocator();
$customerService = $serviceLocator->get('Admin\Service\CustomerService');
$restSyncService = $serviceLocator->get('Admin\Service\SyncRestClientService');
return new \Admin\Controller\CustomerController($customerService, $restSyncService);
}
}
CustomerController.php
namespace Admin\Controller;
class CustomerController extends AbstractRestfulController {
public function __construct($customerService, $restSyncService) {
$this->customerService = $customerService;
$this->restSyncService = $restSyncService;
}
}
module.config.php
'controllers' => [
'factories' => [
'Admin\Controller\CustomerController' => 'Admin\Factory\Controller\CustomerControllerFactory',
]
],
'service_manager' => [
'factories' => [
'Admin\Service\SyncRestClientService' => 'Admin\Factory\SyncRestClientServiceFactory',
]
]
SyncRestClientServiceFactory.php
namespace Admin\Factory;
class SyncRestClientServiceFactory implements FactoryInterface {
public function createService(ServiceLocatorInterface $serviceLocator) {
$entityManager = $serviceLocator->get('doctrine.entitymanager.orm_default');
$x1 = $serviceLocator->get(...);
$x2 = $serviceLocator->get(...);
$x3 = $serviceLocator->get(...);
// ...
return new \Admin\Service\SyncRestClientService($entityManager, $x1, $x2, $x3, ...);
}
}
The SyncRestService is a complex service class which queries some internal server of our system. It has a lot of dependencies, and is always created if a request comes to the CustomerController. But this sync-service is only used inside the syncAction() of the CustomerController! Before I was using simply $this->serviceLocator->get('Admin\Service\SyncRestClientService') inside the syncAction() so only then it was instantiated.
In general it looks like a lot of instances are created through factories at every request, but the most dependencies are not used. Is this an issue because of my design or it is a normal side-effect behaviour of "doing dependency injection through constructors"?
In my opinion it is a normal effect of dependency injection through constructors.
I think you have now two options (not mutually exclusive) to improve how your application works:
Split your controllers, so that the dependencies are instanciated only when needed. This would certainly give rise to more classes, more factories, and so on, but your code would attain more to the single responsability principle
You could use Lazy Services, so that, even if some services are dependencies of the whole controller, they will be actually instanciated only the first time they are called (so never for the actions where they are not called!)
If you only use your SyncRestClientService inside a controller you should consider changing it from a service to a controller plugin (or make a controller plugin where you inject your SyncRestClientService).
Like that you can still get it inside your controller syncAction method very similar to like you did before. This is exactly the purpose of the ZF2 controller plugins.
First you need to create your controller plugin class (extending Zend\Mvc\Controller\Plugin\AbstractPlugin):
<?php
namespace Application\Controller\Plugin;
use Zend\Mvc\Controller\Plugin\AbstractPlugin;
class SyncPlugin extends AbstractPlugin{
protected $syncRestClientService;
public function __constuct(SyncRestClientService $syncRestClientService){
$this->syncRestClientService = $syncRestClientService
}
public function sync(){
// do your syncing using the service that was injected
}
}
Then a factory to inject your service in the class:
<?php
namespace Application\Controller\Plugin\Factory;
use Application\Controller\Plugin\SyncPlugin;
class SyncPluginFactory implements FactoryInterface
{
/**
* #param ServiceLocatorInterface $serviceController
* #return SyncPlugin
*/
public function createService(ServiceLocatorInterface $serviceController)
{
$serviceManager = $serviceController->getServiceLocator();
$syncRestClientService = $serviceManager>get('Admin\Service\SyncRestClientService');
return new SyncPlugin($syncRestClientService);
}
}
Then you need to register your plugin in your module.config.php:
<?php
return array(
//...
'controller_plugins' => array(
'factories' => array(
'SyncPlugin' => 'Application\Controller\Plugin\Factory\SyncPluginFactory',
)
),
// ...
);
Now you can use it inside your controller action like this:
protected function syncAction(){
$plugin = $this->plugin('SyncPlugin');
//now you can call your sync logic using the plugin
$plugin->sync();
}
Read more on controller plugins here in the documentation
Maybe you only need one dependency to be injected into the controller constructor (the ServiceManager instance). I don't see any cops around...
namespace Admin\Factory\Controller;
class CustomerControllerFactory implements FactoryInterface {
public function createService(ServiceLocatorInterface $controllerManager)
{
$serviceLocator = $controllerManager->getServiceLocator();
return new \Admin\Controller\CustomerController($serviceLocator);
}
}
Personally I get the action name in the controller factory to inject services on a per action basis.
Have a look at my sites controller.
namespace Admin\Controller\Service;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Admin\Controller\SitesController;
use Admin\Model\Sites as Models;
class SitesControllerFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$actionName = $serviceLocator->getServiceLocator()->get('Application')->getMvcEvent()->getRouteMatch()->getParam('action');
$controller = new SitesController();
switch ($actionName) {
case 'list':
$controller->setModel($serviceLocator->getServiceLocator()->get(Models\ListSitesModel::class));
break;
case 'view':
$controller->setModel($serviceLocator->getServiceLocator()->get(Models\ViewSiteModel::class));
break;
case 'add':
$controller->setModel($serviceLocator->getServiceLocator()->get(Models\AddSiteModel::class));
break;
case 'edit':
$controller->setModel($serviceLocator->getServiceLocator()->get(Models\EditSiteModel::class));
break;
}
return $controller;
}
}
As you can see I use $serviceLocator->getServiceLocator()->get('Application')->getMvcEvent()->getRouteMatch()->getParam('action'); to get the action name and use a switch statement to inject the dependencies when required.
I don't know if this is the best solution but it works for me.
Hope this helps.

Laravel dependancy injection for views

I'm trying to get the hang of dependancy injection and the IoC container in Laravel.
Currently I have a class full of static methods that I use in my views. E.g.
class Templatizer {
/**
* Generates a colored FontAwsome check or cross from a true/false argument
* #param boolean $bool
* #return string The HTML markup of the icon
*/
public static function boolicon($bool)
{
return $bool ? '<span class="fa fa-check text-success"></span>' : '<span class="fa fa-times text-danger"></span>';
}
}
I have composer autoload the class and in my view I can just go {{ Templatizer::boolicon($trueOrFalseValue) }}.
Clearly this is bad practice and I'd like to move away from using static methods. I presume the correct way is to inject an instance of Templatizer and use the methods something like {{ $templatizer->boolicon($v) }}`.
How would I structure this? Presumably I'd need to inject an instance of Templatizer into my controller via the constructor? e.g.
class PagesController extends BaseController {
protected $templatizer;
public function __construct(Templatizer $templatizer)
{
$this->templatizer = $templatizer;
}
}
And then for, say, the method for the index page I pass the instance to the view? e.g.
# inside PagesController
public function index()
{
return View::make('pages.index', ['templatizer' => $this->templatizer]);
}
If this is correct, where is an appropriate place to put my Templatizer class? How would I bind it to the IoC container?
First of all I don't see anything wrong with calling these methods statically. It looks like this is just a HTML helper class of your own and you should be fine.
If you decide to go with Dependency Injection the "correct" way to register your class would be using Service Providers.
Assigning it to the views the way you wrote would work but you can also get it once you need it this way:
$templatizer = App::make('Yournamespace\Templatizer');
And finally probably the best solution in your case would be building your own Facade.
Yes you should inject it via the controller constructor, the files can live anywhere you like as long as they are autoloaded in.
I like to create a folder in the root directory called src so that my composer.json file looks like:
"autoload": {
"classmap": [
....
],
"psr-4": {
"Foo\\": "src/"
}
}
Then you can have src/Templatizer.php which would look like:
<?php namespace Foo;
class Templatizer {
}
Now you just need a service provider to bind your instance of Templatizer (this basically makes Laravel aware of your class and allows you to inject it into your controllers) in src/FooServiceProvider.php
<?php namespace Foo;
use Illuminate\Support\ServiceProvider;
class FooServiceProvider extends ServiceProvider {
/**
* Indicates if loading of the provider is deferred
*
* #var boolean
*/
protected $defer = false;
/**
* Register the service provider
*/
public function register() {
$this->app->bind('Foo\Templatizer', function($app) {
return new Templatizer();
});
}
}
Don't forget to add Foo\FooServiceProvider to the providers array in app config and you should be all set to do...
public function __construct(Foo\Templatizer $templatizer) {
You are also create instance on BaseController.
class BaseController extends Controller {
/**
* Setup the layout used by the controller.
*
* #return void
*/
var $templatizer;
protected function setupLayout()
{
if ( ! is_null($this->layout))
{
$this->layout = View::make($this->layout);
$templatizer = new \Templatizer();
View::share('templatizer', $templatizer);
}
}
}
use this $templatizer instance in a all view.
something like {{ $templatizer->boolicon($v) }}`.

Zend framework 2 translator in model

How to get translator in model?
Inside view we can get translator using this code
$this->translate('Text')
Inside controller we can get translator using this code
$translator=$this->getServiceLocator()->get('translator');
$translator->translate("Text") ;
But how to get translator in model?
I'd tried so many ways to get service locator in models
2 of those
1)Using MVC events
$e=new MvcEvent();
$sm=$e->getApplication()->getServiceManager();
$this->translator = $sm->get('translator');
if i pring $sm it is showing null. but it works fine in Model.php onBootstrap
2)Created one model which implements ServiceLocatorAwareInterface
SomeModel.php
<?php
namespace Web\Model;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class SomeModel implements ServiceLocatorAwareInterface
{
protected $services;
public function setServiceLocator(ServiceLocatorInterface $locator)
{
$this->services = $locator;
}
public function getServiceLocator()
{
return $this->services;
}
}
and used that inside my model
$sl = new SomeModel();
$sm=$sl->getServiceManager();
var_dump($sm); exit;
$this->translator = $sm->get('translator');
this is also printing null.
If you don't need the servicemanager instance in your model, simply inject translator instance to it.
For example:
// Your model's constructor
class MyModel {
// Use the trait if your php version >= 5.4.0
use \Zend\I18n\Translator\TranslatorAwareTrait;
public function __construct( $translator )
{
$this->setTranslator( $translator );
}
public function modelMethodWhichNeedsToUseTranslator()
{
// ...
$text = $this->getTranslator()->translate('lorem ipsum');
// ...
}
}
When you creating your model first time on service or controller level
class someClass implements ServiceLocatorAwareInterface {
public function theMethodWhichCreatesYourModelInstance()
{
// ...
$sm = $this->getServiceLocator();
$model = new \Namespace\MyModel( $sm->get('translator') )
// ...
}
}
If you need to instantiate your model (new MyModel();) on multiple methods/classes, consider to writing a factory for it.
Here is a nice article about Dependency Injection and PHP by Ralph Schindler for more detailed comments about this approach.
For your Model class to be ServiceLocatorAware, you not only need to implement the interface, you also need to make your model a service of the service manager, and fetch the model from there.
Add your model to the service manager, since it doesn't appear to need any constructor params, it's invokable, so you can add it to the invokables array in service manager config. You can do that by using the getServiceConfig() method in your Module class...
class Module
{
public function getServiceConfig()
{
return array(
'invokables' => array(
'SomeModel' => 'Fully\Qualified\ClassName\To\SomeModel',
),
);
}
}
Then, instead of calling the new keyword to create your model instance, you fetch it from the service manager, for instance, by calling the getServiceLocator() method in a controller action...
public function fooAction()
{
$sm = $this->getServiceLocator();
$model = $sm->get('SomeModel');
}
When your model is fetched from the service manager, a service initializer will look to see if it implements the ServiceLocatorAwareInterface and automatically call setServiceLocator() if it does, passing it an instance of the service manager.

MVC, DI (dependency injection) and creating Model instance from Controller

My Dispatcher is "choosing" correct Controller; then creating Controller's instance (DependencyInjectionContainer is passed to Controller constructor); then calling some Controller's method...
class UserController extends Controller
{
public function __construct(DependencyInjectionContainer $injection) {
$this->container = $injection;
}
public function detailsAction() {
...
}
}
DependencyInjectionContainer contains DB adapter object, Config object etc.
Now let's see what detailsAction() method contains...
public function detailsAction() {
$model = new UserModel();
$model->getDetails(12345);
}
As you see I'm creating new instance of UserModel and calling getDetails methods.
Model's getDetails() method should connect to db to get information about user. To connect to DB UserModel should be able to access DB adapter.
What is the right way to pass DependencyInjectionContainer to the UserModel?
I think that this way is wrong...
public function detailsAction() {
$model = new UserModel($this->container);
$model->getDetails(12345);
}
Instead of injecting the entire DI Container into your classes, you should inject only the dependencies you need.
Your UserController requires a DB Adapter (let's call this interface IDBAdapter). In C# this might look like this:
public class UserController
{
private readonly IDBAdapter db;
public UserController(IDBAdapter db)
{
if (db == null)
{
throw new ArgumentNullException("db");
}
this.db = db;
}
public void DetailsAction()
{
var model = new UserModel(this.db);
model.GetDetails(12345);
}
}
In this case we are injectiing the dependency into the UserModel. In most cases, however, I would tend to consider it a DI smell if the UserController only takes a dependency to pass it on, so a better approach might be for the UserController to take a dependency on an Abstract Factory like this one:
public interface IUserModelFactory
{
UserModel Create();
}
In this variation, the UserController might look like this:
public class UserController
{
private readonly IUserModelFactory factory;
public UserController(IUserModelFactory factory)
{
if (factory == null)
{
throw new ArgumentNullException("factory");
}
this.factory = factory;
}
public void DetailsAction()
{
var model = this.factory.Create();
model.GetDetails(12345);
}
}
and you could define a concrete UserModelFactory that takes a dependency on IDBAdapter:
public class UserModelFactory : IUserModelFactory
{
private readonly IDBAdapter db;
public UserModelFactory(IDBAdapter db)
{
if (db == null)
{
throw new ArgumentNullException("db");
}
this.db = db;
}
public UserModel Create()
{
return new UserModel(this.db);
}
}
This gives you better separation of concerns.
If you need more than one dependency, you just inject them through the constructor. When you start to get too many, it's a sign that you are violating the Single Responsibility Principle, and it's time to refactor to Aggregate Services.
I'd use a singleton object for all config parameters :
You set it up in your bootstrap, then choose to use it directly or pass it as parameter in your objects.
The idea being to have one method all around to retrieve your config data.
You may then provide an abstract class for db manipulation which uses your config. singleton.
DependancyInjection can still be used to override your default data.
The above link in the comment (possible 'duplicate') concludes on using constructor injection : this is close to your current method.
However if I try to figure how your model works, I guess you will have many other model classes other than "userModel". Thus an abstract class using a config singleton might be a good solution : all your next model classes will just extend this abstract class, and you don't have to worry about your config.
On the other hand, your solution is good to me as long as your dependanceInjectionContainer changes often.

Categories