[dev] [commits] Horde-Hatchery branch master updated. 2374bf4d0704a85d5ef81f88a9d9a5ef5dea0f15

Gunnar Wrobel p at rdus.de
Wed Sep 23 20:06:46 UTC 2009


Hi James,

hasBinder() would be one part of hasInstance(). hasInstance() would  
first check if there is already a concrete instance available. If not  
it would do what you describe for hasBinder() and determine if there  
is a potential binding available.

Maybe the use case I imagine is all wrong. Let me try to clarify my  
last example. Maybe you can tell me why the following would be  
incorrect:

   public static function getConfiguredObject($injector)
   {
     $driver = "standard";
     if ($injector->hasInstance('object_driver')) {
       $driver = $injector->getInstance('object_driver');
     }
     $result = new Object($driver);
     return $result;
   }

I deliberately register a simple string as instance here. And it is  
being registered to "object_driver" which is a simple name. It  
specifies no interface and will never yield an object.

Cheers,

Gunnar

Quoting James Pepin <james at jamespepin.com>:

> I think what we want is hasBinder() and not
> hasInstance()
> If there is a binder set for an interface, then
> presumably, we can create it.  If there is not one set, then we
know
> that we can't create it.  The only way to know if we actually can
> create it is by actually creating it, or by simulating creating
> it. If we are just wanting to see if a binding is set for
> that interface, then we'll have to add back hasBinder(), a method
we
> had at first, but removed because it was deemed unnecessary at the
> time. hasBinder can follow the chain all the way up the
> parent, and at the TopLevel parent, just return false.  Of course,
> that would give you possibly incorrect results when your
'interface'
> requested is a concrete class.  You'd have to create a
> ReflectionClass in the TopLevel Injector to determine if you have a
> concrete class or an interface/abstract class.   I think what you  
> want can be done, but we should be
> asking if there is a binder, and not if there is an instance,
> because going through all the motions to create an object only to
> then redo all that work seems wrong to me, and I would definitely
> advise people against using it in production.  And just checking
for
> a cached object on the Injector would yield indeterminate
> results. I don't think I'd ever use it, but if you think you will
> then it won't hurt any existing code to add back
> hasBinder($interface).
> Does that make sense? Are we on the same page?   Would
> you like me to create a patch so you can see what I mean in
> code? -J
> On Tue, Sep 22, 2009 at 5:11
> PM, Gunnar Wrobel <p at rdus.de[1]>
> wrote:
>  .8ex;border-left:1px #ccc solid;padding-left:1ex;"> Hi James,
class="im">
>
> Quoting James Pepin <james at jamespepin.com[2]>:
>
>  .8ex;border-left:1px #ccc solid;padding-left:1ex"> Thats an
> interesting point.  We were working under the assumption
> that you would use either a factory class for buliding objects, or
> use setter injection for optional dependencies.

  Same assumption here.

  Your factory class would have the ability to try and
get an instance.

  Meaning the factory would do something like this:

public static function getObject($injector)
{
$optdep = null;
try {
$optdep = $injector->getInstance('Opt_Dep');
} catch (Exception $e) {
}
$result = new Object($optdep);
return $result;
}

Using hasInstance() this would look like this:

public static function getObject($injector)
{
$result = new Object($injector->hasInstance('Opt_Dep') ?
$injector->getInstance('Opt_Dep') : null);
return $result;
}

  The hasInstance method you're speaking of... would it
also run through the entire process of creating an instance if one
is not already created?

  No, definitely not.

  Or do you merely want to know if a cached
instance exists on the Injector or one of its parents?  Or are
looking for something that can tell you if the injector can create
an instance?

  This is what I'm looking for. I want to know if it makes sense to
ask the injector for a given instance.

  So far, with the code as is, the only way to tell if an instance can
be
created is to try and fail.

  As depicted in my example above. With hasInstance() you will have
the overhead of checking the hierarchy of injectors for a binding to
the given interface. You  will however avoid the overhead of calling
createInstance() if it is not necessary. Probably no major gain. But
to me it warrants the existence of such a function ;)

Cheers,

Gunnar

On Tue, Sep 22, 2009 at 3:18 PM, Gunnar
  Wrobel <p at rdus.de[3][1]> wrote:
0pt 0.8ex; padding-left: 1ex;" class="gmail_quote">
  class="im">Quoting Chuck Hagenbuch <
href="mailto:chuck at horde.org[4]">chuck at horde.org[5]>:
  0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"> Quoting
Gunnar Wrobel < href="mailto:p at rdus.de[6]">p at rdus.de[7]>:
0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"> As I only
just started with the Provider I used in at a very few places so
far. So there will be no pain in moving to the Injector. And I do
like the Injector package as it is definitely *not* as bloated as
some of the other frameworks I looked at. Well, probably depends on
what you want to do with such a framework but the Injector looks
pretty good for what Horde might need.

Cool.

Within Horde_Provider I used some magic methods (__get(), __set(),
__isset(), and __unset()) for convenience. The Injector currently
offers getInstance() and setInstance(). Is there a specific reason
for
avoiding the use of __get() and __set()?

I've passed this along to Bob and James, and cc:ed them on this
reply.

When working with interface names I agree that I'd rather use
$injector->getInstance('Horde_Kolab_Server') than
$injector->Horde_Kolab_Server.
Nevertheless the factory based Binder allows you to bind the
instances to any name. And for the unit testing I find it convenient
if you can use your mocks without requiring the use of a dependency
injector:

$injector = new stdClass;
$injector->some_mock = Mock();

In any case the Injector should get a hasInstance() method. If you
agree I'll add it.

With hasInstance, what sort of logic would be checking it? It makes
sense to me for completeness, but on second thought I'm not 100% sure
what you'd use it for.

Some dependencies can be optional. A factory method can check if
such dependencies are available. You probably would not need that
function if you rely solely on constructor injection.

Cheers,

Gunnar

I wrote a short summary on how to use Horde_Provider with Horde
(http://cvs.horde.org/co.php/framework/Provider/doc/Horde/Provider/usage.txt?r=2374bf4d0704a85d5ef81f88a9d9a5ef5dea0f15[8]).
Do you think it makes sense if I adapt it to the Injector and add it
to the package?

That would be fabulous!

Thanks,
-chuck

--
Horde developers mailing list - Join the hunt:
http://horde.org/bounties/[9]
Frequently Asked Questions: http://horde.org/faq/[10]
To unsubscribe, mail: dev-unsubscribe at lists.horde.org[11]

  Links:
------
[1] mailto:p at rdus.de[12]



Links:
------
[1] mailto:p at rdus.de
[2] mailto:james at jamespepin.com
[3] mailto:p at rdus.de
[4] mailto:chuck at horde.org
[5] mailto:chuck at horde.org
[6] mailto:p at rdus.de
[7] mailto:p at rdus.de
[8]  
http://cvs.horde.org/co.php/framework/Provider/doc/Horde/Provider/usage.txt?r=2374bf4d0704a85d5ef81f88a9d9a5ef5dea0f15
[9] http://horde.org/bounties/
[10] http://horde.org/faq/
[11] mailto:dev-unsubscribe at lists.horde.org
[12] mailto:p at rdus.de

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: Digitale PGP-Unterschrift
URL: <http://lists.horde.org/archives/dev/attachments/20090923/df71aed3/attachment.bin>


More information about the dev mailing list