We use cookies to improve your experience. No personal information is gathered and we don't serve ads. Cookies Policy.

ExpressionEngine Logo ExpressionEngine
Features Pricing Support Find A Developer
Partners Upgrades
Blog Add-Ons Learn
Docs Forums University
Log In or Sign Up
Log In Sign Up
ExpressionEngine Logo
Features Pro new Support Find A Developer
Partners Upgrades
Blog Add-Ons Learn
Docs Forums University Blog
  • Home
  • Forums

How to use the new autoloader

Developer Preview

Rob Sanchez's avatar
Rob Sanchez
335 posts
11 years ago
Rob Sanchez's avatar Rob Sanchez

Is there a sanctioned way to use the autoloader in an addon?

This is the way I figured out, but it seems clunky to have to use the global syntax.

public function __construct()
    {
        global $AUTO;
 
        $AUTO->addPrefix('MyAddon', PATH_THIRD.'my_addon/src/MyAddon/');
    }
       
Adrian Macneil's avatar
Adrian Macneil
21 posts
11 years ago
Adrian Macneil's avatar Adrian Macneil

Just a thought - why don’t you guys tack the autoloader onto the global ee() object? ee()->autoloader->addPrefix() would work fine.

       
Pascal Kriete's avatar
Pascal Kriete
2,589 posts
11 years ago
Pascal Kriete's avatar Pascal Kriete
ee()->autoloader->addPrefix() would work fine.

Yeah, normally that’s probably where it would go. People have a habit of replacing things we put there with their own stuff, so I think we’re going to be a little more strict (and yet more flexible) on this one.

We talked it over and we’re thinking of make it a singleton-by-choice.

new Autoloader() // use your own instance
Autoloader::getInstance() // use the shared instance

We’re going to recommend people use the shared instance for performance reasons, but we’re keeping the constructor open so we can run isolated autoloader tests, and so it’s there for extension and instantiation if someone happens to need that.

It didn’t make dev preview 6, but in the next one and in the final release it’ll be:

Autoloader::getInstance()->addPrefix(..)
       
Adrian Macneil's avatar
Adrian Macneil
21 posts
11 years ago
Adrian Macneil's avatar Adrian Macneil

Out of interest, why don’t you guys just use the existing \Composer\Autoload\ClassLoader class? You can use it standalone without pulling in all of composer. It does pretty much the same thing as your class, but is battle tested and easy to use/extend for us third party devs.

https://getcomposer.org/apidoc/master/Composer/Autoload/ClassLoader.html

       
Pascal Kriete's avatar
Pascal Kriete
2,589 posts
11 years ago
Pascal Kriete's avatar Pascal Kriete

The primary reason is PSR-0 vs PSR-4. All the defaults for the composer loader are PSR-0. We prefer PSR-4. While composer is capable of PSR-4, all of those methods are suffixed with ‘psr4’ which is a little confusing to new developers.

Also confusing is the fact that it’s composer namespaced, when composer really wouldn’t be available in the system. Plus, cherry picking single files makes it difficult to pull in upstream changes. We don’t benefit from the open source aspect if we just cherry pick files. Someone has to remember where those files come from and update / test regularly.

Lastly, long term I don’t see us encouraging developers to use it. In fact, I don’t think composer encourages it either. There’s an in-between phase where we’re running parallel systems and it can’t be avoided, but long term I would prefer add-ons to have a config file (similar to composer.json). So you would never need to touch the autoloader.

Does that make sense?

       
Adrian Macneil's avatar
Adrian Macneil
21 posts
11 years ago
Adrian Macneil's avatar Adrian Macneil

Yeah that makes sense. It’s nice creating a simpler interface for PSR4 only, hopefully composer will do that at some point too.

In the short term I don’t see us changing from our existing setup (we ship with the composer autoloader, since we depend on various third party libraries), but it’s nice to see you are thinking about this and moving to a more OO code style.

Not really a fan of singletons, would prefer to see a dependency container/IoC pattern (which is essentially what the global ee() object is). The fact that people can extend it is powerful, not a hindrance (although I doubt people would go swapping out core libs and expect things to keep working as normal).

       
Pascal Kriete's avatar
Pascal Kriete
2,589 posts
11 years ago
Pascal Kriete's avatar Pascal Kriete
Not really a fan of singletons, would prefer to see a dependency container/IoC pattern (which is essentially what the global ee() object is). The fact that people can extend it is powerful, not a hindrance

Which is why we’re keeping the constructor public. To me a di container should piece together the different modules of the application (module not used in the EE sense), the autoloader is really a part of the dependency resolution process. Right now there’s just not really enough namespaced code to group some things.

although I doubt people would go swapping out core libs and expect things to keep working as normal

Please shout that from the rooftops! A relatively common pattern right now is to replace things on ee() with an object that extends ours. Works great once. Works not-at-all when more than one extension does it.

dependency container/IoC pattern (which is essentially what the global ee() object is)

Oh I wish. Right now it’s a service locator full of singletons. The bane of all testable code. Someday though … 😊

       

Reply

Sign In To Reply

ExpressionEngine Home Features Pro Contact Version Support
Learn Docs University Forums
Resources Support Add-Ons Partners Blog
Privacy Terms Trademark Use License

Packet Tide owns and develops ExpressionEngine. © Packet Tide, All Rights Reserved.