2

For my concrete class I'd like to have a dependency (via interface type-hint) that at the time of instantiation not only lazy-loads (e.g. Magento 2 Proxy) but also resolves to the class-name, for example via a function call.

As far as I've understood the concept of the proxy the proxy is only able to lazy-load a concrete class instance.

In my case I need to lazy-resolve such an instance as well.

Example:

In context of my module, there is the current user. So that current user is the dependency. As it's the dependency the class has to ask for it (not to look for it).

<?php
# ...
class MyModule
{
 # ... 
 public function __construct(CurrentCustomerInterface $customer) 
 {
 $this->customer = $customer;
 }
 # ...
}

Right now a common pattern I do see in my code is to require the Session and obtain the current user from it. This violates a design principle, as you should not look for things.

I could extract that looking into a CurrentustomerResolver but still I need to look for things, it's just a bit more abstract (I would add a single layer of indirectness).

Question is: What does the Magento 2 dependency injection layer provide for true(tm) lazy-load of dependencies?

asked Aug 19, 2016 at 8:17

1 Answer 1

3

I'm not sure why the current customer would have different class names and would try to avoid that if possilbe, but I'll take it as requirement to answer the question.

Since the automatically generated proxy classes can't do that for you, I'd suggest to write your own. To avoid manually creating all the boilerplate, extend the autogenerated proxy and only override _getSubject() which instantiates the actual object.

This could look like this (for an interface CurrentCustomerInterface):

class DynamicCurrentCustomerInterfaceProxy extends CurrentCustomerInterfaceProxy
{
 /**
 * Get proxied instance
 *
 * @return \Magento\Customer\Api\CustomerRepositoryInterface
 */
 protected function _getSubject()
 {
 // replace the following line to determine the class name
 // based on customer session or whatever
 $instanceName = $this->_instanceName;
 if (!$this->_subject) {
 $this->_subject = true === $this->_isShared
 ? $this->_objectManager->get($instanceName)
 : $this->_objectManager->create($instanceName);
 }
 return $this->_subject;
 }
}
answered Aug 19, 2016 at 9:20
1
  • Okay, that would be for re-using the proxy. I have to try if this actually works, the DI layer needs to know that the proxy should be generated. But I do see the point in your answer how it could work. +1 for this alone. Commented Aug 19, 2016 at 14:02

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.