Service Location in ZF (ServiceLocator/InstanceManager RFC)

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Service Location in ZF (ServiceLocator/InstanceManager RFC)

ralphschindler
Hey All,

I've talked about this for a while, but last week myself and Matthew sat
down and took my existing ServiceLocator proposal and code-base and
built it into the ZendSkeletonAppliaction to see what things looked like.

For background, the RFC is here:
http://framework.zend.com/wiki/display/ZFDEV2/RFC+-+ServiceLocator

The reason for my pushing this is that I feel (and have always felt), a
solid DiC solution should be opt-in and not an implementation detail of
a default application stack.  This is primarily due to the complexity of
seeding any DiC with the relevant information it requires to know HOW to
go about making instances.  I'll leave it at that, if someone has
questions as to why, we can do this in a separate thread.

Moving onward, the goals of a Service Location approach are simple:

   * easier to write new services
   * simpler configuration files
   * easier to understand how existing services are wired
   * hand-written code will be faster than hand written di configs

Matthew and I feel like these have been achieved, and we'd like to share
those ideas with the community, perhaps gain approval, and make this the
default/minimal "instance management" infrastructure for ZF2 applications.

(Note that the component name has changed from Zend\ServiceLocator to
Zend\InstanceManager.  If it makes sense we can update the name inside
the RFC, although I am unsure if that is necessary.)

Next, have a look at 3 things:

   * the InstanceManager implementation along with the ServiceLocator RFC

     branch:
https://github.com/weierophinney/zf2/tree/feature/instancemanager

     code:
https://github.com/weierophinney/zf2/tree/feature/instancemanager/library/Zend/InstanceManager

   * The changes to Zend\Mvc

     code:
https://github.com/weierophinney/zf2/tree/feature/instancemanager/library/Zend/Mvc

   * and finally, the App Skeleton

     code:
https://github.com/weierophinney/ZendSkeletonApplication/tree/feature/instance-manager

This branch of the Skeleton Application works against the above
mentioned branch of ZF2.

Without being super long winded in this email, I'd offer for everyone to
examine the code and the RFC and start a dialog.  In short, this
implementation of the instance manager solves these immediate problems
we've become aware of:

   * use closures as instance factories (similar to Pimple)
   * promote configuration as a service
   * instance aliases for resolving naming differences between modules
   * has facilities for "scoped container": the controller as a service
problem

All that said ... let's start a discourse on it,

Thanks!
Ralph Schindler







Reply | Threaded
Open this post in threaded view
|

Re: Service Location in ZF (ServiceLocator/InstanceManager RFC)

xoops
Thank you!
You solve the problems that stopped us from using Di component.

On Mon, Apr 9, 2012 at 9:42 PM, Ralph Schindler <[hidden email]> wrote:
Hey All,

I've talked about this for a while, but last week myself and Matthew sat down and took my existing ServiceLocator proposal and code-base and built it into the ZendSkeletonAppliaction to see what things looked like.

For background, the RFC is here:
http://framework.zend.com/wiki/display/ZFDEV2/RFC+-+ServiceLocator

The reason for my pushing this is that I feel (and have always felt), a solid DiC solution should be opt-in and not an implementation detail of a default application stack.  This is primarily due to the complexity of seeding any DiC with the relevant information it requires to know HOW to go about making instances.  I'll leave it at that, if someone has questions as to why, we can do this in a separate thread.

Moving onward, the goals of a Service Location approach are simple:

 * easier to write new services
 * simpler configuration files
 * easier to understand how existing services are wired
 * hand-written code will be faster than hand written di configs

Matthew and I feel like these have been achieved, and we'd like to share those ideas with the community, perhaps gain approval, and make this the default/minimal "instance management" infrastructure for ZF2 applications.

(Note that the component name has changed from Zend\ServiceLocator to Zend\InstanceManager.  If it makes sense we can update the name inside the RFC, although I am unsure if that is necessary.)

Next, have a look at 3 things:

 * the InstanceManager implementation along with the ServiceLocator RFC

   branch: https://github.com/weierophinney/zf2/tree/feature/instancemanager

   code: https://github.com/weierophinney/zf2/tree/feature/instancemanager/library/Zend/InstanceManager

 * The changes to Zend\Mvc

   code: https://github.com/weierophinney/zf2/tree/feature/instancemanager/library/Zend/Mvc

 * and finally, the App Skeleton

   code: https://github.com/weierophinney/ZendSkeletonApplication/tree/feature/instance-manager

This branch of the Skeleton Application works against the above mentioned branch of ZF2.

Without being super long winded in this email, I'd offer for everyone to examine the code and the RFC and start a dialog.  In short, this implementation of the instance manager solves these immediate problems we've become aware of:

 * use closures as instance factories (similar to Pimple)
 * promote configuration as a service
 * instance aliases for resolving naming differences between modules
 * has facilities for "scoped container": the controller as a service problem

All that said ... let's start a discourse on it,

Thanks!
Ralph Schindler










--

Taiwen Jiang (aka D.J.)

Build Xoops Engine
web and mobile application platform

CTO for EEFOCUS.com
Leading social platform for electronics professionals


Reply | Threaded
Open this post in threaded view
|

Re: Service Location in ZF (ServiceLocator/InstanceManager RFC)

Marco Pivetta (Ocramius)
In reply to this post by ralphschindler
tl;dr: nice component, but in some cases reduces functionality, and we need rules for that.

Hi Ralph,
As discussed yesterday with Matthew after you left, I just wanted to report you where the discussion got.
Overall, I think the InstanceManager is a very nice implementation. My only issues were with the ApplicationManager ( https://github.com/weierophinney/zf2/blob/feature/instancemanager/library/Zend/Mvc/ApplicationManager.php#L37 ) and the new module config ( https://github.com/weierophinney/ZendSkeletonApplication/blob/feature/instance-manager/module/Application/config/module.config.php )

1 - the ApplicationManager currently uses too many callbacks as factories, and that makes adding features to existing instance factories tricky, especially if you cannot do any assumptions about what the pre-existing closure does. That has been discussed, and what came out is that there's so many callbacks just to show off the InstanceManager usage.

2 - the new configuration for modules requires you to remember a lot of config keys that aren't explicitly set somewhere (some XSD or similar structure). I am probably insane (see  https://github.com/Ocramius/ZfPhpcrOdm/blob/master/config/module.config.php ), but I particularly liked the fact that with DiC only, configuration depends on a class' public interface. That is a lot less stuff to remember, and even if the DiC add some overhead, compiled InstanceManager configuration could get the job done. On the other side Matthew has a point when stating that ZF2 is comples. It is, it is VERY complex, but I fear that we are going to loose functionality to move in a position that is more near to RAD, which I didn't choose ZF2 for. I like ZF2's flexibility even if complex, and I'd love to see it simplified, but not by cutting out the "difficult" way (that is soo lovely flexible :) ).

Overall, as said, the main functionality (instancemanager + moving bootstrap into application) looks really nice. I'd like to have an abstract factory using the DiC as fallback factory (by default, as I still see the DiC as ZF2's main feature along with the event driven design). I see the instance manager more like the "!important" in CSS for now: solves some problems but makes it more difficult to restore the previous behavior, but maybe I'm just doing a mistake.

So, short said, I would still see the DiC instance factory as available by default (using $mergedConfig['di']), and try to keep these closures under control, they really scared me yesterday :)

Marco Pivetta

http://twitter.com/Ocramius     

http://marco-pivetta.com    



On 9 April 2012 15:42, Ralph Schindler <[hidden email]> wrote:
Hey All,

I've talked about this for a while, but last week myself and Matthew sat down and took my existing ServiceLocator proposal and code-base and built it into the ZendSkeletonAppliaction to see what things looked like.

For background, the RFC is here:
http://framework.zend.com/wiki/display/ZFDEV2/RFC+-+ServiceLocator

The reason for my pushing this is that I feel (and have always felt), a solid DiC solution should be opt-in and not an implementation detail of a default application stack.  This is primarily due to the complexity of seeding any DiC with the relevant information it requires to know HOW to go about making instances.  I'll leave it at that, if someone has questions as to why, we can do this in a separate thread.

Moving onward, the goals of a Service Location approach are simple:

 * easier to write new services
 * simpler configuration files
 * easier to understand how existing services are wired
 * hand-written code will be faster than hand written di configs

Matthew and I feel like these have been achieved, and we'd like to share those ideas with the community, perhaps gain approval, and make this the default/minimal "instance management" infrastructure for ZF2 applications.

(Note that the component name has changed from Zend\ServiceLocator to Zend\InstanceManager.  If it makes sense we can update the name inside the RFC, although I am unsure if that is necessary.)

Next, have a look at 3 things:

 * the InstanceManager implementation along with the ServiceLocator RFC

   branch: https://github.com/weierophinney/zf2/tree/feature/instancemanager

   code: https://github.com/weierophinney/zf2/tree/feature/instancemanager/library/Zend/InstanceManager

 * The changes to Zend\Mvc

   code: https://github.com/weierophinney/zf2/tree/feature/instancemanager/library/Zend/Mvc

 * and finally, the App Skeleton

   code: https://github.com/weierophinney/ZendSkeletonApplication/tree/feature/instance-manager

This branch of the Skeleton Application works against the above mentioned branch of ZF2.

Without being super long winded in this email, I'd offer for everyone to examine the code and the RFC and start a dialog.  In short, this implementation of the instance manager solves these immediate problems we've become aware of:

 * use closures as instance factories (similar to Pimple)
 * promote configuration as a service
 * instance aliases for resolving naming differences between modules
 * has facilities for "scoped container": the controller as a service problem

All that said ... let's start a discourse on it,

Thanks!
Ralph Schindler








Reply | Threaded
Open this post in threaded view
|

Re: Service Location in ZF (ServiceLocator/InstanceManager RFC)

akrabat
In reply to this post by ralphschindler

On 9 Apr 2012, at 14:42, Ralph Schindler wrote:
>
>  * use closures as instance factories (similar to Pimple)
>  * promote configuration as a service
>  * instance aliases for resolving naming differences between modules
>  * has facilities for "scoped container": the controller as a service problem
>
> All that said ... let's start a discourse on it,


An Initial look seems to suggest that the way we've been doing things so far in ZF2 is no longer the case and we have to learn a new way. I don't have a problem with this per-se, but it seems like a significant change of thinking will be required from using Zend\Di configuration.

Some questions:

How would you change the "wiring" now. E.g. If I want to write my own extension of Zend\View\Resolver\AggregateResolver, called AkrabatView\Resolver\AggregateResolver, how do I configure Application to use it? It looks like instantiating a  Zend\View\Resolver\AggregateResolver is hard coded in ApplicationManager?

This difficulty in overriding appears to be the same for all classes used within the Mvc layer now. I could be wrong, but it looks like you have to find the correct closure in ApplicationManager and copy/paste it somewhere else just so that you can change the "new" line (or the use statement). Obviously, some closures are trivial, but others aren't. Is this right?

Related, ApplicationManager::configureInstanceManager() is a very big method as a result of all those closures. Looks like scary code!

How do I get database configuration into the adapter config object when I get a TDG backed mapper from the InstanceManger? Do I have to write a separate closure that does this for every single mapper in my application? I've read "How do I get configuration into the various services?" section of the RFC and it seems that I have to write closures in multiple places? It's also unclear how it works when the config needs to go multiple levels down.

I'm unclear how configuration can be standardised?  Do we all have to agree on the same key in the config within config/autoload? This doesn't appear to be the case with InstanceManager as everyone has to write their own closure? At one point in the RFC, it talks about a "mailer" config key. Why is it called "mailer"? What happens if another module expect the same configuration to be called "mail"? It appears that config keys are now completely arbitrary. Will this make using modules from lots of different people harder as we have to go through each one we use and find out the conventions that have been used within it and map them to whatever we've used in our config/autoload files?

Finally, are we saying that if ZF2 is only for devs who are completely comfortable with closures? I see closures in the config files in the
RFC, so presumably INI, XML, JSON etc are now not usable for ZF2 configuration?


Maybe I'm just misunderstanding how easy this will be in practice. I'd really like to see a more complete application to get a feel for how a non-Zend\Di world looks as I can't work it out from the RFC as it seems very abstract and the Skeleton app is too trivial.


Regards,

Rob...

Reply | Threaded
Open this post in threaded view
|

Re: Service Location in ZF (ServiceLocator/InstanceManager RFC)

ralphschindler
In reply to this post by Marco Pivetta (Ocramius)
Hey Ocramius,

> 1 - the ApplicationManager currently uses too many callbacks as
> factories, and that makes adding features to existing instance factories
> tricky, especially if you cannot do any assumptions about what the
> pre-existing closure does. That has been discussed, and what came out is
> that there's so many callbacks just to show off the InstanceManager usage.

These should probably be service objects ultimate.  A closure can be
registered as a factory for any kind of instance though, as it is mainly
there to produce a instance.  The is effectively the same as the
InstanceFactory interface since that is a single method createInstance().

They could be either or, classes lend themselves to inheritance; but
closures lend themselves to performance (since there are fewer files to
include, etc).

> 2 - the new configuration for modules requires you to remember a lot of
> config keys that aren't explicitly set somewhere (some XSD or similar
> structure). I am probably insane (see
> https://github.com/Ocramius/ZfPhpcrOdm/blob/master/config/module.config.php
> ), but I particularly liked the fact that with DiC only, configuration
> depends on a class' public interface. That is a lot less stuff to

Yeah, I like this good ... but it requires all developers to write DI
friendly code, to understand the 3 main DI patterns.  What's even more
difficult is for jr. developer to understand the differences between
configuration, objects that are dependencies vs. objects that
collaborate in other ways.  At the end of the day, they all look the
same b/c they are essentially parameters to some method call somewhere.

> remember, and even if the DiC add some overhead, compiled
> InstanceManager configuration could get the job done. On the other side

This means ZF is slow out the box, and you're required to "compile"
something in order for it to be fast.  IN development, this means that
every time you change the interface to a class, a recompile needs to be
done.  THis also means that "compiling" needs to be a step in your
release process so that the application will work ... which means your
release process can't simply be "use FTP to upload the site".

See how things get incrementally complex?  I am ok with this, but I
wonder where this leaves jr. developers and people whom are just getting
started with building OO applications.  Where is our entry level?

> Overall, as said, the main functionality (instancemanager + moving
> bootstrap into application) looks really nice. I'd like to have an
> abstract factory using the DiC as fallback factory (by default, as I
> still see the DiC as ZF2's main feature along with the event driven
> design). I see the instance manager more like the "!important" in CSS
> for now: solves some problems but makes it more difficult to restore the
> previous behavior, but maybe I'm just doing a mistake.

I guess we have to determine how important the current problems are.  I
feel like complexity and performance of the current solution are
non-starters for me.  I think others feel the same way.

I am less likely to use something like Zend\Di when I can write a
service locator that achieves the same level of code organization in
just a few lines of code.

The question for me at that point is, how much added complexity do we
need to ensure that we build an environment where "modules" can flourish.


> So, short said, I would still see the DiC instance factory as available
> by default (using $mergedConfig['di']), and try to keep these closures
> under control, they really scared me yesterday :)



-ralph


Reply | Threaded
Open this post in threaded view
|

Re: Service Location in ZF (ServiceLocator/InstanceManager RFC)

ralphschindler
In reply to this post by akrabat

Hey Rob,

On 4/10/12 4:42 AM, Rob Allen wrote:

>
> On 9 Apr 2012, at 14:42, Ralph Schindler wrote:
>>
>> * use closures as instance factories (similar to Pimple) * promote
>> configuration as a service * instance aliases for resolving naming
>> differences between modules * has facilities for "scoped
>> container": the controller as a service problem
>>
>> All that said ... let's start a discourse on it,
>
>
> An Initial look seems to suggest that the way we've been doing things
> so far in ZF2 is no longer the case and we have to learn a new way. I
> don't have a problem with this per-se, but it seems like a
> significant change of thinking will be required from using Zend\Di
> configuration.

That's the nature of beta software no?  That said, you make a good point.

Consider this though: the current way of doing things might be a
non-starter for some people, and they have yet to begun writing ZF2
applications.  We still need to find the ideal way to go about building
applications in the ZF2 philosophy.

Di currently is a level of magic that I think scares people up-front. It
does auto-instantiation and auto-wiring of objects.  It does this based
off generally complex and in-depth configuration files (nested very
deeply in most cases).  Zend\Di has grown in significant complexity
because instead of writing simple, clear and rule based DI injectable
code, PHP developers want Zend\Di to work with the way they write code.
  This means more configuration for the tool to understand their code.
(Think how we have the injections keyword now).

> Some questions:
>
> How would you change the "wiring" now. E.g. If I want to write my own
> extension of Zend\View\Resolver\AggregateResolver, called
> AkrabatView\Resolver\AggregateResolver, how do I configure
> Application to use it? It looks like instantiating a
> Zend\View\Resolver\AggregateResolver is hard coded in
> ApplicationManager?

Ideally, those factories become classes, so the current
AggregateResolver wiring might look like this:

namespace Zend\Mvc\Application\Service {
   class ViewAggregateResolver {
     public function createService($im) {
       $map   = $im->get('TemplateMapResolver');
       $stack = $im->get('TemplatePathStack');
       $aggregate = new AggregateResolver();
       $aggregate->attach($map);
       $aggregate->attach($stack);
       return $aggregate;
     }
   }
}

Then, in the application.php configuration:

$application['service_classes']['AggregateResolver']
   = 'Akrabat\Service\ViewAggregateResolver';

This level of ApplicationManager and service configuraiton is not
demonstrated anywhere, but if the stock instances need to be overridden,
that can be achieved.

Keep in mind.  If we want a module ecosystem to flourish, they need to
have certain assurances that instances of a particular kind are
available, so swapping out your AggregateResolver means it probably has
to act very similarly to the one inside the stock application so that
they can have the same assurances of functionality.

> This difficulty in overriding appears to be the same for all classes
> used within the Mvc layer now. I could be wrong, but it looks like
> you have to find the correct closure in ApplicationManager and
> copy/paste it somewhere else just so that you can change the "new"
> line (or the use statement). Obviously, some closures are trivial,
> but others aren't. Is this right?

Correct, you write your own services.  InstanceManager is just like DI
with the exception that it does not do auto-instantiation or auto-wiring
or any of the tasks that are required to provide that functionality.  It
means you can get back to writing code, and not configuration.

You can still use DiC as an instance factory, but what IM provides you
is a place where you write the code that does the instantation and wiring.

> Related, ApplicationManager::configureInstanceManager() is a very big
> method as a result of all those closures. Looks like scary code!

Agreed.

> How do I get database configuration into the adapter config object
> when I get a TDG backed mapper from the InstanceManger? Do I have to
> write a separate closure that does this for every single mapper in my

The rule is basically this.  Start by writing the service you need.  In
the beginning, it will just be some kind of TableGateway perhaps.  Then,
as your application grows, you abstract out the services that need to be
shared.  So, for example, in the beginning, the new call to the database
connection might be burried inside the service that returns your
TableGateway object, but as more objects need a database connection,
then your database connection object becomes a service itself.

> application? I've read "How do I get configuration into the various
> services?" section of the RFC and it seems that I have to write
> closures in multiple places? It's also unclear how it works when the
> config needs to go multiple levels down.

You can use closures or classes.  It's up to you.  Or, you can make DiC
the source of your abstract factory and continue on like business as
usual where DiC was the core implementation.

Out the box though, we should be providing service classes so that DiC
doesn't have to scan code to understand how things are instantiated and
wired.

> I'm unclear how configuration can be standardised?  Do we all have to
> agree on the same key in the config within config/autoload? This

Yes.  We've already done that to some degree: people call
$di->get('Some\Class\Name'); or $di->get('SomeAlias');  We've just
agreed up front to use class names as the service names.

> doesn't appear to be the case with InstanceManager as everyone has to
> write their own closure? At one point in the RFC, it talks about a
> "mailer" config key. Why is it called "mailer"? What happens if
> another module expect the same configuration to be called "mail"? It

Naming is one of those key features provided by InstanceManager.

See this section:

http://framework.zend.com/wiki/display/ZFDEV2/RFC+-+ServiceLocator#RFC-ServiceLocator-Examples%3AUsageInsideModules

That is an all inclusive example, but if one module has a different
service naming from another, it should create an alias.

The target of the alias should be handled inside a configuration that
can be overridden.  This means that a module can use a name like
"mymodule_mailer" and it will always be mapped to whatever the
application calls its "mailer" instance.

> appears that config keys are now completely arbitrary. Will this make
> using modules from lots of different people harder as we have to go
> through each one we use and find out the conventions that have been
> used within it and map them to whatever we've used in our
> config/autoload files?

See above about aliases.  This is the exact problem this attempts to solve.

> Finally, are we saying that if ZF2 is only for devs who are
> completely comfortable with closures? I see closures in the config
> files in the RFC, so presumably INI, XML, JSON etc are now not usable
> for ZF2 configuration?

Closures or classes need to be invoked.  The classes need to be
invokable or an instance of InstanceFactoryInterface.  The code inside
the body is simple the instantiation and wiring code.

> Maybe I'm just misunderstanding how easy this will be in practice.
> I'd really like to see a more complete application to get a feel for
> how a non-Zend\Di world looks as I can't work it out from the RFC as
> it seems very abstract and the Skeleton app is too trivial.

Ok, ill get with matthew on this.

-ralph

Reply | Threaded
Open this post in threaded view
|

Re: Service Location in ZF (ServiceLocator/InstanceManager RFC)

akrabat
Hi Ralph,

Bits that I've snipped needed no further comment :)


On 11 Apr 2012, at 16:28, Ralph Schindler wrote:

> On 4/10/12 4:42 AM, Rob Allen wrote:
>>
>> An Initial look seems to suggest that the way we've been doing things
>> so far in ZF2 is no longer the case and we have to learn a new way. I
>> don't have a problem with this per-se, but it seems like a
>> significant change of thinking will be required from using Zend\Di
>> configuration.
>
> That's the nature of beta software no?  That said, you make a good point.

Definitely. The idea is that we learn what isn't working and fix it :)  I'm not knocking the concept.  I agree about DI being complex too and I hate it when I make a mistake in the config!



> Keep in mind.  If we want a module ecosystem to flourish, they need to have certain assurances that instances of a particular kind are available, so swapping out your AggregateResolver means it probably has to act very similarly to the one inside the stock application so that they can have the same assurances of functionality.

Agreed. My main point here is that we don't know what people are going to want to do down the line and experience with ZF1 has taught us that people want to override classes to add a little bit more functionality or tweak it a bit. I would like that use-case to be do-able and to be able to explain how to do it in less than 30 lines of prose!



>> How do I get database configuration into the adapter config object
>> when I get a TDG backed mapper from the InstanceManger? Do I have to
>> write a separate closure that does this for every single mapper in my
>
> The rule is basically this.  Start by writing the service you need.  In the beginning, it will just be some kind of TableGateway perhaps.  Then, as your application grows, you abstract out the services that need to be shared.  So, for example, in the beginning, the new call to the database connection might be burried inside the service that returns your TableGateway object, but as more objects need a database connection, then your database connection object becomes a service itself.

I'm still unclear how this helps me ensure that I share ZfcUser's db adapter with my own modules. More specifically, I only want to write the username/password/etc once in my config files.

It would be good if we could get a standard solution for db config in particular (but log and mail also come to mine) into Zend\Db backed mappers. This should be drop-dead simple in a ZF2 app and, if possible, provided within skeleton, so that all future modules use the same process.



> Naming is one of those key features provided by InstanceManager.
>
> See this section:
>
> http://framework.zend.com/wiki/display/ZFDEV2/RFC+-+ServiceLocator#RFC-ServiceLocator-Examples%3AUsageInsideModules
>
> That is an all inclusive example, but if one module has a different service naming from another, it should create an alias.

You mean that the dev needs to create an alias in application/config/global.config.php ?  I would assume that two 3rd party modules aren't going to know that they have used different config keys for the db settings?


> The target of the alias should be handled inside a configuration that can be overridden.  This means that a module can use a name like "mymodule_mailer" and it will always be mapped to whatever the application calls its "mailer" instance.

Right. I suspect that everything will become much clearer when I understand what you just wrote :)  


>> Maybe I'm just misunderstanding how easy this will be in practice.
>> I'd really like to see a more complete application to get a feel for
>> how a non-Zend\Di world looks as I can't work it out from the RFC as
>> it seems very abstract and the Skeleton app is too trivial.
>
> Ok, ill get with matthew on this.

Thanks. This would be useful.


Regards,

Rob…

Reply | Threaded
Open this post in threaded view
|

Re: Service Location in ZF (ServiceLocator/InstanceManager RFC)

akrabat
In reply to this post by ralphschindler
Hi Ralph,

Bits that I've snipped needed no further comment :)


On 11 Apr 2012, at 16:28, Ralph Schindler wrote:

> On 4/10/12 4:42 AM, Rob Allen wrote:
>>
>> An Initial look seems to suggest that the way we've been doing things
>> so far in ZF2 is no longer the case and we have to learn a new way. I
>> don't have a problem with this per-se, but it seems like a
>> significant change of thinking will be required from using Zend\Di
>> configuration.
>
> That's the nature of beta software no?  That said, you make a good point.

Definitely. The idea is that we learn what isn't working and fix it :)  I'm not knocking the concept.  I agree about DI being complex too and I hate it when I make a mistake in the config!



> Keep in mind.  If we want a module ecosystem to flourish, they need to have certain assurances that instances of a particular kind are available, so swapping out your AggregateResolver means it probably has to act very similarly to the one inside the stock application so that they can have the same assurances of functionality.

Agreed. My main point here is that we don't know what people are going to want to do down the line and experience with ZF1 has taught us that people want to override classes to add a little bit more functionality or tweak it a bit. I would like that use-case to be do-able and to be able to explain how to do it in less than 30 lines of prose!



>> How do I get database configuration into the adapter config object
>> when I get a TDG backed mapper from the InstanceManger? Do I have to
>> write a separate closure that does this for every single mapper in my
>
> The rule is basically this.  Start by writing the service you need.  In the beginning, it will just be some kind of TableGateway perhaps.  Then, as your application grows, you abstract out the services that need to be shared.  So, for example, in the beginning, the new call to the database connection might be burried inside the service that returns your TableGateway object, but as more objects need a database connection, then your database connection object becomes a service itself.

I'm still unclear how this helps me ensure that I share ZfcUser's db adapter with my own modules. More specifically, I only want to write the username/password/etc once in my config files.

It would be good if we could get a standard solution for db config in particular (but log and mail also come to mine) into Zend\Db backed mappers. This should be drop-dead simple in a ZF2 app and, if possible, provided within skeleton, so that all future modules use the same process.



> Naming is one of those key features provided by InstanceManager.
>
> See this section:
>
> http://framework.zend.com/wiki/display/ZFDEV2/RFC+-+ServiceLocator#RFC-ServiceLocator-Examples%3AUsageInsideModules
>
> That is an all inclusive example, but if one module has a different service naming from another, it should create an alias.

You mean that the dev needs to create an alias in application/config/global.config.php ?  I would assume that two 3rd party modules aren't going to know that they have used different config keys for the db settings?


> The target of the alias should be handled inside a configuration that can be overridden.  This means that a module can use a name like "mymodule_mailer" and it will always be mapped to whatever the application calls its "mailer" instance.

Right. I suspect that everything will become much clearer when I understand what you just wrote :)  


>> Maybe I'm just misunderstanding how easy this will be in practice.
>> I'd really like to see a more complete application to get a feel for
>> how a non-Zend\Di world looks as I can't work it out from the RFC as
>> it seems very abstract and the Skeleton app is too trivial.
>
> Ok, ill get with matthew on this.

Thanks. This would be useful.


Regards,

Rob…

Reply | Threaded
Open this post in threaded view
|

Re: Service Location in ZF (ServiceLocator/InstanceManager RFC)

akrabat
In reply to this post by ralphschindler
Hi Ralph,

Bits that I've snipped needed no further comment :)


On 11 Apr 2012, at 16:28, Ralph Schindler wrote:

> On 4/10/12 4:42 AM, Rob Allen wrote:
>>
>> An Initial look seems to suggest that the way we've been doing things
>> so far in ZF2 is no longer the case and we have to learn a new way. I
>> don't have a problem with this per-se, but it seems like a
>> significant change of thinking will be required from using Zend\Di
>> configuration.
>
> That's the nature of beta software no?  That said, you make a good point.

Definitely. The idea is that we learn what isn't working and fix it :)  I'm not knocking the concept.  I agree about DI being complex too and I hate it when I make a mistake in the config!



> Keep in mind.  If we want a module ecosystem to flourish, they need to have certain assurances that instances of a particular kind are available, so swapping out your AggregateResolver means it probably has to act very similarly to the one inside the stock application so that they can have the same assurances of functionality.

Agreed. My main point here is that we don't know what people are going to want to do down the line and experience with ZF1 has taught us that people want to override classes to add a little bit more functionality or tweak it a bit. I would like that use-case to be do-able and to be able to explain how to do it in less than 30 lines of prose!



>> How do I get database configuration into the adapter config object
>> when I get a TDG backed mapper from the InstanceManger? Do I have to
>> write a separate closure that does this for every single mapper in my
>
> The rule is basically this.  Start by writing the service you need.  In the beginning, it will just be some kind of TableGateway perhaps.  Then, as your application grows, you abstract out the services that need to be shared.  So, for example, in the beginning, the new call to the database connection might be burried inside the service that returns your TableGateway object, but as more objects need a database connection, then your database connection object becomes a service itself.

I'm still unclear how this helps me ensure that I share ZfcUser's db adapter with my own modules. More specifically, I only want to write the username/password/etc once in my config files.

It would be good if we could get a standard solution for db config in particular (but log and mail also come to mine) into Zend\Db backed mappers. This should be drop-dead simple in a ZF2 app and, if possible, provided within skeleton, so that all future modules use the same process.



> Naming is one of those key features provided by InstanceManager.
>
> See this section:
>
> http://framework.zend.com/wiki/display/ZFDEV2/RFC+-+ServiceLocator#RFC-ServiceLocator-Examples%3AUsageInsideModules
>
> That is an all inclusive example, but if one module has a different service naming from another, it should create an alias.

You mean that the dev needs to create an alias in application/config/global.config.php ?  I would assume that two 3rd party modules aren't going to know that they have used different config keys for the db settings?


> The target of the alias should be handled inside a configuration that can be overridden.  This means that a module can use a name like "mymodule_mailer" and it will always be mapped to whatever the application calls its "mailer" instance.

Right. I suspect that everything will become much clearer when I understand what you just wrote :)  


>> Maybe I'm just misunderstanding how easy this will be in practice.
>> I'd really like to see a more complete application to get a feel for
>> how a non-Zend\Di world looks as I can't work it out from the RFC as
>> it seems very abstract and the Skeleton app is too trivial.
>
> Ok, ill get with matthew on this.

Thanks. This would be useful.


Regards,

Rob…

Reply | Threaded
Open this post in threaded view
|

Re: Service Location in ZF (ServiceLocator/InstanceManager RFC)

Artur Bodera
In reply to this post by ralphschindler
On Wed, Apr 11, 2012 at 5:28 PM, Ralph Schindler <[hidden email]> wrote:
That's the nature of beta software no?  That said, you make a good point.

Consider this though: the current way of doing things might be a
non-starter for some people, and they have yet to begun writing ZF2
applications.  We still need to find the ideal way to go about building
applications in the ZF2 philosophy.

Di currently is a level of magic that I think scares people up-front. It does auto-instantiation and auto-wiring of objects.  It does this based off generally complex and in-depth configuration files (nested very deeply in most cases).  Zend\Di has grown in significant complexity because instead of writing simple, clear and rule based DI injectable code, PHP developers want Zend\Di to work with the way they write code.  This means more configuration for the tool to understand their code. (Think how we have the injections keyword now).

After skimming through the implementation and your description, I'm liking it.

I can confirm "bare DI" configuration and those monstrous arrays were scary, as compared to other frameworks' or even zf1's configuration. The goal with zf2 is to make component configuration explicit.

The way I understand it, IM wraps what we got up until beta3 into a more friendly package. It allows us to ship "default managers" with zf2 to handle things like configuring routes, specifying controller classes etc. I was about to propose something similar as we're approaching RC and need to start simplifying things for newcomers.

I'd like to point out a few caveats: good thing about DIC config was that it was somewhat standarized. After a quick tutorial on how DIC takes config array and injects stuff into components, one could easily learn to write DIC configs for each and every component (zf2, userland or even php extensions' classes). IM builders introduce some level of added abstraction that blurs the image.

It'd be great if we could see a "mixed" use-case, where DIC definitions live together with those IM factories. Then, how it's used inside userland in various contexts. For added learning benefits, it could be put side-by-side with things like "static class services", zf1 Registry and other ideas. IM is not limited to services, so it'd be great to show some examples for other common patterns where it comes in handy and when using a DIC is a better alternative.

Great job. Thanks.

A.


-- 
      __
     /.)\   +48 695 600 936
     \(./   [hidden email]