DIC lazy loading

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

DIC lazy loading

Tomáš Fejfar
Hi everyone,

I`m not sure if ML is the ideal place for asking this, but still...

When trying to grasp the idea behind the DI (especially the DIContainer) I
realised that the most useful thing about DI is that you pass around the
DIC rather than the concrete object instances. When object (say some API
client) needs a dependency, say a database (for pulling the username and
password), it states it with having appropriate setter setDbAdapter() (or
constructor param). But rather than inserting concrete database instance,
I'll pass the DIC instead - as kind of proxy object. Than, when the
instance is needed for say $dbAdapter->query() call, it's called on the DIC
and in it's guts it fetches the instance (regardless whether it's new
instance or reused one) and call the method. This creates enormous
performance gains as the dependencies are instantiated JustInTime and
nothing is wasted (say when you do only public operations - public feed -
and username and password is not needed). There are many of such
dependencies all over the application (basic CRUD update - needs model
instance - when ID param is missing we can't continue - redirect to
index/list - model instance is not needed).

But from what I see in Zend/Di this is not possible, am I right? When I
want anything from the DIC I get the whole package - with all the
dependencies instantiated, don't I? So the core advantage is that I don't
need to pull the base configs from Zend_Registry, save a bunch of "new
Obj()" calls and don't have to use singletons anymore.

I would expect the DIC to work somhow along these lines -
https://gist.github.com/1384029 But that's not the case with Zend\Di. Is
this my poor understanding of DIC or it's just the way the DI works?

Thanks for any insight :)

Tomas Fejfar, w3w.cz
Reply | Threaded
Open this post in threaded view
|

Re: DIC lazy loading

weierophinney
Administrator
-- Tomáš Fejfar <[hidden email]> wrote
(on Monday, 21 November 2011, 10:49 PM +0100):
> I`m not sure if ML is the ideal place for asking this, but still...
>
> When trying to grasp the idea behind the DI (especially the DIContainer) I
> realised that the most useful thing about DI is that you pass around the
> DIC rather than the concrete object instances. When object (say some API
> client) needs a dependency, say a database (for pulling the username and
> password), it states it with having appropriate setter setDbAdapter() (or
> constructor param). But rather than inserting concrete database instance,
> I'll pass the DIC instead - as kind of proxy object.

no, no, no!

DiC is about retrieving an object *with* its dependencies. You shouldn't
be passing it around; that defeats the purpose. The point is to pull one
or two objects from it, and then do your work.

If you've got code paths that get unneeded dependencies, consider
splitting those paths up. As an example, if some controller actions
don't require a DB connection and/or data mapper, and some do, then
create two controllers, one that handles actions requiring statefulness
(i.e., DB connectivity, persistence) and those that don't.

> Than, when the instance is needed for say $dbAdapter->query() call,
> it's called on the DIC and in it's guts it fetches the instance
> (regardless whether it's new instance or reused one) and call the
> method. This creates enormous performance gains as the dependencies
> are instantiated JustInTime and nothing is wasted (say when you do
> only public operations - public feed - and username and password is
> not needed). There are many of such dependencies all over the
> application (basic CRUD update - needs model instance - when ID param
> is missing we can't continue - redirect to index/list - model instance
> is not needed).

Remember, however, that in the case of the db abstraction layer, no
_actual_ connection is made to the database _until_ you perform an
operation. So you're simply slinging around some objects -- which
typically are not going to account for any significant processing time
and/or overhead.

So, even in the case where we have a missing ID, you won't incur
anything more than instantiating a few objects.

> But from what I see in Zend/Di this is not possible, am I right? When I
> want anything from the DIC I get the whole package - with all the
> dependencies instantiated, don't I?

Yes. That's what the DIC is for.

> So the core advantage is that I don't need to pull the base configs
> from Zend_Registry, save a bunch of "new Obj()" calls and don't have
> to use singletons anymore.

Yes. And that's a very, very big advantage.

But you're missing something else. You get the JIT benefits to a large
degree, because on each request, you're only loading what you need for
_that_ request. No more, no less. This is much better than in ZF1, where
we were loading _all_ possible application resources on _every_ request.

> I would expect the DIC to work somhow along these lines -
> https://gist.github.com/1384029 But that's not the case with Zend\Di.
> Is this my poor understanding of DIC or it's just the way the DI
> works?

What you're describing there is more along the lines of a service
locator. Service locators tend to be domain specific, and _are_
typically passed around between objects, which retrieve the various
services they require from it.

The problems are similar to what you get using a Registry or Singleton,
however: hidden dependencies, hard-coded dependencies, etc. The benefits
are more optimistic loading (the JIT you describe above). Basically, you
program the two approaches slightly differently -- with DI, you think
about the code paths and how to optimize them to minimize dependency
chains, with service locators you think about in-place optimizations.

--
Matthew Weier O'Phinney
Project Lead            | [hidden email]
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

--
List: [hidden email]
Info: http://framework.zend.com/archives
Unsubscribe: [hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: DIC lazy loading

ralphschindler
In reply to this post by Tomáš Fejfar
I talked about this in my presentation on Zend\Di at ZendCon.

Basically, you're talking about the differences between having a Service
Locator (Service Location) and utilizing a DI Container.

http://www.slideshare.net/ralphschindler/zend-di-in-zf-20/24

The dependency graph for objects is typically.

http://www.slideshare.net/ralphschindler/zend-di-in-zf-20/25

Wiring becomes cumbersome, so you have two choices.  Move all the common
dependencies into a service locator, and make all your consumers depend
only on the service locator -OR- utilize a DI framework of some sort.

When you use SL's, your dependency graph starts to look like this:

http://www.slideshare.net/ralphschindler/zend-di-in-zf-20/27

Each solution has its benefits and drawbacks.

Matthew pretty much summed it up in response, but also know I'll talk
about this in more detail in my webinar in december.

-ralph

On 11/21/11 3:49 PM, Tomáš Fejfar wrote:

> Hi everyone,
>
> I`m not sure if ML is the ideal place for asking this, but still...
>
> When trying to grasp the idea behind the DI (especially the DIContainer) I
> realised that the most useful thing about DI is that you pass around the
> DIC rather than the concrete object instances. When object (say some API
> client) needs a dependency, say a database (for pulling the username and
> password), it states it with having appropriate setter setDbAdapter() (or
> constructor param). But rather than inserting concrete database instance,
> I'll pass the DIC instead - as kind of proxy object. Than, when the
> instance is needed for say $dbAdapter->query() call, it's called on the DIC
> and in it's guts it fetches the instance (regardless whether it's new
> instance or reused one) and call the method. This creates enormous
> performance gains as the dependencies are instantiated JustInTime and
> nothing is wasted (say when you do only public operations - public feed -
> and username and password is not needed). There are many of such
> dependencies all over the application (basic CRUD update - needs model
> instance - when ID param is missing we can't continue - redirect to
> index/list - model instance is not needed).
>
> But from what I see in Zend/Di this is not possible, am I right? When I
> want anything from the DIC I get the whole package - with all the
> dependencies instantiated, don't I? So the core advantage is that I don't
> need to pull the base configs from Zend_Registry, save a bunch of "new
> Obj()" calls and don't have to use singletons anymore.
>
> I would expect the DIC to work somhow along these lines -
> https://gist.github.com/1384029 But that's not the case with Zend\Di. Is
> this my poor understanding of DIC or it's just the way the DI works?
>
> Thanks for any insight :)
>
> Tomas Fejfar, w3w.cz
>


--
List: [hidden email]
Info: http://framework.zend.com/archives
Unsubscribe: [hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: DIC lazy loading

Tomáš Fejfar
Thanks both of you for your answers. It cleared many of my "blank spots".
It looks like that there will be a big mind-shift for me, that will make me
love the new code I write and hate anything pre-zf2 :D

I hope I'll manage to attend the webinar in dec., last time I missed it due
to the ISP failure :(


On Mon, Nov 21, 2011 at 11:33 PM, Ralph Schindler
<[hidden email]>wrote:

> I talked about this in my presentation on Zend\Di at ZendCon.
>
> Basically, you're talking about the differences between having a Service
> Locator (Service Location) and utilizing a DI Container.
>
> http://www.slideshare.net/**ralphschindler/zend-di-in-zf-**20/24<http://www.slideshare.net/ralphschindler/zend-di-in-zf-20/24>
>
> The dependency graph for objects is typically.
>
> http://www.slideshare.net/**ralphschindler/zend-di-in-zf-**20/25<http://www.slideshare.net/ralphschindler/zend-di-in-zf-20/25>
>
> Wiring becomes cumbersome, so you have two choices.  Move all the common
> dependencies into a service locator, and make all your consumers depend
> only on the service locator -OR- utilize a DI framework of some sort.
>
> When you use SL's, your dependency graph starts to look like this:
>
> http://www.slideshare.net/**ralphschindler/zend-di-in-zf-**20/27<http://www.slideshare.net/ralphschindler/zend-di-in-zf-20/27>
>
> Each solution has its benefits and drawbacks.
>
> Matthew pretty much summed it up in response, but also know I'll talk
> about this in more detail in my webinar in december.
>
> -ralph
>
>
> On 11/21/11 3:49 PM, Tomáš Fejfar wrote:
>
>> Hi everyone,
>>
>> I`m not sure if ML is the ideal place for asking this, but still...
>>
>> When trying to grasp the idea behind the DI (especially the DIContainer) I
>> realised that the most useful thing about DI is that you pass around the
>> DIC rather than the concrete object instances. When object (say some API
>> client) needs a dependency, say a database (for pulling the username and
>> password), it states it with having appropriate setter setDbAdapter() (or
>> constructor param). But rather than inserting concrete database instance,
>> I'll pass the DIC instead - as kind of proxy object. Than, when the
>> instance is needed for say $dbAdapter->query() call, it's called on the
>> DIC
>> and in it's guts it fetches the instance (regardless whether it's new
>> instance or reused one) and call the method. This creates enormous
>> performance gains as the dependencies are instantiated JustInTime and
>> nothing is wasted (say when you do only public operations - public feed -
>> and username and password is not needed). There are many of such
>> dependencies all over the application (basic CRUD update - needs model
>> instance - when ID param is missing we can't continue - redirect to
>> index/list - model instance is not needed).
>>
>> But from what I see in Zend/Di this is not possible, am I right? When I
>> want anything from the DIC I get the whole package - with all the
>> dependencies instantiated, don't I? So the core advantage is that I don't
>> need to pull the base configs from Zend_Registry, save a bunch of "new
>> Obj()" calls and don't have to use singletons anymore.
>>
>> I would expect the DIC to work somhow along these lines -
>> https://gist.github.com/**1384029 <https://gist.github.com/1384029> But
>> that's not the case with Zend\Di. Is
>> this my poor understanding of DIC or it's just the way the DI works?
>>
>> Thanks for any insight :)
>>
>> Tomas Fejfar, w3w.cz
>>
>>
>
> --
> List: [hidden email]
> Info: http://framework.zend.com/**archives<http://framework.zend.com/archives>
> Unsubscribe: zf-contributors-unsubscribe@**lists.zend.com<[hidden email]>
>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: DIC lazy loading

Simon Walter
On Monday, November 21, 2011 14:05:02 Tomáš Fejfar wrote:
> Thanks both of you for your answers. It cleared many of my "blank spots".

Nice reading for me too, BTW. Thanks for taking the time to explain this guys.

--
List: [hidden email]
Info: http://framework.zend.com/archives
Unsubscribe: [hidden email]