tag:robotlegs.tenderapp.com,2009-10-18:/discussions/problems/21-mapsingleton-vs-mapvalueRobotlegs: Discussion 2018-10-18T16:35:07Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/7222842009-12-14T16:59:42Z2009-12-14T16:59:47ZmapSingleton vs. mapValue<div><p>using mapSingleton I have a working example of proxy injection.
in my AppContext:</p>
<p>injector.mapSingleton(UserProxy);</p>
<p>then, in my StartUpCommand:</p>
<p>public class StartUpCommand extends Command<br>
{</p>
<pre>
<code>[Inject] public var userProxy:UserProxy;
override public function execute ():void
{
trace('StartUpCommand', userProxy);
}</code>
</pre>
<p>}</p>
<p>all working fine, great. however, looking at this:</p>
<p><a href=
"http://knowledge.robotlegs.org/faqs/framework-core/injection-mapping-with-the-injector-class">
http://knowledge.robotlegs.org/faqs/framework-core/injection-mappin...</a></p>
<p>i understand that i can change my AppContext code to this to
achieve the same result:</p>
<p>var userProxy:UserProxy = new UserProxy();<br>
injector.mapValue(StartUpCommand, userProxy);</p>
<p>however if I do that i get the following error:</p>
<p>Error: Injector is missing a rule to handle injection into
target [object StartUpCommand]. Target dependency:
com.client.appname.model::UserProxy</p>
<p>woe is me! what gives?</p></div>Richard Willistag:robotlegs.tenderapp.com,2009-10-18:Comment/7222842009-12-14T17:02:33Z2009-12-14T17:02:33ZmapSingleton vs. mapValue<div><p>On Dec 14, 2009, at 10:59 AM, Richard Willis wrote:</p>
<blockquote>
<p>var userProxy:UserProxy = new UserProxy();
injector.mapValue(StartUpCommand, userProxy);</p>
<p>however if I do that i get the following error:</p>
<p>Error: Injector is missing a rule to handle injection into
target [object StartUpCommand]. Target dependency:
com.client.appname.model::UserProxy</p>
</blockquote>
<p>var userProxy:UserProxy = new UserProxy();<br>
injector.mapValue(UserProxy, userProxy);</p>
<p>You are mapping the value of a UserProxy class with a specific
instance, not mapping the value to BE injected in a specific
class.</p></div>Joel Hookstag:robotlegs.tenderapp.com,2009-10-18:Comment/7222842009-12-14T19:52:08Z2009-12-14T19:52:08ZmapSingleton vs. mapValue<div><p>Indeed, the way you were doing it initially seems more
appropriate, ie:</p>
<pre>
injector.mapSingleton(UserProxy);
</pre>
<p>Unless you have a reason to eagerly instantiate the proxy, in
which case:</p>
<pre>
var userProxy:UserProxy = new UserProxy();
injector.mapValue(UserProxy, userProxy);
</pre>
<p>However, it's usually better to let the framework instantiate
the class lazily (as it does with mapSingleton), rather than
eagerly (as with mapValue).</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/7222842009-12-15T13:37:59Z2009-12-15T13:38:02ZmapSingleton vs. mapValue<div><p>thanks guys.</p>
<p>why would you consider mapSingleton's lazy instans. to be better
shaun? i realise it doesn't actually create a singleton, but
anything with that word in it tends to make me a bit nervous.plus
my understanding is that mapSingleton just injects its given class
willy-nilly around the architecture blindly. isn't that a bit of an
unnecessary overhead?</p>
<p>i'm new to dep. inj. (just started this week) so if sorry if
these come across as idiotic newbie questions. just tryin to
learn.</p>
<p>:)</p></div>Richard Willistag:robotlegs.tenderapp.com,2009-10-18:Comment/7222842009-12-15T14:00:37Z2009-12-15T14:00:37ZmapSingleton vs. mapValue<div><p>Hey Richard,</p>
<blockquote>
<p>why would you consider mapSingleton's lazy instans. to be better
shaun? i realise it doesn't actually create a singleton, but
anything with that word in it tends to make me a bit nervous.</p>
</blockquote>
<p>In my opinion, mapSingleton has three advantages over
mapValue:<br>
- The fact that it lazily creates its instance means that the
instance is created exactly if and when it is needed, possibly
reducing<br>
initialization overhead in cases where it is used for seldomly<br>
accessed functionality<br>
- It clearly communicates the intent: The developer wants exactly
one shared instance of this class to be used for every request
made<br>
- It simply reduces what you have to type and automates priming the
singleton itself with dependencies by instantiating it internally
and<br>
immediately injecting into it</p>
<p>As Shaun said some time ago, Singletons with a big "S" are
the<br>
original anti-pattern and should be avoided at all costs. On the
other<br>
hand, there's nothing wrong with explicitly stating that you want
each<br>
request for a certain type (and possibly a certain name) to be<br>
fulfilled with the same instance of a class. And that's exactly
what<br>
singletons with a small "s" are for.</p>
<blockquote>
<p>plus my understanding is that mapSingleton just injects its
given class willy-nilly around the architecture blindly. isn't that
a bit of an unnecessary overhead?</p>
</blockquote>
<p>I'm not sure what you mean by that, maybe you can elaborate a
bit?<br>
After the instance has been created at first request, value and<br>
singleton mappings should be pretty much identical in behavior
and<br>
overhead.</p>
<blockquote>
<p>i'm new to dep. inj. (just started this week) so if sorry if
these come across as idiotic newbie questions. just tryin to
learn.</p>
</blockquote>
<p>No worries. Feel free to check the knowledge database and ask
questions.</p>
<p>cheers,<br>
till</p></div>Till Schneidereittag:robotlegs.tenderapp.com,2009-10-18:Comment/7222842009-12-15T19:22:47Z2009-12-15T19:22:47ZmapSingleton vs. mapValue<div><blockquote>
<p>However, it's usually better to let the framework instantiate
the class lazily (as it does > with mapSingleton), rather than
eagerly (as with mapValue).</p>
</blockquote>
<p>It's usually better to say <em>why</em> it's better, rather than
just saying that it is. :)</p>
<p>The only functional difference I see, as Till pointed out, is
that mapSingleton won't create the instance until it's needed,
possibly reducing initialization time and saving some runtime
memory. From project's I've worked on this seems rare and the
savings would be unnoticeable.</p>
<p>Personally I like mapValue best (at least today I do),
considering that the Injector's singleton is really only single to
itself (not system-wide) and so not really a Singleton, which is
why we feel better using it.</p>
<p>Good discussion, thanks!</p></div>Tyler Wrighttag:robotlegs.tenderapp.com,2009-10-18:Comment/7222842009-12-16T03:44:33Z2009-12-16T03:44:33ZmapSingleton vs. mapValue<div><p>Perhaps the problem is the big S. mapSingleton should be renamed
mapsingleton ;)</p></div>Tim Oxleytag:robotlegs.tenderapp.com,2009-10-18:Comment/7222842009-12-16T17:48:56Z2009-12-16T17:48:56ZmapSingleton vs. mapValue<div><p>@Tim: Haha! Believe it or not, I had actually considered
that!</p>
<p>@Tyler:</p>
<p>One of the benefits of DI is that client code doesn't have to
know "how" to construct the objects/collaborators/dependencies that
it needs to get it's job done. The task of constructing such an
object can be left to the container.</p>
<p>The benefits of Lazy vs Eager aside, using mapValue requires
that you construct said object yourself. If the constructor of the
object changes you will need to change the code that constructs it.
The container, on the other hand, would most likely be able to
figure out how to construct the new object without any changes to
your code.</p>
<p>Also, manually constructing objects that rely on setter
injection is error prone: you might forget to set the appropriate
dependencies after construction. Leaving construction to the
container will safe guard against that.</p>
<p>The only time that I use mapValue is when I need to put an
object into the container that already exists. For everything else,
I leave it up to the container to build my objects for me.</p>
<p>Finally (and very subjectively), using mapValue makes me feel
like I'm using the Service Locator / Registry pattern - granted, an
IoC container IS a registry of sorts - I just don't like it!</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/7222842009-12-17T03:33:34Z2009-12-17T03:33:34ZmapSingleton vs. mapValue<div><p>I see your point. DI isn't my primary workflow for object
creation - I<br>
assumed that each object to map wouldn't often be injected itself,
otherwise<br>
you have to start worrying about the order of your mappings. But I
can see<br>
that I would want a Controller injected into, and then to be
provided via<br>
injection into other objects.</p>
<p>So mapSingleton does the following, except lazily:
mapValue(Type,<br>
instantiate(MyType));</p>
<p>re: registry - everything needs a home, a registry can be a
beautiful<br>
organization of data and configuration, making a system easy to
update and<br>
extend (as we see from RL Injector/Context). It's only ugly when it
becomes<br>
a global trough for all the table scraps. :)</p></div>Tyler Wright