0

I am currently developing a symfony application in which I want to have loose coupling of the business logic and the framework. I don't want to depend on the whole symfony framework and may be able exchange the framework later (and run my business logic outside of a bundle).

The Symfony DI Container is an independent component, which may be used without the whole symfony framework. So I basically can handle my dependencies with this component (in a yml file, via PHP, etc.).

Assume, I want to configure the dependencies with annotations using the JMSDiExtraBundle. Is there any possibility to use this bundle outside of an symfony application? If not, what may be the best option, to handle my dependencies? I would like to use annotations :)

  • Configure the Container with PHP, Yaml or anything else and work without annotations
  • Use another DI Container in combination with the Symfony one, which offers annotations (e.g. PHP-DI)
  • Do not build the applicatoin independently from symfony and don't ever exchange the framework.
Matthieu Napoli
  • 48,448
  • 45
  • 173
  • 261
Markus
  • 333
  • 4
  • 11

1 Answers1

1

Author of PHP-DI here. Is there a reason why you want to keep Symfony's container?

You said you would be open to use PHP-DI with Symfony's container, so FYI there's an integration possible with the documentation available here. However I don't think it will suit you because it's an integration with the whole Symfony framework. If you want to know how it works, check out the GitHub project.

Now another solution, which might be better, would be to use both Symfony's container and PHP-DI. You can use Acclimate for that. Here is a quick example (not tested):

$sfContainer = /* ... */;
$phpdiContainer = /* ... */;

// Adapt Symfony's container. PHP-DI doesn't need this because it is compliant with
// Container Interop https://github.com/container-interop/container-interop
$acclimator = new ContainerAcclimator;
$sfContainer = $acclimator->acclimate($sfContainer);

$container = new CompositeContainer([$sfContainer, $phpdiContainer]);

Here, the composite container ($container) will first look for services in Symfony's container, then in PHP-DI's container.

Now the trick is that each container don't know about the other one. So if you use PHP-DI's annotations, you can't inject Symfony's services. But PHP-DI is awesome (hell yeah :p) so you can make it aware of the parent container (which is the composite container) using ContainerBuilder::wrapContainer():

$container = new CompositeContainer();

// Add Symfony's container
$container->addContainer($acclimate->adaptContainer($symfonyContainer));

// Configure PHP-DI container
$builder = new ContainerBuilder();
$builder->wrapContainer($container);

// Add PHP-DI container
$phpdiContainer = $builder->build();
$container->addContainer($acclimate->adaptContainer($phpdiContainer));

// Good to go!
$foo = $container->get('foo');

This is taken from PHP-DI's documentation.

Now all is good in the world. The only problem left is that Symfony doesn't know PHP-DI's services, but Symfony's container don't have an equivalent feature, so there's no way around that (that's too bad). In my experience, I don't find it a big problem.

But all in all, I would advise you to use only PHP-DI and everything will be much simpler.

Matthieu Napoli
  • 48,448
  • 45
  • 173
  • 261