0

Context: From a Laravel service container, we can easily bind abstracts to concrete implementations, and variables to scalar types, using the following, respectively:

// Abstracts to concrete implementations
$this->app->when(Foo::class)->needs(Bar::class)->give(new FooBar);

// Variables to scalars
$this->app->when(Foo::class)->needs('$bar')->give('fooBar');

Problem: I want to bind concrete classes to specific constructor variables (so a combination of the two), but it won't let me:

$this->app->when(Foo::class)->needs('$bar')->give(new FooBar);

That just returns:

Illuminate \ Contracts \ Container \ BindingResolutionException
Target [FooBar] is not instantiable while building [Foo].

At least, when the constructor variable is typed to FooBar, not when it's mixed. But setting it to mixed is not acceptable to me.

// Doesn't work:
class Foo
{
    public function __construct(
        protected FooBar $foo,
    )
    {
    }
}

// Works:
class Foo
{
    public function __construct(
        protected mixed $foo,
    )
    {
    }
}

To be clear, the new FooBar I want to inject is dynamically resolved, so I can't just new Foo(new FooBar), and I need this to work for multiple constructor arguments of the same type (which are each bound to different implementations), along with other dependencies:

class Foo
{
    public function __construct(
        protected FooBar $primaryFoo, // e.g. new Foobar('green')
        protected FooBar $secondaryFoo, // e.g. new FooBar('blue')
        // ... Other dependencies
    )
    {
    }
}

I can't figure out what syntax to use and I can't find anything that points to this in the docs or in the foundation code. It doesn't seem like I can achieve this with bind() as that is meant for use with abstracts. Any ideas?

exastris
  • 23
  • 5
  • Why not to bind like $this->app->bind(Foo::class, fn() => new Foo(new Bar, new Bar)) – Maksim Aug 16 '23 at 21:16
  • @Maksim Because there are other dependencies to resolve through the container. I can't really combine that in bind(), right? Returning `$this->app->make()` from the closure results in an infinite loop? – exastris Aug 17 '23 at 06:26

0 Answers0