auryn icon indicating copy to clipboard operation
auryn copied to clipboard

Configuration writer for production

Open ascii-soup opened this issue 12 years ago • 5 comments
trafficstars

With the new file-based configuration options becoming available, it might be nice to add a feature for development that uses the standard reflection-based auto-wiring and then writes out the equivalent configuration for increased performance in production (and for actual-dependency discovery purposes).

ascii-soup avatar Jul 09 '13 12:07 ascii-soup

I agree. The only thing to be aware of with this is that Closure delegates cannot be serialized. Granted, there's little need to use lambdas for your delegates because the Provider essentially turns SomeClass::__invoke into a string version of a closure via its auto-instantiation and provisioning. The possibility exists, though, and would prevent you from dumping the configuration into a JSON file since array and string values can't be extrapolated for a Closure.

Also, this is somewhat related to the (currently unpushed) ApcProviderBuilder which caches the fully populated Provider instance in-memory so that it doesn't have to be constructed and populated on each application request (in web environments).

rdlowrey avatar Jul 09 '13 16:07 rdlowrey

I see what you mean about closures, but delegates have to be defined manually anyway, right? I just mean that any time the Provider "auto-wires" a dependency (reflection during "make" call, basically), it could spit out a quick define() call that mimics what it's just done. Or am I continuing to misunderstand?

ascii-soup avatar Jul 09 '13 16:07 ascii-soup

If I understand what you're asking (I may not) ...

No, the delegates can be just as automatic as any of the other Provider settings because they are lazily executed by Provider::execute as needed. So you could do the following instead of a closure delegate:

<?php
class Car {}
class SomeDependency {}
class MyCarFactory {
    private $someDependency;
    function __construct(SomeDependency $someDep) {
        $this->someDependency = $someDep;
    }
    function __invoke() {
        return new Car;
    }
}

$provider = (new Provider)->delegate('Car', 'MyCarFactory');

This could easily be dumped by a ConfigurationWriter to JSON as:

{
    "delegates": {
        "Car":"MyCarFactory"
    }
}

A closure, for obvious reasons, cannot be dumped to a JSON file. Though I guess since the point of the ConfigurationWriter would be to improve performance you'd often want to dump to a PHP file in which it would be perfectly possible to store the Closure.

It's probably a better bet to avoid the Closure altogether, though, because by dumping to JSON (or XML or whatever) you'd have your dependency graph represented in a standardized text-format and would be able to manipulate it for any visualizations you wanted.

rdlowrey avatar Jul 09 '13 16:07 rdlowrey

Ah, yes, I think we are talking about slightly different things.

I mean the following:

<?php

class Car {}
class SomeDependency {}

class Porsche
{
    function __construct(Car $car, SomeDependency $someDep) {}
}

$porsche = (new Provider)->make('Porsche');

There is no manual configuration here, it's all done via reflection due to concrete type hints.

It would be nice if this could output (somewhere, configurable, etc):

<?php

$configuration = array(
    'definitions' => array(
        'Porsche' => array(
            'car' => 'Car',
            'someDep' => 'SomeDependency'
        )
    )
);

The only real reason for this is so that dependencies can easily be written into the configuration during development. If you need to delegate() or alias() or anything, you need to do that by calling the appropriate methods on the provider anyway, however you don't necessarily need to write that down with make()

Just a handy tool for developers. It could potentially be added as some kind of "plugin" or "extension" maybe.

ascii-soup avatar Jul 10 '13 10:07 ascii-soup

Ah I see what you mean now. I'll see what I can do in the next couple of days if I have some spare time about doing something like this. Probably something to the effect of ...

void ConfigurationWriter::export(Provider $provider, string $saveToPath, string $format = 'php')

The optional format specifier would allow you to export to JSON (or any other formats supported in the future) and if you're dumping to a text format have closure delegates then you'd get an exception.

I'd probably just use reflection to access the private properties of the Provider instance passed in.

Lemme know if you have any other thoughts on this.

rdlowrey avatar Jul 10 '13 11:07 rdlowrey

I'll see what I can do in the next couple of days ... Lemme know if you have any other thoughts on this.

I think I'm going to close this issue before a decade has passed.

Danack avatar Apr 17 '23 13:04 Danack