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?

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;
    }
}
  • 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. – hakre Aug 19 '16 at 14:02

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.