Laravel - pass parameters through app->bind to model's constructor
Asked Answered
A

3

9

Well, code describes it all. I've an Entity Service Provider, which pass an instance of Playlist Model, which supposed to get an array as it's first constructor parameter. How to pass that parameter through app->bind? Knowing that EntityServiceProvider is automagically injected when referenced in the controller.

        // Current Code
        /**
         * Playlist Entity
         *
         * @return Playlist\PlaylistEntity
         */
        $this->app->bind('Playlist\PlaylistEntity', function($app)
        {
            return new PlaylistEntity($app->make('Playlist\PlaylistRepositoryInterface'));
        });



        // Should be something like this:
        /**
         * Playlist Entity
         *
         * @return Playlist\PlaylistEntity
         */
        $this->app->bind('Playlist\PlaylistEntity', function($app)
        {
            return new PlaylistEntity($app->make('Playlist\PlaylistRepositoryInterface', $parameters));
        });

Similar case: Laravel 4: Passing data from make to the service provider

Ascanius answered 13/2, 2014 at 6:20 Comment(2)
The answer in the 'similar case' post is correct as far as I can tell. $this->app->bind('Whatever', function ($app, $params) { var_dump($params); }); followed by App::make('Whatever', [1, 2, 3]); var_dumps the [1, 2, 3] array for me.Pinnatifid
how to do this with Facades not make ? is it possibleZina
A
9

Alex Russell's comment works for me as well.

The answer in the 'similar case' post is correct as far as I can tell. $this->app->bind('Whatever', function ($app, $params) { var_dump($params); }); followed by App::make('Whatever', [1, 2, 3]); var_dumps the [1, 2, 3] array for me.

Apograph answered 5/4, 2016 at 3:21 Comment(1)
Confirmed. Works for me as well, even in the last version (5.3)Practicable
H
4

In Laravel 5.4 the ability to pass config parameters when resolving from the container using App::make() was removed and subsequently re-implemented as App::makeWith().

BTW I tried to make this a comment on the previous answer, but it didn't let me. Maybe due to not enough experience points?

Huntington answered 9/5, 2017 at 23:0 Comment(1)
Be careful makeWith is not the same as make, it does not allow to put another object in the app container for test cases like so app()->instance(MyClass::class, $myObject);, the mocking is broken now. Even in laravel 5.6Cisneros
M
2

Thanks @yevgeniy-afanasyev for pointing out the problems when mocking. If you need to mock these instances, you could go for Taylor Otwell's early suggestion here: https://github.com/laravel/ideas/issues/391#issuecomment-285197048

I just needed that and it worked well. Just return a closure and call it, when you ::make.

// Service Provider
$this->app->bind(MyClass::class, function ($app) {
   return function($param) : MyClass
   {
       return new MyClass($param);
   }
}

// ::make
$myInstance = App::make(MyClass::class)($myParameter);

// mock
$myMock = Mockery::mock(new MyClass($myParameter));
$this->instance(MyClass::class, function($param) use ($myMock) { return $myMock; });
Marcmarcano answered 15/5, 2019 at 15:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.