Closed pauleveritt closed 5 years ago
@mmerickel For now I've copied injector.py into my project and I'll use a private copy.
I was under the impression originally that you were trying to use the wired.dataclasses.factory
and add extra features to it but that doesn't appear to be the case. The injector really only exists to support that api.
I think you just need to vendor the injector for now. You've already written a custom factory that is a superset of features supported in wired. I'm not sure it's the right time to expose the injector publicly just to avoid rewriting that code in your custom extension.
Replaces #31 and supports PR #33
It is with great pleasure that I demonstrate @mmerickel is wrong. đ Or at least, demonstrate a use case for something he correctly pointed out couldn't work.
In #33 I made a small change to let the
Injector
be passed in some args which would be used before the container when looking stuff up. This is to support mywired_components
: in a template, you might do{{ Breadcrumb(label='Hello') }}
andlabel
would be passed into the dataclass factory.@mmerickel pointed out two flaws:
.get()
, which doesn't and shouldn't support arbitrary argsMichael asked for an example to justify a change supporting the second bullet. Here goes.
wired_components
I have a project
wired_components
with a branchcomponent_decorator
that copies in a privateinjector.py
file with the changes I made in the PR.I made two flavors of my component creation, one without the injector-props change that shows I have to manually provide things:
... and one where I can just use injection:
The second is shorter, but that's less important: it lets me use the features of injection and components can access things in the container other than my hardwired list.
Double Partial
How do the props get there? This is kind of a freaky setup, due to Jinja2. I register partial functions corresponding to each component. The partial function has the container. It points to a function which is callable with the parameters.
So, a double partial, so to speak, with both container and props in scope. I can then pass both into
Injector.__call__
.Recommendation
This shows that the Injector is useful beyond just a service container. It can be used, for example, when sniffing standalone functions that might want arguments injected.
At a minimum, it makes my use case much better. I recommend accepting my change (which breaks nothing) and putting
Injector
inwired.dataclasses.__all__
as part of the public API.Sidenote: At some point in the future I might resurrect my Jinja2 extension that would eliminate one of those partials. But that's painful and low on the list.