Annotation loader

2 views
Skip to first unread message

Loïc Frering

unread,
Jan 20, 2010, 7:53:20 AM1/20/10
to symfony-c...@googlegroups.com
Hello,
I recently developed an additional loader for the Service Container: ServiceContainerLoaderAnnotations. You can check my post about it and the code on my Bitbucket.

The code can still be improved but I would be pleased to contribute this development and his evolutions to the Dependency Injection component if this functionality seems pertinent to you.

Best regards,

--
Loïc Frering
loic.f...@gmail.com

Bernhard Schussek

unread,
Jan 22, 2010, 9:39:44 AM1/22/10
to symfony-c...@googlegroups.com
Hi Loïc,

Your blog post looks very interesting! (some Spring inspiration there? :) )

I will try it out.

Bernhard

Jordi Boggiano

unread,
Jan 22, 2010, 10:05:14 AM1/22/10
to symfony-c...@googlegroups.com
On 20.01.2010 13:53, Loïc Frering wrote:
> I recently developed an additional loader for the Service Container:
> ServiceContainerLoaderAnnotations. You can check my post about
> it [...]

This is interesting, and I must say more elegant than the YAML
declaration imo, since it is self-documenting code. On the other hand,
you don't have one centralized point where to define everything, which
could be a handicap in some situations.

The only point that is not clear to me, is how to have different service
container definitions, i.e. for development, production, testing. Since
the definition is part of the code, it seems to me that it is rather
static, but maybe I overlooked something ?

Cheers,
Jordi

signature.asc

Loïc Frering

unread,
Jan 22, 2010, 10:28:01 AM1/22/10
to Symfony Components
Thanks Bernhard.
That's actually inspired by Spring and the recent JSR330 ;)

Lukas Kahwe Smith

unread,
Jan 22, 2010, 10:32:09 AM1/22/10
to symfony-c...@googlegroups.com

On 22.01.2010, at 16:05, Jordi Boggiano wrote:

> On 20.01.2010 13:53, Loïc Frering wrote:
>> I recently developed an additional loader for the Service Container:
>> ServiceContainerLoaderAnnotations. You can check my post about
>> it [...]
>
> This is interesting, and I must say more elegant than the YAML
> declaration imo, since it is self-documenting code. On the other hand,
> you don't have one centralized point where to define everything, which
> could be a handicap in some situations.

yeah .. well i guess one could still check the cached implementation.

> The only point that is not clear to me, is how to have different service
> container definitions, i.e. for development, production, testing. Since
> the definition is part of the code, it seems to me that it is rather
> static, but maybe I overlooked something ?


i guess what would be cool is to have this be the default, which is combined with a parameters yaml and all of which can be overloaded for other environments.

regards,
Lukas Kahwe Smith
m...@pooteeweet.org

Jordi Boggiano

unread,
Jan 22, 2010, 10:49:17 AM1/22/10
to symfony-c...@googlegroups.com
On 22.01.2010 16:32, Lukas Kahwe Smith wrote:
> i guess what would be cool is to have this be the default, which is combined with a parameters yaml and all of which can be overloaded for other environments.

Indeed that sounds like a good compromise, annotations with yaml override.

Cheers,
Jordi

signature.asc

Loïc Frering

unread,
Jan 22, 2010, 10:50:10 AM1/22/10
to Symfony Components
Hello Jordi, hello Lukas,

Thanks for your feedbacks!

Concerning the environment management, as said Lukas, your annotation
definition can be the default definition of your service container.
You can override the services definition by loading others environment
specific definition files after the annotation loader did his job.
Then the later definition for an identified service will override the
previous one.

Another solution would be to load different paths to the annotation
loader depending on the environment. For example:

$loader = LoSo_Symfony_Components_ServiceContaineAnnotationsLoader
($container);
$loader->load('/root_path/' . $env . '/classes_directory');

Regards,
Loïc Frering

Jordi Boggiano

unread,
Jan 22, 2010, 10:58:51 AM1/22/10
to symfony-c...@googlegroups.com
On 22.01.2010 16:50, Loïc Frering wrote:
> Concerning the environment management, as said Lukas, your annotation
> definition can be the default definition of your service container.
> You can override the services definition by loading others environment
> specific definition files after the annotation loader did his job.
> Then the later definition for an identified service will override the
> previous one.

Ok I wasn't aware of that, then it sounds easy enough to override parts
of the stuff with the Yaml parser.

> Another solution would be to load different paths to the annotation
> loader depending on the environment. For example:

Aye, I thoguht about that, it would probably work for tests which can be
self-contained, but we have quite some differences in service
definitions for production and development at the moment, and we can't
just copy paste half the code to have different parameters. Speaking of
which, and sorry if I miss the obvious but it's friday, how do you pass
parameters to a service ? I got how your stuff works for
cross-dependencies between services, but if I want to inject a string or
int or an array into a constructor, how is that done? Because for that
yaml is pretty handy.

Cheers,
Jordi

signature.asc

Geoffrey Bachelet

unread,
Jan 22, 2010, 11:18:09 AM1/22/10
to symfony-c...@googlegroups.com
Overriding annotations with yaml sounds weird to me :/

Wouldn't it be possible to have something like that:

/**
 * @Service(env=prod) myService
 */
class MyServiceForProd
{
}

Or am I missing something ?

You could then standardize annotations (syntax purely an e.g.):

@Service(env=prod, name=myservice)

The point is if I decide to use the Annotation parser, that's because I don't want to use the YAML parser, so why force me to use it ?

Lukas Kahwe Smith

unread,
Jan 22, 2010, 11:29:04 AM1/22/10
to symfony-c...@googlegroups.com

you dont want to change your code just because you add a new env. imagine if symfony core code would do this.
i think its quite logical .. maybe the better approach would be to generate the yaml from the code?

Loïc Frering

unread,
Jan 22, 2010, 12:11:55 PM1/22/10
to symfony-c...@googlegroups.com
Jordi, I planned to add an @Property annotation support to inject properties into parameters or methods. By the way I still have to think about how to manage constructors or if I use the @Inject annotation with a particular parameter... Concerning the environment dependent path, I indeed mentioned it for completely different implementations of a service, for mocking purpose for example.

Geoffrey, I quite agree with Lukas: your classes implementation should not be environment dependent, just the configuration should depend on the environment. Then the @Property mentioned above annotation should do the trick to configure your services according to your environment.

Regards.

--
You received this message because you are subscribed to the Google Groups "Symfony Components" group.
To post to this group, send email to symfony-c...@googlegroups.com.
To unsubscribe from this group, send email to symfony-compone...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/symfony-components?hl=en.




--
Loïc Frering
128, rue Marius Berliet
69008 Lyon
0 954 954 786
06 48 08 67 79
loic.f...@gmail.com

Loïc Frering

unread,
Jan 23, 2010, 10:24:41 AM1/23/10
to symfony-c...@googlegroups.com
Hello guys,
I added support to an @Value annotation for parameters support with annotations. If you use @Value without description, the parameter identifier will be automatically determined. You can also explicitly define the parameter identifier: @Value %mail.transport%.

You can check the code on my Bitbucket, do not hesitate to provide feedbacks :)

Here's an example:
  • In services.yml:
parameters:
  foo: bar

  • In TestService.php:
<?php
/**
 * @author Loïc Frering <loic.f...@gmail.com>
 * @Service
 */
class Default_Service_TestService
{
    /**
     * @var string
     */
    protected $_foo;

    /**
     * @var Default_Service_TestService2
     */
    protected $_testService2;

    /**
     * @param string $foo
     * @return Default_Service_TestService
     * @Value
     */
    public function setFoo($foo)
    {
        $this->_foo = $foo;
        return $this;
    }

    /**
     * @param Default_Service_TestService2 $testService2
     * @return Default_Service_TestService
     * @Inject
     */
    public function setTestService2($testService2)
    {
        $this->_testService2 = $testService2;
        return $this;
    }
    

    public function test()
    {
        return 'Test method from TestService. foo = ' . $this->_foo . '.';
    }

    public function test2()
    {
        return $this->_testService2->test2() . ' called from testService. foo = ' . $this->_foo . '.';
    }
}

Cheers

Reply all
Reply to author
Forward
0 new messages