Git Product home page Git Product logo

Comments (5)

mabar avatar mabar commented on May 26, 2024

Your steps to reproduce show only extension registration, but not extension config, do you use any?

redis_client_factory > prefix is nullable, but redis_client_factory is not. Minimal configuration in your case should be:

foo:
  redis_client_factory:
    replication: []

By default is only structure required(), other Expect:: methods expect value only optionally.
When field is not required, it is null by default.
If null should be posible to pass explicitly (not just by default), field must be made nullable.
In compound types (arrayOf, listOf, anyOf), required() has any effect only on root element (because list/array values are validated only when exist, I am not sure about required() on an element in anyOf)

With these presumption, your minimal configuration should create following structure:

stdClass(
  redis_client_factory: stdClass(
    prefix: null
    replication: stdClass(
      service: null
      sentinels: null
    )
  )
)

Always use either nullable() or required() if you want to be sure

from di.

rootpd avatar rootpd commented on May 26, 2024

In this scenario, I didn't use any extra configuration for extension. But thanks for the clarification of the nullable and required, it was helpful.

What's more important, your comment made me realize, that this fails at the different place than I thought.

Internally, we set extra parameters to the application configuration based on the extension configuration:

public function loadConfiguration()
{
    $builder = $this->getContainerBuilder();

    // set extension parameters for use in config
    $builder->parameters['redis_client_factory'] = $this->config->redis_client_factory; // this is now stdClass

    // ...
}

Then we let other extensions to use %redis_client_factory.prefix% parameter.

So what actually happened was, that we made one of the config parameters stdClass and then tried to access one of its properties (prefix; see $var on the screenshot), which was null.

image

So the question is different.

  • Is this the expected/valid behavior? If the parameter is stdClass and the property exists, but it's null, should this be a "missing parameter" exception?
  • Or is having parameter of type stdClass completely wrong approach from our side?

from di.

mabar avatar mabar commented on May 26, 2024

Extension configuration can be get this way:

foreach ($this->compiler->getExtensions(FooExtension::class) as $extension) {
	$extension->getConfig();
}

Alternatively, you could get extension the same way and call some public method on it.

In an extension, parameters are already inlined where they were passed, so any changes to them will affect only extensions that access parameters directly and parameters in generated DIC. Also having an object in parameters was never expected, so that is probably why you got an exception.

Personally, I don't like extensions configuring each other, it can mess up really easy. Instead, do most of the config in neon, if it's not more complicated than in extension. Even vendor packages can have neon files, just add them via Configurator as usual.
In more complicated cases is sufficient rule to register services in loadConfiguration() in extension A and modify these services (received via $this->getContainerBuilder()->findByType()) in beforeCompile() in extension B

from di.

mabar avatar mabar commented on May 26, 2024

But you are right the condition is wrong. It should throw objects are not supported. Ideally I think builder parameters should be marked @readonly because only ParametersExtension should write into that property.

from di.

rootpd avatar rootpd commented on May 26, 2024

Thanks for the hints. I had a hunch that what I do is not the cleanest approach in the world, so we'll just try to amend it on our side.

The rest (@readonly for parameters, exception if not-supported stdClass is found in the parameters) sounds reasonable to me. It would make the expectations explicit and easier to understand.

from di.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.