Giter Club home page Giter Club logo

Comments (6)

philipobenito avatar philipobenito commented on September 2, 2024 1

@mrtus yeah, the bootable service provider is where your big hit is going to come from, but I understand it can be quite annoying if you miss something in provides, the approach with that was really to try and provide a balance, it's less convenient, but allows for lazy loading which hugely improves performance for big applications, as it will only ever define what is needed in the current process.

Hope that gives you a little context on it.

The compiled container is my main priority for the package right now, but I may also look at how I might improve the iteration of definitions, storing against keys is unfortunately not the answer, as it doesn't solve the problem of knowing what's defined directly with the container and what is in a service provider, all about balance again with that, but may be able to squeeze some more performance out of it somewhere.

I'll close this as you mentioned but I'll pop a comment here when I have have something you can play with with the compiler, your app might actually be a great test case if it's big.

from container.

philipobenito avatar philipobenito commented on September 2, 2024 1

Yeah you'd sort of just be moving the problem with that, reflection performance may well be just as bad with that many definitions.

It is kind of a no win choice, convenience vs performance :-(

from container.

philipobenito avatar philipobenito commented on September 2, 2024 1

Saying that though, you'd only actually be reflecting on what's needed in the process, so you may be better off, you'd lose any and all customisation options that way though

from container.

philipobenito avatar philipobenito commented on September 2, 2024

Hi, for now, yes, your own implementation would be my suggestion.

However, I'm working on a new feature that will allow you to compile the container ready for production, that will generate a container implementation that just instantly instantiates what you want, based on what you have defined. I've had some health issues recently so development has been slow, but hoping it's only a couple of months out.

from container.

mrtus avatar mrtus commented on September 2, 2024

Hi @philipobenito

Thank you for your swift reply!

I'm already more than happy with your quick answer confirming my proposal.

A precompiled definition set sounds awesome, I'm eager to see what it becomes!


I'll provide some insights as well on how we use the container since those are always valuable :)

We generally only use the ->addShared method with a callback as second argument which can instantiate the argument, it is super simple to use.

We also use BootableServiceProviderInterface to avoid having to define everything on the provides method (I realise that this is probably the main reason that we have such a big performance impact), it is that, or running into mistakes because a service was not exposed.

We also wrote a test that can find all definitions and checks if it can actually construct those instances (part of avoiding those other mistakes that can happen 😄)

Container factory test
final class ContainerFactoryTest extends TestCase
{
	private static ?Container $container = null;

	public static function getContainer(): Container
	{
		if (self::$container === null) {
			self::$container = ContainerFactory::load();
		}

		return self::$container;
	}

	/**
	 * @test
	 * @dataProvider dataProvider
	 */
	public function itShouldProvide(string $class): void
	{
		$actual = self::getContainer()->get($class);

		if (class_exists($class)) {
			$this->assertInstanceOf($class, $actual);
		}

		$this->assertNotNull($actual);
	}

	public function dataProvider(): array
	{
		$classes = [];
		foreach ($this->getAllContainerDefinitions() as $definition) {
			$classes[$definition->getAlias()] = [$definition->getAlias()];
		}

		return $classes;
	}

	/**
	 * @return DefinitionInterface[]
	 */
	public function getAllContainerDefinitions(): iterable
	{
		/** @var DefinitionAggregateInterface $providerAggregate */
		$providerAggregate = $this->getPrivateProperty(self::getContainer(), 'definitions');

		return $providerAggregate->getIterator();
	}

	public function getPrivateProperty($class, string $propertyName)
	{
		$property = new ReflectionProperty($class, $propertyName);

		$property->setAccessible(true);

		return $property->getValue($class);
	}
}

PS. Feel free to close this issue as you see fit.

I wish you a speedy recovery @philipobenito!

from container.

mrtus avatar mrtus commented on September 2, 2024

Yes, I was making the same conclusion about the provides, I understand the use of the provides but it also is a hell in maintenance. Maybe we are simply not conditioned enough as developers to actually use it 🙈.
We stepped away from it because we caused a couple of incidents with our app a couple of years back, because of missing definitions, hence also the additional container factory test.

Some more details then;
At boot we have about ~600 dependencies configured.

Additional service can be added dynamically as well (which won't be solvable through a compiler) and will always be created through reflection and auto-wiring.

Taking a look at ReflectionContainer the cacheResolution could be a solution, also with tags. Although maybe that is a bandaid on a different problem 😁.

from container.

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.