I posted Introducing Annotated Container Part 3. It talks about some of the things I've learned after working on Annotated Container for roughly a year.


I wanna make some improvements to this but I"m super pleased with how integrating Annotated Container into Amp's http-server went. It took me roughly 1~ hour to do this.

It supports autowiring routing using a `#[Controller(method: HttpMethod::Get, path: '/path')]` syntax.


Somewhere a Java developer is smiling maniacally, rubbing their hands together... "Yes, yes. Feel the darkness course through you."

Show thread

With Annotated Container I had to allow defining services that can't be annotated. I created a class named `ContainerDefinitionBuilderContextConsumer`. In that moment the name didn't bother me too much. It was descriptive enough if you know the internals of the library. But, knowing that users will need to implement this interface I now cringe when I see it.

I'm currently writing documentation on it. I just typed `ContainerDefinitionBuilderContextConsumerFactory` ... mega cringe

I put together a demo app showcasing Annotated Container. It integrates Doctrine and Symfony Console. It includes a "clean" architecture, real database calls, and something you can clone and run on your own machine to see how Annotated Container functions.


Always wanted to write a HTTP mocking framework with . Decided to write one using amphp/http-client v5 with Fiber support.


As the backing implementations start to implement their own Attributes Annotated Container could keep up with them. For example, I could, in theory, support Symfony's `#[When(env: test)]` attribute and convert that into, effectively, a `#[Service(profiles: ['test'])]` definition.

Show thread

One of the "bells & whistles" feature of Annotated Container I'm interested in is the ability for apps to implement their own custom Attributes. For example, you could implement ` #[Controller]` Attribute that acts as a shared service but additional static analysis tools could detect if any #[Controller] instances are dependencies in _other_ services.

This also would allow you to implement your own Attribute API if you don't like what I've come up with.

Annotated Container's next few releases are planned out, with actual themes for what I want to accomplish instead of "just make it work right"!


Next up is improving the way backing libraries are implemented. After that, I'm planning on adding a lot more options for Container implementations to install.

Yesterday I wrote a library for documenting Architectural Decisions with Attributes. I feel like this kind of construct could be useful in documenting why your codebase is the way it is. Being able to annotate parts of your codebase should make it easier to remember those decisions for existing devs or learn about them for new devs.


Nearly finished up with a CLI tool that will allow easily integrating with Annotated Container.

It'll `init` a configuration file that defines which directories to scan. Default scan directories include anything setup in your composer.json autoload and autoload-dev.

You can `build` a ContainerDefinition and cache the result. A `cache clear` command lets you blow that away.

One I'm most excited about is `inspect` which will allow you to see all the Services, Injects, etc. that AC parsed.

I wrote a Psalm plugin to make sure I'm marking classes as final correctly.


It also appears that parsing 1 relatively large codebase takes much longer than many smaller codebases. Annotated Container parses many small codebases, has 10x as many tests, and has never taken 9s to run tests.

Show thread

Dog-fooding Annotated Container and found a small bug with caching a ContainerDefinition. I get it fixed and implement caching in the app I'm working on. Tests went from taking 9.0s to 0.4s.


I knew that parsing a codebase to figure out all the Attributes was gonna be expensive but I wasn't expecting that much.

cspray boosted

@cspray the more I see of this project the more excited I get.

I miss my old dic and this just might be the modernization it needed

Nothing quite like eating your own dog food and actually enjoying the taste.

One of the features I think is gonna get a lot of mileage, at least in my own projects, is the way Annotated Container handles injecting non-object values.

class Foo {

public function __construct(
#[Inject('BAR', from: 'env')]
string $baz
) {}


The value from `getenv('BAR')` will be injected at runtime. You can define your own values to use in `from` and have complete runtime control of what non-object gets injected into a service.

I released 1.0 of Annotated Container last week. I also just posted Part 2 introducing the framework!


The article details how to handle multiple concrete services for the same interface, injecting non-object values, and integrating with third-party code that can't be annotated!

One of the features I might try to get into the pre-1.0 Annotated Container is the idea of a proxy service. Using github.com/Ocramius/ProxyManag I could have Annotated Container support this concept pretty easily I think.

In the example the database URL would automagically get injected from the corresponding environment variable.

Show older
PHP Community on Mastodon

Open source. Open community. We are dedicated to building and enriching the PHP community.