# cakePHP 5: Dependency Injection - Inject existing service into Component

**URL:** <https://discourse.cakephp.org/t/cakephp-5-dependency-injection-inject-existing-service-into-component/12721>\
**Category:** Need Help\
**Created:** [September 29, 2025, 7:03pm UTC](https://discourse.cakephp.org/t/cakephp-5-dependency-injection-inject-existing-service-into-component/12721 "2025-09-29T19:03:55Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![der-dave](https://avatars.discourse-cdn.com/v4/letter/d/e47774/32.png) [@der-dave](https://discourse.cakephp.org/u/der-dave)\
**Post date:** [September 29, 2025, 7:03pm UTC](https://discourse.cakephp.org/t/cakephp-5-dependency-injection-inject-existing-service-into-component/12721/1 "2025-09-29T19:03:55Z")

</div>

Hi there,

I an using cakePHP 5.2.7. and registred in my _Application.php_ a service:

```php
$container
    ->add(GenericProvider::class, function () {
        return new GenericProvider([
            'clientId' => 'xxx',
            'clientSecret' => 'xxx',
            'redirectUri' => 'https://account.xyz.com/oauth/callback',
            'urlAuthorize' => 'https://auth.xyz.com/authorize',
            'urlAccessToken' => 'https://auth.xyz.com/token',
            'urlResourceOwnerDetails' => 'https://auth.xyz.com/userinfo',
            'pkceMethod' => GenericProvider::PKCE_METHOD_S256,
        ]);
    });

```

Some of you may recognize this is e generic league/oauth2-client.

I also build a small Component: _OauthComponent.php_ to do some basic tasks.

Now I want to inject the _GenericProvider::class_ into the _OauthComponent.php._

In the official documentation, I found this:  
[Dependency Injection - 5.x](https://book.cakephp.org/5/en/development/dependency-injection.html#component-example)  
For me, this means I have to do it in Application::service like this way:

```php
$container->add(OauthComponent::class)
    ->addArgument(ComponentRegistry::class)
    ->addArgument(GenericProvider::class);

```

and can get the GenericProvider by constructor:

```php
class OauthComponent extends Component
{
    protected GenericProvider $provider; // OAuth2-client

    public function __construct(ComponentRegistry $registry, GenericProvider $provider, array $config = [])
    {
        parent::__construct($registry, $config);
        $this->provider = $provider;
    }

    ...
    ...
}

```

But now I get the error:

> App\Controller\Component\OauthComponent::\_\_construct(): Argument #3 ($config) must be of type array, Cake\Controller\ComponentRegistry given

and when I toggle the arguments of _[internal]in App\Controller\Component\OauthComponent-\>\_\_construct I can see the following:_

> object(Cake\Controller\ComponentRegistry) {  
> }
> 
> object(League\OAuth2\Client\Provider\GenericProvider) {  
> }
> 
> object(Cake\Controller\ComponentRegistry) {  
> }
> 
> object(League\OAuth2\Client\Provider\GenericProvider) {  
> }
> 
> []

It looks like ComponentRegistry and GenericProvider are registered twice and during injecting it into the compoent, first 3 arguments are used which will mean that the empty array (last argument) is not assigned correctly.

Any ideas? Many thanks to all whe read this 🙂

---

<div class="post-metadata">

**Author:** ![dereuromark](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/dereuromark/32/37_2.png) [@dereuromark](https://discourse.cakephp.org/u/dereuromark)\
**Post date:** [September 30, 2025, 1:17am UTC](https://discourse.cakephp.org/t/cakephp-5-dependency-injection-inject-existing-service-into-component/12721/2 "2025-09-30T01:17:52Z")

</div>

Most likely a bug in component loading.

When a component is registered in the container with arguments, the ComponentRegistry::\_create() method tries to add those arguments again by calling reflectArguments() and then addArguments().

The logic should either:

1. Not call reflectArguments() if arguments are already configured, OR
2. Use extend() differently to replace rather than append arguments, OR
3. Clear existing arguments before adding new ones

The bug is at src/Controller/ComponentRegistry.php:156-164. It should check if arguments are already configured before trying to add more, or it should replace the existing configuration rather than extending it.

The user should not manually add arguments in Application.php - they should just register the component class itself:

$container-\>add(OauthComponent::class);

And let the reflectArguments() call handle the dependency resolution. The documentation example is misleading too maybe.

---

<div class="post-metadata">

**Author:** ![dereuromark](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/dereuromark/32/37_2.png) [@dereuromark](https://discourse.cakephp.org/u/dereuromark)\
**Post date:** [September 30, 2025, 1:22am UTC](https://discourse.cakephp.org/t/cakephp-5-dependency-injection-inject-existing-service-into-component/12721/3 "2025-09-30T01:22:59Z")

</div>

Can you check if this branch works? [Fix up DI for components. by dereuromark · Pull Request #18938 · cakephp/cakephp · GitHub](https://github.com/cakephp/cakephp/pull/18938)

---

<div class="post-metadata">

**Author:** ![der-dave](https://avatars.discourse-cdn.com/v4/letter/d/e47774/32.png) [@der-dave](https://discourse.cakephp.org/u/der-dave)\
**Post date:** [September 30, 2025, 6:00pm UTC](https://discourse.cakephp.org/t/cakephp-5-dependency-injection-inject-existing-service-into-component/12721/4 "2025-09-30T18:00:21Z")

</div>

Hello dereuromark,

thank you for your quick response to this. I changed the _ComponentRegistry_ and its working now. Thank you!

But, as you mentioned that it should be simply possible to register the component call itself like:

```php
$container->add(OauthComponent::class);

```

Thats not working, I got an Exception:

> Component `App\Controller\Component\OauthComponent` is registered in container but cannot be resolved.

So I am doing it like the documentation says:

```php
$container->add(OauthComponent::class)
            ->addArgument(ComponentRegistry::class)
            ->addArgument(GenericProvider::class);

```

* * *

* * *

Another bug I just noticed is (and I don’t know if its problem depending on the change in _ComponentRegistry_), if Controller and Component have same names like

```php
OauthController;
OauthComponent;

```

I got completely weird results and errors saying:

> [Cake\ORM\Exception\MissingTableClassException] Table class for alias `Oauth` could not be found. in /cakephp/src/ORM/Locator/TableLocator.php on line 249
> 
> Exception Attributes: array (  
> 0 =\> ‘for alias `Oauth`’,  
> )

Its weired because I am not using _TableLocator_ anywhere in _OauthController_ or _OauthComponent_. For now I fixed it changing name of _OauthController_ to something different.

---

<div class="post-metadata">

**Author:** ![dereuromark](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/dereuromark/32/37_2.png) [@dereuromark](https://discourse.cakephp.org/u/dereuromark)\
**Post date:** [September 30, 2025, 11:12pm UTC](https://discourse.cakephp.org/t/cakephp-5-dependency-injection-inject-existing-service-into-component/12721/5 "2025-09-30T23:12:25Z")

</div>

Did you see the PR I linked? Did you check if that one solves it?

---

<div class="post-metadata">

**Author:** ![der-dave](https://avatars.discourse-cdn.com/v4/letter/d/e47774/32.png) [@der-dave](https://discourse.cakephp.org/u/der-dave)\
**Post date:** [October 1, 2025, 4:01am UTC](https://discourse.cakephp.org/t/cakephp-5-dependency-injection-inject-existing-service-into-component/12721/6 "2025-10-01T04:01:22Z")

</div>

Hello dereuromark,

**yes, I see the PR and tried it out. Its working! Thank you!** (I wrote it also in my last reply ;))

But there are some special cases I described in the previous reply, maybe its also interesting for you.

---

<div class="post-metadata">

**Author:** ![dereuromark](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/dereuromark/32/37_2.png) [@dereuromark](https://discourse.cakephp.org/u/dereuromark)\
**Post date:** [October 1, 2025, 9:55am UTC](https://discourse.cakephp.org/t/cakephp-5-dependency-injection-inject-existing-service-into-component/12721/7 "2025-10-01T09:55:00Z")

</div>

You might want to add these things to the PR and actual code discussion, and not keep it inside a forum itself 🙂

---

<div class="post-metadata">

**Author:** ![der-dave](https://avatars.discourse-cdn.com/v4/letter/d/e47774/32.png) [@der-dave](https://discourse.cakephp.org/u/der-dave)\
**Post date:** [October 1, 2025, 7:14pm UTC](https://discourse.cakephp.org/t/cakephp-5-dependency-injection-inject-existing-service-into-component/12721/8 "2025-10-01T19:14:53Z")

</div>

Ok, done it. I was not sure if its ok to post things there

---

<div class="post-metadata">

**Author:** ![ADmad](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/admad/32/20_2.png) [@ADmad](https://discourse.cakephp.org/u/ADmad)\
**Post date:** [October 2, 2025, 4:18pm UTC](https://discourse.cakephp.org/t/cakephp-5-dependency-injection-inject-existing-service-into-component/12721/9 "2025-10-02T16:18:25Z")

</div>

@der-dave To fix your `MissingTableClassException` exception set the `$defaultTable` property of the controller to empty string.

By default that property gets set to a model name based on the controller name (so `Oauth` in your case). Then when you access `$this→Oauth` in your controller, since that property is not explicitly declare the magic `__get()` **method of the controller is called which first tries to load a table class based on the `$defaultTable` property. So setting it to empty string will prevent that and the magic** `__get()` will then move on to checking for a component with that name, which you do have.

---

<div class="post-metadata">

**Author:** ![der-dave](https://avatars.discourse-cdn.com/v4/letter/d/e47774/32.png) [@der-dave](https://discourse.cakephp.org/u/der-dave)\
**Post date:** [October 3, 2025, 12:27pm UTC](https://discourse.cakephp.org/t/cakephp-5-dependency-injection-inject-existing-service-into-component/12721/10 "2025-10-03T12:27:20Z")

</div>

Oh, thank you, that solved it. Didn’t know about this. Great!
