<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Moving containers beyond testability</title>
	<atom:link href="http://lostechies.com/jimmybogard/2010/09/21/moving-containers-beyond-testability/feed/" rel="self" type="application/rss+xml" />
	<link>http://lostechies.com/jimmybogard/2010/09/21/moving-containers-beyond-testability/</link>
	<description>Strong opinions, weakly held</description>
	<lastBuildDate>Thu, 20 Jun 2013 08:29:00 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
	<item>
		<title>By: Scott Bellware</title>
		<link>http://lostechies.com/jimmybogard/2010/09/21/moving-containers-beyond-testability/#comment-2629</link>
		<dc:creator>Scott Bellware</dc:creator>
		<pubDate>Thu, 30 Sep 2010 16:15:56 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2010/09/21/moving-containers-beyond-testability.aspx#comment-2629</guid>
		<description>Casey,

Those semantic markers are available in most programming languages. It&#039;s nothing special to C# or Java. Unfortunately though, these markers in C# and Java, and languages like them, introduce unnecessary constraints on code construction.</description>
		<content:encoded><![CDATA[<p>Casey,</p>
<p>Those semantic markers are available in most programming languages. It&#8217;s nothing special to C# or Java. Unfortunately though, these markers in C# and Java, and languages like them, introduce unnecessary constraints on code construction.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Casey Kramer</title>
		<link>http://lostechies.com/jimmybogard/2010/09/21/moving-containers-beyond-testability/#comment-2628</link>
		<dc:creator>Casey Kramer</dc:creator>
		<pubDate>Thu, 23 Sep 2010 12:54:52 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2010/09/21/moving-containers-beyond-testability.aspx#comment-2628</guid>
		<description>Scott,
Naturally I can&#039;t speak for Udi directly, but my feeling after attending this particular talk was that he was presenting you with a new way of solving your problems, using tools that you have available right no, and with only a small amount of work (defining some interfaces and setting up the container to resolve them).  The examples given were C# (maybe there was some Java too, don&#039;t remember now), and so the details of the proposed solution were specific to C#/Java.  

Part of the reason for using generics and interfaces to define your roles, I think, was because it was semantically pleasant to work with in C#.  So, if you have a class that implements an : IUseLazyLoading, then it is clear to the person looking at it what is going on.   You actually see a lot of this in NServiceBus, where you have combinations of interfaces like: IConfigureThisEndoing, As_A.Publisher</description>
		<content:encoded><![CDATA[<p>Scott,<br />
Naturally I can&#8217;t speak for Udi directly, but my feeling after attending this particular talk was that he was presenting you with a new way of solving your problems, using tools that you have available right no, and with only a small amount of work (defining some interfaces and setting up the container to resolve them).  The examples given were C# (maybe there was some Java too, don&#8217;t remember now), and so the details of the proposed solution were specific to C#/Java.  </p>
<p>Part of the reason for using generics and interfaces to define your roles, I think, was because it was semantically pleasant to work with in C#.  So, if you have a class that implements an : IUseLazyLoading, then it is clear to the person looking at it what is going on.   You actually see a lot of this in NServiceBus, where you have combinations of interfaces like: IConfigureThisEndoing, As_A.Publisher</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Scott Bellware</title>
		<link>http://lostechies.com/jimmybogard/2010/09/21/moving-containers-beyond-testability/#comment-2627</link>
		<dc:creator>Scott Bellware</dc:creator>
		<pubDate>Wed, 22 Sep 2010 14:27:10 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2010/09/21/moving-containers-beyond-testability.aspx#comment-2627</guid>
		<description>Just as an aside, the reason that static object containers reduce design elegance is that they move knowledge that should be part of (or close to) the abstractions that the knowledge concerns to a more remote knowledge location. The immediacy of knowledge is reduced, affecting simplicity and clarity, and this is ultimately an affect on the ability for humans to understand the code under their noses by looking at the code under their noses. The more removed that an abstraction&#039;s knowledge is, the less elegance it has, and the more error-prone the code will be for humans, and the more frustrating to learn or remember.

If all you have is an environment where you must use something like an IoC framework to get by, then it&#039;s a good thing that they exist. But when there are better alternatives available, it&#039;s as much an imperative to master them as it was to master IoC frameworks back in the day before you had realized the value of IoC frameworks.

When I talk about the learning trajectory pointing out of the .NET sphere, this is an example of what I mean.

For me, I want to make the most of my abilities, and work in an environment that compliments my understanding and ability to the absolute utmost - just as I had done when I started day-to-day use of an IoC framework in 2005 (admittedly late to the IoC party).

The skills that we&#039;ve learned from the programming patterns that are in the same sphere as IoC tools are vastly more effective one the constraints the require an IoC tool are lifted. I want all of that ability and all of that productivity - regardless of whether it runs on open source on Microsoft technology or open source on non-Microsoft technology.

.NET is not my bottleneck. I hope that it doesn&#039;t persist in being the bottleneck in this community, because there&#039;s enough smarts and ability in this community to be really lit up by removing these same constraints that I mentioned.

I wonder what people in this community could achieve if the fullest potential of their abilities were unleashed from mere frameworks and language constraints.

Just a thought...</description>
		<content:encoded><![CDATA[<p>Just as an aside, the reason that static object containers reduce design elegance is that they move knowledge that should be part of (or close to) the abstractions that the knowledge concerns to a more remote knowledge location. The immediacy of knowledge is reduced, affecting simplicity and clarity, and this is ultimately an affect on the ability for humans to understand the code under their noses by looking at the code under their noses. The more removed that an abstraction&#8217;s knowledge is, the less elegance it has, and the more error-prone the code will be for humans, and the more frustrating to learn or remember.</p>
<p>If all you have is an environment where you must use something like an IoC framework to get by, then it&#8217;s a good thing that they exist. But when there are better alternatives available, it&#8217;s as much an imperative to master them as it was to master IoC frameworks back in the day before you had realized the value of IoC frameworks.</p>
<p>When I talk about the learning trajectory pointing out of the .NET sphere, this is an example of what I mean.</p>
<p>For me, I want to make the most of my abilities, and work in an environment that compliments my understanding and ability to the absolute utmost &#8211; just as I had done when I started day-to-day use of an IoC framework in 2005 (admittedly late to the IoC party).</p>
<p>The skills that we&#8217;ve learned from the programming patterns that are in the same sphere as IoC tools are vastly more effective one the constraints the require an IoC tool are lifted. I want all of that ability and all of that productivity &#8211; regardless of whether it runs on open source on Microsoft technology or open source on non-Microsoft technology.</p>
<p>.NET is not my bottleneck. I hope that it doesn&#8217;t persist in being the bottleneck in this community, because there&#8217;s enough smarts and ability in this community to be really lit up by removing these same constraints that I mentioned.</p>
<p>I wonder what people in this community could achieve if the fullest potential of their abilities were unleashed from mere frameworks and language constraints.</p>
<p>Just a thought&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Scott Bellware</title>
		<link>http://lostechies.com/jimmybogard/2010/09/21/moving-containers-beyond-testability/#comment-2626</link>
		<dc:creator>Scott Bellware</dc:creator>
		<pubDate>Wed, 22 Sep 2010 14:07:56 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2010/09/21/moving-containers-beyond-testability.aspx#comment-2626</guid>
		<description>Scott and Jimmy,

Why loop through a container rather than just loop through the subclasses of a class?

Of course, it&#039;s a loaded question because looping through the subclasses of a class is a non-trivial problem in .NET. Building a list of subclasses of a parent class suggests that something dynamic is going to be done with those classes.

This is a case where using the assembly-scanning abilities of a container makes a lot of sense, but in the end, it makes sense because there really aren&#039;t many better choices.

Here&#039;s how I&#039;d do this in a language that has this feature as a first class capability.

BusinessEvent.subclasses.each { &#124;clazz&#124; clazz.do_something }

One implementation for this can be seen at: http://gist.github.com/591695

This is possible because class definitions are runtime code rather than frozen at some point between the editor and runtime.

Another way to do this would be to query the object space at runtime: http://gist.github.com/591707

The object space is the active memory of a Ruby program. Every object in memory is available through the object space. Since every class in Ruby is an object, a program&#039;s classes are also available through the object space. Note, that Ruby objects are garbage collected, so take this into consideration when using the object space.

In either case, the code to collect subclasses can be generalized to a module and included into any base class that offers this service. It can also be added to the Class class, extending the service to every class in an app.

This is a good example of a reasonable argument against container frameworks on the grounds of protecting design elegance from low cohesion components like composition containers that have to take on all of the dynamic programming patterns under the sun because static languages aren&#039;t amenable to this style of programming out of the box.

Ultimately, the responsibility for providing a list of subclasses is the responsibility of the base class of interest. If the environment doesn&#039;t allow for this, then we have to fall back to workarounds.

Nonetheless, it&#039;s a darned good use of a framework in a static language. I just don&#039;t think that these - as I&#039;ve called them - &quot;bionic crutches&quot; should be celebrated when really they are signaling some fairly significant limitations that require remediation tools before they can be really useful. No doubt, they&#039;re useful when needed, but the other way around this is to change the environment so that these needs are no longer concerns.</description>
		<content:encoded><![CDATA[<p>Scott and Jimmy,</p>
<p>Why loop through a container rather than just loop through the subclasses of a class?</p>
<p>Of course, it&#8217;s a loaded question because looping through the subclasses of a class is a non-trivial problem in .NET. Building a list of subclasses of a parent class suggests that something dynamic is going to be done with those classes.</p>
<p>This is a case where using the assembly-scanning abilities of a container makes a lot of sense, but in the end, it makes sense because there really aren&#8217;t many better choices.</p>
<p>Here&#8217;s how I&#8217;d do this in a language that has this feature as a first class capability.</p>
<p>BusinessEvent.subclasses.each { |clazz| clazz.do_something }</p>
<p>One implementation for this can be seen at: <a href="http://gist.github.com/591695" rel="nofollow">http://gist.github.com/591695</a></p>
<p>This is possible because class definitions are runtime code rather than frozen at some point between the editor and runtime.</p>
<p>Another way to do this would be to query the object space at runtime: <a href="http://gist.github.com/591707" rel="nofollow">http://gist.github.com/591707</a></p>
<p>The object space is the active memory of a Ruby program. Every object in memory is available through the object space. Since every class in Ruby is an object, a program&#8217;s classes are also available through the object space. Note, that Ruby objects are garbage collected, so take this into consideration when using the object space.</p>
<p>In either case, the code to collect subclasses can be generalized to a module and included into any base class that offers this service. It can also be added to the Class class, extending the service to every class in an app.</p>
<p>This is a good example of a reasonable argument against container frameworks on the grounds of protecting design elegance from low cohesion components like composition containers that have to take on all of the dynamic programming patterns under the sun because static languages aren&#8217;t amenable to this style of programming out of the box.</p>
<p>Ultimately, the responsibility for providing a list of subclasses is the responsibility of the base class of interest. If the environment doesn&#8217;t allow for this, then we have to fall back to workarounds.</p>
<p>Nonetheless, it&#8217;s a darned good use of a framework in a static language. I just don&#8217;t think that these &#8211; as I&#8217;ve called them &#8211; &#8220;bionic crutches&#8221; should be celebrated when really they are signaling some fairly significant limitations that require remediation tools before they can be really useful. No doubt, they&#8217;re useful when needed, but the other way around this is to change the environment so that these needs are no longer concerns.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Scott Bellware</title>
		<link>http://lostechies.com/jimmybogard/2010/09/21/moving-containers-beyond-testability/#comment-2625</link>
		<dc:creator>Scott Bellware</dc:creator>
		<pubDate>Wed, 22 Sep 2010 13:30:07 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2010/09/21/moving-containers-beyond-testability.aspx#comment-2625</guid>
		<description>Casey,

Is Udi&#039;s counsel here on using an IoC tool due to the supremacy of an IoC tool for this job, or that this is just the way that Udi does things in that he&#039;s been a static language developer for a good part of his career?

Ultimately, is this some kind of best way to do it, or just the way we currently have available to us in C#?</description>
		<content:encoded><![CDATA[<p>Casey,</p>
<p>Is Udi&#8217;s counsel here on using an IoC tool due to the supremacy of an IoC tool for this job, or that this is just the way that Udi does things in that he&#8217;s been a static language developer for a good part of his career?</p>
<p>Ultimately, is this some kind of best way to do it, or just the way we currently have available to us in C#?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Casey Kramer</title>
		<link>http://lostechies.com/jimmybogard/2010/09/21/moving-containers-beyond-testability/#comment-2624</link>
		<dc:creator>Casey Kramer</dc:creator>
		<pubDate>Wed, 22 Sep 2010 12:59:34 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2010/09/21/moving-containers-beyond-testability.aspx#comment-2624</guid>
		<description>This actually ties in nicely with what Udi Dahan has to say about &quot;Making Roles Explicit&quot; (http://www.infoq.com/presentations/Making-Roles-Explicit-Udi-Dahan).  The overarching concept being that you explicitly define the roles in your application (which can, but don&#039;t have to be, associated with a use case) and lean on the compositional aspects of IoC to build the correct behavior for a role.  The &quot;Profile&quot; concept in the NServiceBus Generic Host is a perfect example of this.  It allows you to specify a profile when running the service, and that profile dictates which mechanisms are used when the Message Bus is constructed.  So for example, there is a built-in production profile which turns on persistent subscription storage (via a DB), among other things.  The design of NServiceBus is such that you can define your own profiles, and utilize the profiles within your service in a simple, straight-forward way (lets here it for OCP and SRP, huh?).  I think our industry needs more of this kind of thinking.</description>
		<content:encoded><![CDATA[<p>This actually ties in nicely with what Udi Dahan has to say about &#8220;Making Roles Explicit&#8221; (<a href="http://www.infoq.com/presentations/Making-Roles-Explicit-Udi-Dahan" rel="nofollow">http://www.infoq.com/presentations/Making-Roles-Explicit-Udi-Dahan</a>).  The overarching concept being that you explicitly define the roles in your application (which can, but don&#8217;t have to be, associated with a use case) and lean on the compositional aspects of IoC to build the correct behavior for a role.  The &#8220;Profile&#8221; concept in the NServiceBus Generic Host is a perfect example of this.  It allows you to specify a profile when running the service, and that profile dictates which mechanisms are used when the Message Bus is constructed.  So for example, there is a built-in production profile which turns on persistent subscription storage (via a DB), among other things.  The design of NServiceBus is such that you can define your own profiles, and utilize the profiles within your service in a simple, straight-forward way (lets here it for OCP and SRP, huh?).  I think our industry needs more of this kind of thinking.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Scott</title>
		<link>http://lostechies.com/jimmybogard/2010/09/21/moving-containers-beyond-testability/#comment-2623</link>
		<dc:creator>Scott</dc:creator>
		<pubDate>Wed, 22 Sep 2010 10:55:09 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2010/09/21/moving-containers-beyond-testability.aspx#comment-2623</guid>
		<description>@Jimmy

 &gt; Then it’s just a matter of looping through the instances and executing them one by one.

I have used a similar approach - letting the container grab all instances of a type (in my case events) and executing them one by one. What do you do to control the order of these tasks, if necessary. I could see the need for running startup tasks in a specific order.</description>
		<content:encoded><![CDATA[<p>@Jimmy</p>
<p> > Then it’s just a matter of looping through the instances and executing them one by one.</p>
<p>I have used a similar approach &#8211; letting the container grab all instances of a type (in my case events) and executing them one by one. What do you do to control the order of these tasks, if necessary. I could see the need for running startup tasks in a specific order.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: isaiah</title>
		<link>http://lostechies.com/jimmybogard/2010/09/21/moving-containers-beyond-testability/#comment-2622</link>
		<dc:creator>isaiah</dc:creator>
		<pubDate>Wed, 22 Sep 2010 08:34:11 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2010/09/21/moving-containers-beyond-testability.aspx#comment-2622</guid>
		<description>Hi Jimmy
there is an interesting thread which you may find useful

http://groups.google.com/group/growing-object-oriented-software/browse_thread/thread/ef299b03620a4cef/f1dcfecb9969e174?lnk=gst&amp;q=Ioc#f1dcfecb9969e174

</description>
		<content:encoded><![CDATA[<p>Hi Jimmy<br />
there is an interesting thread which you may find useful</p>
<p><a href="http://groups.google.com/group/growing-object-oriented-software/browse_thread/thread/ef299b03620a4cef/f1dcfecb9969e174?lnk=gst&#038;q=Ioc#f1dcfecb9969e174" rel="nofollow">http://groups.google.com/group/growing-object-oriented-software/browse_thread/thread/ef299b03620a4cef/f1dcfecb9969e174?lnk=gst&#038;q=Ioc#f1dcfecb9969e174</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: bogardj</title>
		<link>http://lostechies.com/jimmybogard/2010/09/21/moving-containers-beyond-testability/#comment-2621</link>
		<dc:creator>bogardj</dc:creator>
		<pubDate>Wed, 22 Sep 2010 01:51:06 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2010/09/21/moving-containers-beyond-testability.aspx#comment-2621</guid>
		<description>@Scott

Thanks for the insight!  I do agree that lifecycle management shouldn&#039;t just be a switch that&#039;s flipped on or off.  Perhaps IoC is not the right name for everything that&#039;s going on in containers these days.</description>
		<content:encoded><![CDATA[<p>@Scott</p>
<p>Thanks for the insight!  I do agree that lifecycle management shouldn&#8217;t just be a switch that&#8217;s flipped on or off.  Perhaps IoC is not the right name for everything that&#8217;s going on in containers these days.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Scott Bellware</title>
		<link>http://lostechies.com/jimmybogard/2010/09/21/moving-containers-beyond-testability/#comment-2620</link>
		<dc:creator>Scott Bellware</dc:creator>
		<pubDate>Tue, 21 Sep 2010 19:18:06 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2010/09/21/moving-containers-beyond-testability.aspx#comment-2620</guid>
		<description>Jimmy,

The only real reason for moving lifecycle management away from a consumer is if the complexity of various lifecycle strategies reduces the cohesion of the consumer to a point where it&#039;s no longer possible to gain understanding of the service at a glance.

If the lifecycle of the dependency changes, then it&#039;s very likely that the semantics of the service will change. If those semantics are not part of the service abstraction, then it&#039;s possible that there&#039;s knowledge missing from that abstraction. This affects the design elegance of the abstraction. This is an essential consideration for the usability of code and for reducing relearning. And those are productivity and human workflow concerns, and these concerns, like testability, have huge influence on the shape of development cost depending on how they&#039;re tuned for the specific circumstances of a project.

When you say &quot;we don’t want to let the design of an implementation of a dependency affect the service&quot; I hear robotic thinking. You can say it well enough, but there&#039;s no real design principle that will universally serve the goals of software product development that supports that statement.

I&#039;m not saying that this kind of separation is necessarily bad, but it&#039;s also not necessarily good. There are circumstances that are served by this pattern, and circumstances dis-served by the pattern. It isn&#039;t the universal truth that static language pattern orthodoxy suggests.

Inversion of Control doesn&#039;t mean that we remove responsibility for wiring up dependencies from the service requesting or needing them. That&#039;s what &quot;Inversion of Control Framework&quot; means. That&#039;s more of a definition of dependency injection than Inversion of Control. Inversion of Control means that the control of creation of a dependency is removed from the module that uses the dependency. Lifetime management can certainly be combined in a framework with autowiring features, but that&#039;s not specifically what Inversion of Control means as a design quality.

As a side note, Inversion of Control tools and Inversion of Control principles seem to be increasingly mashed up into a single glob, and I think that the conglomeration of these two separate concerns creates some muddy water. You can see this in colloquialisms in the community where &quot;IoC&quot; has become synonymous with &quot;IoC tool&quot; or &quot;IoC framework&quot;.

Lifecycle management and Inversion of Control share some concerns, but they&#039;re not necessarily the same thing. Some frameworks smush these two concerns together, and do so to good effect. Some frameworks don&#039;t smush these two concerns together, and do so to good effect. Either approach can be as easily influenced by the way that the programming language works as by the way that the tool works. And the way that the tool works will reflect its operating environment.

This strikes me as an example of tools occluding principles. Not that you&#039;re not getting benefit from it in your work, but there&#039;s something being lost in not recognizing the precision in the subtlety in the difference between Inversion of Control and Inversion of Control Tool, and the tool&#039;s uses and practices, and the reasons for its design. If the tool informs your whole concept of the principle, the principle&#039;s whole meaning and power risks becoming something lesser than its entire potential.
</description>
		<content:encoded><![CDATA[<p>Jimmy,</p>
<p>The only real reason for moving lifecycle management away from a consumer is if the complexity of various lifecycle strategies reduces the cohesion of the consumer to a point where it&#8217;s no longer possible to gain understanding of the service at a glance.</p>
<p>If the lifecycle of the dependency changes, then it&#8217;s very likely that the semantics of the service will change. If those semantics are not part of the service abstraction, then it&#8217;s possible that there&#8217;s knowledge missing from that abstraction. This affects the design elegance of the abstraction. This is an essential consideration for the usability of code and for reducing relearning. And those are productivity and human workflow concerns, and these concerns, like testability, have huge influence on the shape of development cost depending on how they&#8217;re tuned for the specific circumstances of a project.</p>
<p>When you say &#8220;we don’t want to let the design of an implementation of a dependency affect the service&#8221; I hear robotic thinking. You can say it well enough, but there&#8217;s no real design principle that will universally serve the goals of software product development that supports that statement.</p>
<p>I&#8217;m not saying that this kind of separation is necessarily bad, but it&#8217;s also not necessarily good. There are circumstances that are served by this pattern, and circumstances dis-served by the pattern. It isn&#8217;t the universal truth that static language pattern orthodoxy suggests.</p>
<p>Inversion of Control doesn&#8217;t mean that we remove responsibility for wiring up dependencies from the service requesting or needing them. That&#8217;s what &#8220;Inversion of Control Framework&#8221; means. That&#8217;s more of a definition of dependency injection than Inversion of Control. Inversion of Control means that the control of creation of a dependency is removed from the module that uses the dependency. Lifetime management can certainly be combined in a framework with autowiring features, but that&#8217;s not specifically what Inversion of Control means as a design quality.</p>
<p>As a side note, Inversion of Control tools and Inversion of Control principles seem to be increasingly mashed up into a single glob, and I think that the conglomeration of these two separate concerns creates some muddy water. You can see this in colloquialisms in the community where &#8220;IoC&#8221; has become synonymous with &#8220;IoC tool&#8221; or &#8220;IoC framework&#8221;.</p>
<p>Lifecycle management and Inversion of Control share some concerns, but they&#8217;re not necessarily the same thing. Some frameworks smush these two concerns together, and do so to good effect. Some frameworks don&#8217;t smush these two concerns together, and do so to good effect. Either approach can be as easily influenced by the way that the programming language works as by the way that the tool works. And the way that the tool works will reflect its operating environment.</p>
<p>This strikes me as an example of tools occluding principles. Not that you&#8217;re not getting benefit from it in your work, but there&#8217;s something being lost in not recognizing the precision in the subtlety in the difference between Inversion of Control and Inversion of Control Tool, and the tool&#8217;s uses and practices, and the reasons for its design. If the tool informs your whole concept of the principle, the principle&#8217;s whole meaning and power risks becoming something lesser than its entire potential.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
