Skip to content

More updates for "Type-based" injection #7906

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 10 commits into from
Closed

More updates for "Type-based" injection #7906

wants to merge 10 commits into from

Conversation

weaverryan
Copy link
Member

Apologies for another big PR, and also if I'm stepping on anyone else's feed - I'm just trying to charge through and make all the changes to the docs. This contains 2 things:

  1. More updates to entries to favor type-based injection (type-hinting and relying on autowiring) over manually configuration. I have more chapters to do still, but I'm mostly done.

  2. Important updates (mostly to service_container.rst) now that we're importing all of src/AppBundle in services.yml (Making *all* classes in src/AppBundle available as services symfony-standard#1070). Side note: wooohooo!!!

P.S. I deleted one entry that I thought was really poor and unnecessary.

Copy link
Member

@javiereguiluz javiereguiluz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ryan, thanks for this nice PR. The way you added small tips and help notes for those not using autoconfigure is great and I think people won't have any trouble finding the new docs. Thanks!

implements ``TokenAuthenticatedController``, token authentication is
applied. This lets you have a "before" filter on any controller that you
want.
If your subscriber id *not* called on each request, double-check that
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

id -> is

First, add a ``__construct`` method to ``GenderType``, which receives the gender
configuration::
If you need to access :doc:`services </service_container>` from your form class,
just a ``__construct()`` method like normal::
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just -> use

The ``extended_type`` key of the tag is the type of field that this extension should
be applied to. In your case, as you want to extend the ``Symfony\Component\Form\Extension\Core\Type\FileType``
field type, you will use that as the ``extended_type``.
The ``extended_type`` key of the tag must match the class you're returning from
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks wrong. Why repeat in extended_type exactly the same information I configured in getExtendedType() method? One of those two should be gone.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I completely agree. But, that's the way the feature is built currently - I just double-checked it. I think that getExtendedType() should be static and this extended_type should not be needed (exactly how an event subscriber works).

@@ -71,36 +71,41 @@ Alternatively, you can define your form class as a service. This is a good idea
you want to re-use the form in several places - registering it as a service makes
this easier.

Suppose you need to access the ``doctrine.orm.entity_manager`` service so that you
Suppose you need to access the ``EntityManager`` service so that you
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All this is still confusing to me but ... is this statement correct? --> [...] the EntityManager service [...]

If I execute ./bin/console debug:container --types I see this:

 --------------------------------------------  ------------------------------------------------
  Service ID                                   Class name
 --------------------------------------------  ------------------------------------------------
  Doctrine\Common\Annotations\Reader           alias for "annotations.cached_reader"
  Doctrine\Common\Persistence\ManagerRegistry  alias for "doctrine"
  Doctrine\Common\Persistence\ObjectManager    alias for "doctrine.orm.default_entity_manager"
  Doctrine\DBAL\Driver\Connection              alias for "doctrine.dbal.default_connection"

So there's no "EntityManager service", right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is also an EntityManagerInterface result:

Doctrine\ORM\EntityManagerInterface             alias for "doctrine.orm.default_entity_manager"

But you're right. Saying:

I need to access the EntityManagerInterface service

sounds weirder. Technically the concrete instance is EntityManager, but it's true that you don't see that unless you specifically look at the details for doctrine.orm.default_entity_manager.

So there's no "EntityManager service", but there is an EntityManager object in the container... which is what the user wants (and this is a service).

Anyways, I've made a change, let me know what you think - we should continue tweaking. I think it's important because we need to be able to find clear language to explain things, otherwise there's a problem :)

Next, register this as a service and tag it with ``form.type``:
If you're using :ref:`autowire <services-autowire>` and
:ref:`autoconfigure <services-autoconfigure>`, then you don't need to do *anything*
else: Symfony will automatically know to pass the entity manager service to your
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here again: "the entity manager service"

// But % does need to be escaped
$container->setParameter('url_pattern', 'http://symfony.com/?foo=%%s&amp;bar=%%d');

.. code-block:: yaml
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This empty code-block should be removed.

@weaverryan
Copy link
Member Author

Thanks for the review Javier and the nice words about the notes! I was hoping to have a sanity check from someone else on the clarity :).

@weaverryan weaverryan deleted the more-types-round2 branch May 16, 2017 10:49
Copy link
Contributor

@GuilhemN GuilhemN left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's really great! I missed it so didn't review it before :)

``data_collector``:
If you're using the :ref:`default services.yml configuration <service-container-services-load-example>`
with ``autoconfigure``, then Symfony will automatically see your new data collector!
Your ``collect()`` method should be called next time your refresh.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you

http://symfony.com/schema/dic/services/services-1.0.xsd">
The documentation assumes you're using
`Symfony Standard Edition (version 3.3) services.yml`_ configuration. The most
important part is this:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we're using actions with services as arguments almost everywhere, isn't the controller part important too?


No problem! Just add a ``__construct()`` function to ``TaskType`` and force this
to be passed in by registering ``TaskType`` as a service::
Next, you need to use the ``IssueToNumberTransformer`` object inside if ``TaskType``
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

of


// ...
public function editAction($id, Request $request)
public function editAction($id, Request $request, EntityManagerInterface $e,)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

too many commas :)

$container->loadFromExtension('monolog', array(
'handlers' => array(
'file' => array(
'type' => 'stream',
'level' => 'debug',
'formatter' => 'my_formatter',
'formatter' => JsonFormatter::class',
Copy link
Contributor

@GuilhemN GuilhemN May 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use statement missing (it is documented in config.php, a few lines above).

$event = new FilterBeforeSendEvent($foo, $bar);
$this->dispatcher->dispatch('foo.pre_send', $event);
// dispatch an event before the method
$event = new BeforeSendMailEvent($subject, $message);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BeforeSendingMailEvent would be better, but regarding the "real" event name what about PreSendMailEvent?


// the real method implementation is here
$ret = ...;

// do something after the method
$event = new FilterSendReturnValue($ret);
$this->dispatcher->dispatch('foo.post_send', $event);
$event = new AfterSendMailEvent($ret);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, AfterSendingMailEvent would be better.

@@ -385,7 +352,7 @@ class, you can simply call::
}
}

You can also easily embed the form type into another form::
You can also embed the form type into another form::
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra space.

@@ -15,7 +15,7 @@ a very special object called the **service container**. If you have the service
then you can fetch a service by using that service's id::

$logger = $container->get('logger');
$entityManager = $container->get('doctrine.entity_manager');
$entityManager = $container->get('doctrine.orm.entity_manager');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be backported in 2.7.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #8228.

automatically removed from the final container. In reality, the import simply
means that all classes are "available to be *used* as services" without needing
to be manually configured.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could also note that value object classes with type hinted constructor should be explicitly excluded to avoid issues at compile time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants