-
Notifications
You must be signed in to change notification settings - Fork 9.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ObjectManager's Factory should be replaceable depending on service #569
Comments
@Ocramius, thank you for your contribution! The team will analyze it and we will get back to you once we have the results. |
@Ocramius Can you list the corner cases Magento\Framework\Interception doesn't cover? As for constructors, they are not subject to LSP because they are not object methods and are not part of object's interface. I'm not sure I understand the benefits of instantiation example you provided. We don't support such cases because it can be achieved with standard approaches. Also, $objectManager should not be used in module code directly, because we try to avoid service location. |
@antonkril mainly access to properties and non-public methods.
Constructors are subject to the LSP as well. They may not be a part of the API in magento's core, but any usage of the constructor of an interceptor (usually done via
The point here is lazy loading. If I want to skip instantiation of a service to make it lazy then I can't do that without overriding how it gets instantiated. More on this can be found here and here (I implemented it for both containers).
Service location is perfectly acceptable in the context of factories. The locator doesn't need to leak outside the factory into services. |
@Ocramius Have you seen the support for Proxy classes that already exists? They should help with the lazy loading, unless I'm missing some detail. |
@Ocramius current implementation of Interception allows pluginization of protected methods conceptually. But this access was limited intentionally to prevent 3PD interaction with protected interface of classes in plugins, because it would be a hack, and would render any post-release magento code modifications backwards incompatible.
We avoid usages of
You can read about lazy-loading in Magento with Proxies here
100% agree. I didn't understand that example is from factory. But Magento 2 provides a way to do this without such custom logic. |
Do I get this correct when I say that you would explicitly override services with their proxies counterparts? That's pretty much what I wanted to avoid, and instead silently override a service with a different instance (kind-of like a container compiling pass) |
Different instance of a proxy is created, it substitutes expensive service, and when this service is required, proxy creates it. So this happens transparently to the client code. Client code doesn't distinguish if it works with a proxy or original object. Proxies are auto-generated. |
@antonkril that makes sense, though it seems that it needs manual overrides on the config (by explicitly using the proxy class instead of the real class). That can be fixed via some pre-compiling passes though. Getting back to factories, I still don't see a way of using a different factory to build my object. Would something like a "factory" support be acceptable? I realize that this is touching very core components, but I would like to work on these before there's any feature freeze. |
Yes, you have to declare proxy in config. We had discussions about just declaring types or arguments as "lazy", but decided to leave it explicit for developers to understand the behavior. I'm not sure I understand, how pre-compiling will change the situation? Now we request minimal information in config.
If you are talking about entity (non-injectable) factories, they are auto-generated, but if you create your own factory for your type and name it As for services or injectables (instances that you can ask for in constructor): for now we don't have factories for them. Proper object decomposition allows you to avoid factories for non-injectables. Introduction of such factories would add more "magic" and "invisible" code written by 3PD and would let them think less about their object decomposition. That said, we still have discussions about these "service factories" and if you provide some valid use cases, we can revisit this. |
@Ocramius, could you please provide use cases as asked by @antonkril? |
@antonkril is there also a way of using a factory without depending on a derived class name?
It's not a perfect world, heh...
It would actually simplify instantiation for various kinds of services that don't just rely on constructor injection. That is not an issue for core itself, but for any dependency introduced in a project.
My particular use-case is about making services lazy/proxied (mainly for performance), as well as using own AOP-ish libraries. To do that, I'd basically need to swap out the default instantiation logic somehow, and defer it to a |
Sure.
Adapters should be used for that instead of factories. Adapters are also a better idea because they abstract you from specific implementation of the dependency.
Can you describle what are the problems of current implementation of lazy-loading and AOP? |
@antonkril I just was speaking about this with @Ocramius at DPC. Happy toi chat more. |
* Various improvements: * Implemented a general way of using RSS module * Created a cron job in the Customer module for cleaning the customer_visitor table * Added a warning message to the Use HTTP Only option in the Admin panel * Implemented the Grid component in the Magento UI Library * Reimplemented the URL Rewrites functionality in the new UrlRedirect module * Framework improvements: * Added the ability to install Magento 2 using CLI * Aggregated Magento installation and upgrade into one tool * Refactored CustomerService REST WebApi to be more RESTful * Increased unit and integration test coverage * Moved page asset management to page configuration API, and eliminated the \Magento\Theme\Block\Html\Head block * Eliminated the Root, Html and Title blocks * Themes update: * Removed widgets from the default Magento installation * Fixed bugs: * Fixed an issue with wishlist creation for non-registered customer * Fixed an issue with Google Mapping where Condition did not show correct value * Fixed an issue where there were too many notifications for admin user by default * Fixed a Daylight Savings Time calculation error * Fixed an issue where default cookie path and lifetime were not validated prior to saving * Fixed an issue where current admin password was not required for resetting admin password * Fixed an issue where custom customer attribute or customer address attribute was not accessible when custom_attribute is used as the attribute code * Fixed an issue where integration entity could not be deleted after being searched in grid * Fixed an issue where invalid parameter value was shown in SOAP * Fixed an issue where exception was thrown for Array to String conversion in SOAP * Fixed an issue where exception was thrown due to invalid argument supplied for foreach() statement in REST * Fixed an issue where admin tax notifications did not appear correctly in the System Messages dialog box * Fixed an issue where tax details were missing when viewing order in the Admin panel * Fixed an issue where styles for the storefront store selector were absent * Fixed an issue where customer got 404 page when switching store views on the product page of a product with different URL keys in different store views * Fixed an issue where the Add To Cart button in the MAP pop-up did not work for configurable and bundle products * Fixed an issue where for specifying options for configurable product was absent after adding a product from the MAP pop-up * Fixed an issue where a fatal error was thrown after selecting shipping method on PayPal Express Checkout * Fixed an issue with sending invoice email * Fixed an issue where integration tests failed with a fatal error * Fixed an issue where credit memo entry was not created after performing a refund for an order * Fixed an issue where categories layout for widgets did not work * Fixed an issue where opening a page restricted by ACL lead to blank page instead of the Access Denied page * Fixed an issue where a blank page was displayed instead of the using the Advanced Search result * Fixed an issue where the "Please wait" spinner was absent on Ajax requests for order creation in the Admin panel * Fixed an issue with the main navigation menu location on the page * Modularity: * Implemented the automatic applying of the MAP policy * Indexers: * Eliminated the old Magento_Index module * Search library * Added wildcards filter * Eliminated unused queries and filters * Added IN to Term filter * Moved the "value" attribute from <match> to <query> for the Match query * Refactored the usage of negation * Implemented Request Builder * CatalogSearch adapter * Pluginized adding attribute to search index * Merged base declaration with searchable attributes * Added the following Setup CLI tools in the setup folder * Deployment Configuration Tool * Schema Setup and Update Tool * DB Data Update Tool * Admin User Setup Tool * User Configuration Tool * Installation Tool * Update Tool * GitHub requests: * [#615] (#615) -- Use info as object in checkout_cart_update_items_before * [#659] (#659) -- Recently viewed products sidebar issue * [#660] (#660) -- RSS global setting * [#663] (#663) -- session.save_path not valid * [#445] (#445) -- use of registry in Magento\Tax\Helper\Data * [#646] (#646) -- Fixed flat category indexer bug * [#643] (#643) -- Configurable Products Performance * [#640] (#640) -- [Insight] Files should not be executable * [#667] (#667) -- Tiny improvement on render() method in Column/Renderer/Concat * [#288] (#288) -- Add Cell Phone to Customer Address Form * [#607] (#607) -- sitemap.xml filename is not variable * [#633] (#633) -- Fixed Typo ($_attribite -> $_attribute) * [#634] (#634) -- README.md contains broken link to X.commerce Agreement * [#569] (#569) -- ObjectManager's Factory should be replaceable depending on service * [#654] (#654) -- Demo notice overlapping * Functional tests: * Abandoned carts report * Adding products from wishlist to cart * Create invoice for offline payment methods * Delete products from shopping cart * Delete widget * Global search * Order count report * Order total report
The team has processed this issue. The updated code has just been deployed to the repository under version 0.1.0-alpha97. Thank you for your contribution! This issue is now closed. |
@verklov thanks! Is there any sha1 reference that can be used to verify what was changed, related with this issue? :-) |
@Ocramius, since we are performing deployments as a single merged commit, I guess there is only one way to see this. Please use this link https://github.com/magento/magento2/blame/873d38c884fb56411c4ac3bb46a9d4343e4545fe/lib/internal/Magento/Framework/App/ObjectManagerFactory.php#L105. The string that you are interested in appeared in version 0.1.0-alpha97. |
@verklov ok! Thanks for that =) |
You are welcome! :-) |
…tory MAGETWO-60477: Invalid SalesInventory module version - 2.1
Currently, the
Magento\Framework\ObjectManager\ObjectManager
accepts a singleMagento\Framework\ObjectManager\Factory
as a parameterI've been trying to build better interceptors on top of
ProxyManager
, since the currentMagento\Interception
component is quite naive, and doesn't deal with a lot of corner-cases (different PHP and HHVM versions/bugs/gotchas).The end aim is avoiding any kind of LSP violation (even for constructors) by having interceptors simply have their own factory type.
In pseudo-code, it would be something like this:
The
ObjectManager
would then need to use the configuration to find out the proper factory to be used with a particular service:This is just one possible approach, but it would make:
Interception
component, plugging in a more robust solutionObjectManager#create()
andObjectManager#get()
I'm still digging through the files, but the main point is that instantiation logic is not always getting parameters from a parameter bag and stuffing them in a constructor, for example like in following pseudo-code:
Maybe I missed the way that I can achieve this, but the current factory implementation seems quite inflexible.
The text was updated successfully, but these errors were encountered: