Tsaukpaetra's Injection Dependency
-
@Tsaukpaetra case sensitivity doesn’t matter but if you have a
use Some\Namespace\ClassA;
declaration, ClassA is now a bound name in use for the scope of the file, so a class being declared in the same file (even if it has a namespace declaration) is assumed to overlap the same as the use statement.I haven’t looked at the PHP parser source but I’d buttume the issue is
use Some\Namespace\ClassA
while in another namespace is an implicit alias into that namespace, e.g. that use while insidenamespace Another\Namespace
implicitly declaresAnother\Namespace\ClassA
so a subsequent (actual) class declaration is duplicating inside that namespace.
-
@Arantor said in Tsaukpaetra's Injection Dependency:
@Tsaukpaetra case sensitivity doesn’t matter but if you have a
use Some\Namespace\ClassA;
declaration, ClassA is now a bound name in use for the scope of the file, so a class being declared in the same file (even if it has a namespace declaration) is assumed to overlap the same as the use statement.Well it does matter because if I try to
use blarg\classa
and then try tonew ClassA()
it screams at me.But apparently sometimes not, as shown above.
-
@Tsaukpaetra class names are case insensitive everywhere in PHP, as are function and method names, but not variables or properties or constants.
-
@Arantor said in Tsaukpaetra's Injection Dependency:
@Tsaukpaetra class names are case insensitive everywhere in PHP, as are function and method names, but not variables or properties or constants.
:hair_pulling_intensifies.png:
-
@Tsaukpaetra said in Tsaukpaetra's Injection Dependency:
:hair_pulling_intensifies.png:
Okay, so I get the container is supposed to define things that can be gotten implicitly in the magic constructor of classes, but how do I make it able to inject things into arbitrary objects?
I'm thinking this is going to be application-specific, as I'm trying to make the magic objects from inside the configuration which would provide those objects (?), which is clearly not working...
At best I get a "No entry or class found" but at worse it tells me functions that examples say should exist don't actually exist...
-
Status: I seem to have created a circular dependency...
-
@Tsaukpaetra said in Tsaukpaetra's Injection Dependency:
Status: I seem to have created a circular dependency...
You've done things that depend on you doing things that you haven't done yet? Why, that's precisely the idea!
-
@Tsaukpaetra OK so the idea is that the DI container should be responsible for creating objects.
You say to DI container, hey I'd like one of those objects please, and it inspects the object which says 'I want a thing with a FrobnicatorInterface so I can be constructed', and the DI container should have configuration for 'I have a DiscreteFrobnicator which implements FrobnicatorInterface' so it can pass it in that way.
There are times this will go awry so most of the existing DI container libraries should be able to do a manual override to say 'hey I want you to make one of these objects, but use this for the FrobnicatorInterface this time'
Mileage varies on the library doing this - but Symfony's certainly can handle both having a configuration file of 'this is what the normal bindings are' and also 'on this invocation do something else'
-
@Arantor said in Tsaukpaetra's Injection Dependency:
Mileage varies on the library doing this - but Symfony's certainly can handle both having a configuration file of 'this is what the normal bindings are' and also 'on this invocation do something else'
Could not figure it out. So I just broke the injection thingy and made the object I wanted myself anyways.
I'm sure the proper thing to do is raise some sort of
UnauthorizedException
but since I can't figure out where that might be or what might do the needful I'm just writing the response by hand. In each class.Wait, this sounds like backwards progress...
-
@Tsaukpaetra indicates off-by-one on real class count. When 2 classes are involved it is because they either want to be the same class or to share an unexpressed third dependency, for the simplest case. Aggressive SRP will untangle towards 3 or more in most cases, and/or towards sharing unexpressed dependencies.
Although, perhaps it's just a matter of needing to use
real_injected
vsinjected
, given PHP.
-
@Tsaukpaetra said in Tsaukpaetra's Injection Dependency:
Could not figure it out. So I just broke the injection thingy and made the object I wanted myself anyways.
OK are you using Symfony's DI or something else?
-
@Gribnit said in Tsaukpaetra's Injection Dependency:
Although, perhaps it's just a matter of needing to use real_injected vs injected, given PHP.
PHP 5 fixed this in 2004. It's not funny any more.
-
@Arantor said in Tsaukpaetra's Injection Dependency:
@Tsaukpaetra said in Tsaukpaetra's Injection Dependency:
Could not figure it out. So I just broke the injection thingy and made the object I wanted myself anyways.
OK are you using Symfony's DI or something else?
Whatever the
PHP-DI
package is.I re-fixed it after I discovered there is indeed a
HttpUnauthorizedException
so I didn't need to make aResponse
myself anymore, which resolved the circle.
-
-
@Arantor said in Tsaukpaetra's Injection Dependency:
@Gribnit said in Tsaukpaetra's Injection Dependency:
Although, perhaps it's just a matter of needing to use real_injected vs injected, given PHP.
PHP 5 fixed this in 2004. It's not funny any more.
Doesn't matter. It's the law.
-
-
Status: Confounded.
So, there's a
LoggerFactory
that's supposed to be used to create loggers or whatever.I want to make the default logger factory put shit into the database. Seems easy enough, in the container definition I put the $container->get('LogTable') and pass that into the constructor for the logger factory (I guess? Whatever, some things get injections, others are spared I guess).
Now I want a special logger that's just for the default error handler... but I can't re-use my injected LoggerFactory since it will come pre-installed with the wrong LogTable set up...
Ugh.... and the docs are all "Just autowire but maybe not if you can't the string for the function you autoload and the parameters compile" gibberish...
-
@Tsaukpaetra so you need to define a second logger service, both in your underlying config and the service definitions, then in your error handler ask the DI container for your second logger and run with that.
This might seem hinky but in practice it’s literally no different to “this method needs a Foo that I don’t otherwise have so I need to define a FooFactory service definition”
The service definition just needs to get the configuration for the new service, invoke the factory with the new config and return that as if it did the needful all by itself.
-
@Arantor said in Tsaukpaetra's Injection Dependency:
then in your error handler ask the DI container for your second logger and run with that.
Yeah that's the part. I ended up making a new entry, and just hand-rolled all the things the DI was supposed to be doing for me. Whatever I gues.
-
@Arantor And then you need a second DI framework to inject a logger into your first DI framework?
-
@Tsaukpaetra no, that’s how it should logically work.
DI is about “you need an X to make that work, the configuration says this is the one you need” without caring how X gets made or what X is beyond whether it fulfils some implied or actual interface.
The fact you have Y as a special case subtype of X isn’t really a subtype of X even if its concrete implementation logically is a subtype or sibling type.
You have two dependencies: a general purpose logger and an exceptional behaviour logger. You could satisfy these with the same dependency but for the purposes of service provision they are logically separate services to be catalogued in the DI configuration.
-
@PleegWat it’s singletons all the way down, I’m afraid.
-
@Arantor But at least you haven't baked all the details of this into every single one of your classes. Which is the point of DI. (Many DI systems also have sophisticated mechanisms for building instances of classes, but they're not the heart of DI.)
-
@dkf Yup, and that's the key point here. You can still switch out or replace the implementations of the loggers here at any point because the methods just know they have dependencies of a type to be satisfied, and it's the DI's problem how to satisfy them.