Skip to content
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

Ability to define different aliases for an interface? #35

Closed
Danack opened this issue Dec 4, 2013 · 7 comments
Closed

Ability to define different aliases for an interface? #35

Danack opened this issue Dec 4, 2013 · 7 comments

Comments

@Danack
Copy link
Collaborator

Danack commented Dec 4, 2013

@rdlowrey The other day you asked what features I think are still needed - here is one, which we've discussed this before, but I can't find a link.


Sometimes you need to be able to use different implementations for the same interface, based on external factors.

interface Logger{}

class UtilityClass {
    function __construct(Logger $logger){}
}

class ClassThatIsWorkingCorrectly{
    function __construct(UtilityClass $utilityClass) {}
}

class ClassRelatedToReportedBugs{
    function __construct(UtilityClass $utilityClass) {}
}

Most of our code is working fine and so we want the 'Logger' to be inserted to be one that only reports notices at the 'error' level.

However some of our users have reported bugs that we think is being caused by the code in ClassRelatedToReportedBugs, or code that it calls. We want to be able to configure our system so that any 'Logger' created by 'ClassRelatedToReportedBugs' or any of it's dependencies uses a Logger that reports notices at the 'info' level.

I think this does need to be configurable through configuration rather than modifying the code, as that the changes need to be done on a production server without downtime.

For the above case, my fork with it's (marginally crazy) ability to alias/share different classes based on the chain of class constructors solves that problem.

However there are probably other cases where some other solution would be needed e.g.

// Copies data from one server to another.
function archiveData(DBConnection $liveServer, DBConnection $backupServer){
}

Wouldn't currently be possible would it?

Obviously not every possible way of configuring which classes are instantiated needs to be supported, or should even if it is possible, however I think the first case above is something that most people would expect to be able to configure.

@Danack
Copy link
Collaborator Author

Danack commented Dec 4, 2013

btw there's probably better ways of handling this than just coding it inside Auryn e.g. either make the lookup of which alias/shared class to use either be more easily extendible (by moving it to it's own function), or allowing Auryn to use plugins to alter it's behaviour, rather than trying to do everything in Auryn.

@rdlowrey
Copy link
Owner

rdlowrey commented Dec 4, 2013

I hadn't thought of that (other ways to incorporate "templates" or "profiles"). A plugin or event system would probably resolve my issues. I'm not against the idea itself, I just couldn't reconcile it with how the existing code was structured. I'll give it some thought and throw some ideas at the wall and we'll see what sticks.

@Danack
Copy link
Collaborator Author

Danack commented Dec 8, 2013

A first draft of having the Provider info be a plugin to the Injector is here

Okay so what I've done is:

  1. Separated the actual injector code from the Provider class into a new class called Injector.

  2. Moved all the Provider information about aliases/sharing etc from the Provider class to a StandardProviderPlugin which implements a ProviderPlugin interface.

  3. To keep backward comptatibility for now, the standard Provider class creates a StandardProviderPlugin and passes all the alias/share/delegate calls to that plugin. For a 1.0 release we would probably want to remove this though as it does make it easy for noobs to get started with Auryn, maybe not.

  4. Renamed the 'beingProvisioned' property in the Injector to 'classConstructorChain' and made it be ordered, so that it can be passed to ProviderPlugins.

  5. All the calls to the ProviderPlugins also pass in the classConstructorChain. Although this is ugly, some (or at least my) plugins will in some cases need to have that info, to be able to provision the correct class based on that chain of class constructors.

Obviously still lots to tidy up, but I'm about to jump on a plane to 'Stralia, so will be offline for a while.

@rdlowrey
Copy link
Owner

rdlowrey commented Dec 9, 2013

Awesome. It may take me a day or two before I have the time to sit down and digest everything, but it sounds good.

@Danack
Copy link
Collaborator Author

Danack commented May 22, 2015

Other than the fact that i) The function name sucks ii) The classes in progress get passed to the resolve function as lower case iii) a complete lack of error checking, this doesn't appear to be too horrible a solution.

https://github.com/rdlowrey/Auryn/compare/rdlowrey:master...Danack:lookup?expand=1

@Danack
Copy link
Collaborator Author

Danack commented Jul 2, 2015

Actually this is a way lighter weight solution:
https://github.com/rdlowrey/Auryn/compare/master...Danack:delegateConstructionHierarchy?expand=1

If we really wanted to trim off the last 'InjectionChain'....tbh we could leave this from version 1 until someone really needs it.

Danack added a commit to Danack/Auryn that referenced this issue Dec 21, 2022
@Danack
Copy link
Collaborator Author

Danack commented Dec 21, 2022

A mere nine years later, as this hasn't been added, it probably never will be.

I wrote some words in 7d500bc why not.

@Danack Danack closed this as completed Dec 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants