Last active
December 18, 2015 00:38
-
-
Save AmyStephen/5697696 to your computer and use it in GitHub Desktop.
Are there better approaches for accessing the container to request the creation of a dependent class when creating that class?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| //Level 1 | |
| class Container implements ContainerInterface | |
| { | |
| public function getService($service, $options = array()) | |
| { | |
| // returns class instance if it has been so configured and is available | |
| // creates new instance uses an adapter pattern | |
| } | |
| // also available: getServices, setService, cloneService, removeService... | |
| } | |
| // Level 2 - Adapter - container drives the class construction process via an adapter, interface: | |
| interface InjectorInterface | |
| { | |
| public function get($key, $default = null); | |
| public function set($key, $value = null); | |
| public function setDependencies(); | |
| public function instantiateService($create_static = false); | |
| public function performAfterInstantiationLogic(); | |
| public function getServiceInstance(); | |
| public function destructService(); | |
| } | |
| // Level 3 - Handler - implements the Interface above providing | |
| // 1 - "standard" (automatic convention and reflection approach for simple class construction) | |
| // 2 - per-class custom DI injectors (where gathering dependencies is more complex/custom) | |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Ok @Crell - thanks for that, that gives me something to think on. All the adapter/handler pairs do is create the class. The only "custom" code relates to gathering dependency data and storing it in an area where it can be automatically injected by the abstract class method into the class via the constructor.
In the container itself, I create this Closure and then pass it into the Adapter.
The adapter uses it to request another Service from the IoCC (1st 2 lines.) That it uses to build the dependencies.
In this case, it's getting configuration data from the Application object for email options.
In this example, it's preparing the MVC structure for processing data, which means it needs an instance of the User object, the Field Handler, the Event Scheduler, etc.
The approach has had a good effect in that it has separated out construction code from the application.
I'm trying to keep that code very simple, which speaks to your comment on testing, although I wouldn't want to avoid testing here, it's key processing.
I just can't think of any better way to isolate the class creation (one entry point hooked to the front controller) without using some kind of static (to keep the door open, as it were), but that essentially means you are passing that container into a class, which is what I had been trying to avoid.
I never use the $getService closure outside of the Adapter/Handler pairs. I might even add some code to check that entry comes from a class of that type to discourage broader use.