0

My controllers have an account object and a user object, and almost all interactions with the backend depends on these objects to set access rights, limit data loads, ++++ (I am not using any specific framework)

My controllers have different ways of knowing which objects to use, but usually this is in the session for logged in users (but backend processes might get this information from the queue etc).

So, I am trying to setup PHP-DI for my ServiceLayer and I need to inject Account, User object to the services, but how do I do this in a good way ensuring that these have the right values?

My first attempt was to pass this into a ContainerFactory:

public static function getInstance(EnvironmentConfig $config, ?int $accountId, ?int $userId):Container

Then use these values dynamically in the configuration, however this stopped working when I enabled compilation as the values got cached. (obvious but yes..)

I can use a factory for creating the userObject and Account object and e.g read the values directly from the session in the Factory. But this feels very dirty, and will only work in certain contexts.

The documentation only deals with environment specific values, so I have not found any good description with how to deal with session specific data.

Any suggested patterns for this?

user3159921
  • 65
  • 1
  • 5

2 Answers2

2

A container should store stateless objects. Request-specific data like session, logged in user, etc. are not dependencies, trying to put them into the container means going back to global state.

I highly recommend you pass that data through other ways: method call parameters, store them inside a Request object, at worse inject a RequestStack or similar object. That's what Symfony did when they deprecated injecting the Request objects directly using the container: https://symfony.com/blog/new-in-symfony-2-4-the-request-stack

Matthieu Napoli
  • 48,448
  • 45
  • 173
  • 261
0

Thanks for your quick reply. Principally I do agree, these things are border line as they are intrinsic to all application layer, the application has a global state depending on logged in account and user and that remains like that for the entire session. Yes this is technically request specific, but I need the service layer to be aware of this as so much business logic depends on it.

method call parameters would be technically clean, but super-messy and error prone as this would be the same parameters repeated all over in the application. All the service calls would end up like this:

$service->getCategory($id, $user, $account);
$service->getCategoryByMain($mainCategoryId, $user, $account);

Hence I was looking at PHP-DI to get a cleaner injection than my current setup where I get long Service constructors that are the same all over in the application.

Not sure how to make this neat, so open for any good practical suggestions :) Maybe PHP-DI is not the right tool here, but this is DI problem, where I have a set dependencies that needs to be pushed down in the stack.

user3159921
  • 65
  • 1
  • 5