'CodeIgniter 4 \Config\Service::my-instance-method returns NULL on true $getShared

Config\Services is a class made to reduce huge code development on singleton. Unfortunately I have committed an error.

When repositoryFacade is got from getShared,

Services::repositoryFacade(Services::userRepository(), TRUE);

The code will fail and says:

Config\Services::repositoryFacade(): Return value must be of type App\Domain\Core\IRepositoryFacade, null returned

The following code has been set in app/Config/Service.php

public static function repositoryFacade(IRepository $repository, bool $getShared = false): IRepositoryFacade{
    if ($getShared) {
        return self::getSharedInstance('resourceFacade');
    }

    return new RepositoryFacade($repository);
}

public static function userRepository(bool $getShared = true): IRepository
{
    if ($getShared) {
        return self::getSharedInstance('userRepository');
    }

    return new UserRepository(model(UserModel::class));
}

RepositoryFacade is in infrastructure layer to serve IRepository domain interface one by one, while UserRepository is a concrete class in infrastructure layer, its duty is to let RepositoryFacade to perform ORM, without any touch to domain layer.

Is the getShared not useful at all? There is no error when TRUE value has been removed.

Services::repositoryFacade(Services::userRepository());


Solution 1:[1]

This line of code is incorrect logically.

Services::repositoryFacade(Services::userRepository(), TRUE);

Change it to below works perfectly.

Services::repositoryFacade(Services::userRepository(TRUE));

It would be more than one RepositoryFacade class instances can be made to serve Repository instances, such as UserRepository, ProductRepository, thus we no need to get the same instance of RepositoryFacade.

UserRepository should be unchanged all the times. Therefore we can get the same instance of UserRepository by:

Services::userRepository(TRUE)

If it is needed to use the facade with UserRepository more than once, just

$facade = Services::repositoryFacade(Services::userRepository(TRUE));

// use multiple times with the facade 
$result = $facade->findById(5);
if (!empty($result)) $facade->delete(5); 

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 mondayrris