
The inverse of IoC is Control  - ingridod
http://comoyo.github.com/blog/2013/02/06/the-inverse-of-ioc-is-control/
======
roam
Don't use IoC if you don't need it, but I'll explain why _we_ need it in our
case: some customers require different implementations.

That's where the DI part comes from -- to enable us to load a different
dependency based on the customer. Now, you could provide a different
bootstrapper class per customer or start building a mega class with a lot of
ifs-and-buts(elses), or you specify this kind of stuff in a configuration
file.

We opt for configuration files. We opt for IDEs that can interpret Spring
configuration files which means typos or incorrect dependencies do show up.
This allows us to swap out implementations in case shit goes down without
having to recompile, connect over a VPN to a remote desktop and hop through a
few more hoops to get our class file on the other side. If you're not running
your own apps on infrastructure you control (we should be so lucky), you have
to take this sort of stuff into account. I'd love to be able to say "This is
how stuff's set up. Deal with it."

(And when shit goes down, it is usually not at the place you were expecting it
to happen, which means all kinds of configuration options for your
bootstrapper would probably still fall short.)

~~~
zupatol
I agree with using IoC for different implementations, but I'm puzzled by those
who want to use it everywhere, because it supposedly makes the code easier to
test.

Guice is a nice IoC framework, but look at what they say on their website:

"Think of Guice's @Inject as the new new."

<http://code.google.com/p/google-guice/>

~~~
nkohari
Testing is kind of a side effect. When you design your code with IoC in mind,
you naturally will create more logical separations and avoid tight coupling --
which in turn will make your code easier to test. (Source: I wrote Ninject. :)

------
nahname
IoC is automating the code required to wire up objects that are properly
decomposed.

When you spend a long time learning how to effectively work with static
languages, a few things come out. Dependency inversion and composition.

Where does this leave us? It often means we have classes that need one or more
other objects when they are instantiated. This often results in chains of
objects. For example,

    
    
      new Repository(new SessionFactory(new Configuration()))
    

Writing that code is pretty painful. Rather than dealing with long chains of
dependencies, manually wiring everything up. You define mappings and let an
IoC container do it for you.

Why not just wire everything up manually in static functions and be done with
it? It is really hard to change static code and often impossible to test it in
a language like Java/C#. There is almost nothing you can do to test a piece of
code that calls out to User.find(1) in one of it's methods.

Why are there no IoC practices in ruby? Primarily because the second point is
no longer true (you can test everything easily). I still think there is merit
in knowing the dependency chain rather than just calling User.find(1) and
hoping that something somewhere conjures up a database connection and
configures everything correctly, at the correct time.

IoC is control and automation. Those are both powerful tools to any
programmer.

~~~
bborud
> new Repository(new SessionFactory(new Configuration())) > Writing that code
> is pretty painful.

If you think you are making things less painful by obfuscating the code
snippet above I would challenge you to think about what you are doing. The
above is incredibly clear. There is no doubt what is happening and if you
screw up the compiler will yell at you.

If you obfuscate it through annotations and force readers of your code to try
to reason about how the system will behave runtime, you have added exactly
zero value. You have only degraded the readability and understandability of
the system.

A little extra typing never killed anyone.

~~~
nahname
You don't annotate anything. It simply becomes the following,

    
    
      ...
      public Repository(ISessionFactory factory)
      ...
    

The repository never knows about IoC or where things come from. Nor should it.

~~~
bborud
Oh yeah, because pure magic makes it so understandable.

------
VexXtreme
I have found that in a lot of cases IoC ends up being completely misused and
abused in really horrible ways. One of the more common antipatterns I
encounter is creating an interface for every single thing in the application
("because hey, the implementation might change and it'll be easy to swap
out"). No, if you're building a webshop or a task management application,
abstracting and injecting your business logic or domain objects is as stupid
as it gets.

I always keep hearing this argument "but something will change". No, it won't.
Is it really worth introducing all this boilerplate nonsense into the
application just for the off chance of something changing at some point? And
even if that happens, don't you think you're better off just doing whatever
modifications are necessary vs. putting all this crap into your application?

The only scenario where I've found IoC to make sense is when an application
depends on a module and that module REALLY needs to be swapped out with
another one. I once had that with a stock market analysis application that
depended on X service for data feeds, but X service suddenly stopped working
and I could just inject Y service instead without having to change anything
else. But even in that case IoC container would've been redundant as plain old
DI does the job just fine. That was the only thing in the application that I
wrote that way because I didn't want to hard code an external dependency (that
I have no control over) into my application.

But what I keep encountering is the cargo cult approach to programming where
IoC is done for the sake of IoC and everything is injected for the sake of
being injected, with no rational explanation as to why. It's quite terrible
really.

~~~
specialist
> creating an interface for every single thing in the application

Ditto turning everything into a "service" a la WSDL and now SOA. CORBA lives!

------
wcoenen
It turns out that there is a problem with instantiating everything manually in
main if you have a lot of components: it becomes non-trivial to figure out the
order of instantiation.

This problem will typically surface whenever you add a dependency between
existing components. If the dependency is currently instantiated after the
changed component, it will have to be moved up so it is instantiated earlier.
But then it turns out the dependencies of _that_ component also need to be
moved up etc.

To deal with this you then have to calculate a "dependency rank" for each
component (i.e. 0 for components without dependencies, and x+1 for components
where the max rank among the dependencies is x) just to figure out a new order
that works.

This problem doesn't exist if you use a dependency injection container with
configuration in code, because the order of component registration is not
important.

~~~
mercurial
Yeah, what you'd end up recreating is a directed graph of dependencies, and
make it needlessly fragile.

You don't need the big machinery for smaller projects, though. What I end up
doing in Python is having builder methods in __init__.py which can instantiate
objects from the package (possibly instantiating objects from sub-packages in
the process), with any dependency not in the package or sub-packages being a
parameter. You get some granularity in your dependency injection, you avoid
magic and you don't _need_ to use the builder methods if you don't want to. It
may not scale to large class hierarchies, but for mid-size projects it's fine.

------
jt2190
According to Martin Fowler [1], Inversion of Control is an alternative to
using a Service Locator:

    
    
      > In the Java community there's been a rush of lightweight
      > containers that help to assemble components from
      > different projects into a cohesive application.
      > Underlying these containers is a common pattern to how
      > they perform the wiring, a concept they refer under the
      > very generic name of "Inversion of Control". In this
      > article I dig into how this pattern works... and
      > contrast it with the Service Locator alternative. The
      > choice between them is less important than the principle
      > of separating configuration from use.
    

[1] <http://martinfowler.com/articles/injection.html>

(edit: Also, the Spring Framework has had alternatives to XML configuration
for years: [http://www.ibm.com/developerworks/webservices/library/ws-
spr...](http://www.ibm.com/developerworks/webservices/library/ws-
springjava/index.html))

------
unwind
I'm pretty sure IoC here refers to "inversion of control"
(<http://en.wikipedia.org/wiki/Inversion_of_control>). I had to look it up
though, I find it a bit silly that even the original article doesn't spell
this out in the first sentence.

I guess it's super-obvious from context (and the claim of the title) so I
guess I'm just not very smart, today. Oops.

------
gertgoeman
I think the title's a bit misleading though... This guy is obviously talking
about dependency injection.

Things like callbacks, observers, events, ... are also types of IoC.

------
skrebbel
A lot of people in this thread point out that modern IoC containers are good
because they can automatically wire up your component tree for you, which is
such a hassle to figure out and code manually in a place like main().

This component tree is the core of your application architecture. If the
classes are well named, a big part of the application structure should become
clear to someone reading your hand-coded main(). Also, if this is such a pain
to figure out, why are you using components at all?

I find the idea of splitting functionality into classes but having no clue how
these classes relate to one another a tad scary, really. I usually have a
picture of the entire component tree on the wall near our team. It's great for
pointing at when discussing design, and it's trivial to draw.

Writing a main() really shouldn't be more work than copying that picture into
code. A tad tedious, but never more than an hour of work. Why add all that IoC
complexity for saving 60 minutes. ? Why replace an excellent starting point
for new team members to dive into code by a library that does magic?

Deployment variability doesn't cut it for me. Nearly always, you can foresee
which things may need to be variable, and which aren't. Explicitly make those
configurable, instead of all classes and their arguments like you'd do in
Spring. In your main(), just if or switch over these config settings to
instantiate the right class. Again, very readable, and you strongly convey
intent to code readers.

------
jhartmann
Sure you have to use it where it makes sense, but IoC containers and
frameworks like Spring can really make things easier. If you have to talk to
anything complex (pick your messaging poison), need to keep transactions
across these items, need to run under multiple different web containers and
swap out configuration you are going to have some messy code to handle all of
this sort of stuff. For enterprise integration problems I will pick Spring any
day. For instance I can write a complex messaging bridge between two different
messaging systems using nothing but some xml configuration. The mess of doing
all the JNDI lookups, getting all my XA transactions right, handling firing
messages after certain things happen all can be done without explicitly
putting things all over the code. The beauty of IoC containers and AOP
programming is that you can mix in a well tested piece of code across all your
application with minimal effort. You can mixin authentication, transaction
management, request cleanup, caching, etc. without making major changes to
your app.

I know there are many people here that might crucify me for the opinion but I
call bullshit. They just have never had to work on something sufficiently
complex where IoC and frameworks like Spring can become a huge time savings.
Obviously with any tool you have to make sure you don't chainsaw off your leg,
and its really stupid to do certain things with any tool. The black magick of
aop and IoC can make reasoning about things a little harder, but the shear
power of the tool makes solving hard problems in complex applications
tractable. Try auditing transaction management in an application with 10
thousand tables written by hundreds of people of various experience levels. Or
just use spring transactions and inject the well tested behavior across the
entire application.

------
bborud
Most places I have seen DI frameworks being used, they solve a problem the
programmer shouldn't be having in the first place.

~~~
filpen
Interesting. Do you mind expanding on this? What problems were they trying to
solve?

~~~
bborud
I don't buy that wiring up code explicitly in plain old java without the help
of an injection framework is as painful as some people seem to think -- and if
it really is: I suspect the reason is bad design or that they just haven't
given the problem much thought. That happens.

 _If_ people need the assistance of a framework to wire up their application,
it is probably because the API design sucks ass and there are too many moving
parts the programmer is forced to pay attention to. (And when I say API
design: all code design is about APIs -- every time you create a class or an
interface you are creating an API of some sort). Good APIs hide and abstract.
And good implementations take care of things you don't need to see or know.

And I say _if_ , because most of the time, applications are not so complicated
that you need help to manage wiring them up. Most of the projects I have
worked on the past 15 years can usually be wired up in _less_ than 40-50 lines
in a Main.java. I have worked on some projects that needed considerably more,
but interestingly, managing that code was _never_ a problem.

Explicit wiring you can read from start to finish beats vague declarative shit
that you _may_ be able to figure out if you pay close attention.

~~~
filpen
Thank you for clearing that up, much appreciated.

I also noticed that most of the time the container tends to be used as a
Service Locator indiscriminately around the code base, which tends to create
more problems than it solves. On the other hand, I think it is a good
refactoring step if your plan is to eventually move all the composition logic
at the entry point of the application.

Coming from .NET, I tend to do the wiring as close as possible to the entry
point as well, but I still use a container because it makes object lifecycle
management much easier, and with convention over configuration it is trivial
to associate interfaces to implementations: this not only reduces wiring up
code for complex applications to a few lines, it also makes the rest of the
application container-agnostic, which is quite cool.

~~~
bborud
> t also makes the rest of the application container- > agnostic, which is
> quite cool.

Not least because containers have a tendency to fall out of fashion. For
instance if you suggest using Spring for a large project now, people will
queue up to punch you like a meat pinata.

------
_pmf_
I found that a sweet spot between wiring-by-code and wiring-by-container-and-
configuration-dsl is using a dynamic language for wiring (say, Rhino, which is
very lightweigth): you have the flexibility of wiring-by-code and can easily
change the configuration purely by deployment (without recompiling anything)

~~~
RyanZAG
Just curious, but what's wrong with recompiling? If you make a typo in your
Rhino file on production, your whole app is now failing. Surely it makes more
sense to just take the 5 minutes to recompile (or hopefully 30 minutes and
test it out in dev first)?

I don't really understand what problem using the dynamic language is trying to
solve there, and you've just added in a whole new branch of different code
that won't work with static analysis, and will need to be maintained in
addition to your normal code.

~~~
_pmf_
In my case, I have an Eclipse-based product (toolchain for embedded
development) that must be reconfigured per client or even per project (on
site); i.e. it is more about dynamically creating very specific variants of a
product. Using client/project-specific plugins would be the alternative for
me, but this has much more overhead.

~~~
RyanZAG
Are you not packaging un-used code into your embedded binaries then? You'd
also have to manually test the reconfigured client before deploying it, I
think.

Seems better to make an automated build system off a database of
configurations - a simple sql table with the different settings that could
automatically build versions for all clients. You'd get static compile time
checking of each build, and it would allow for easily running automated tests
against each client's version.

So you'd end up with no un-used code, a database of client configuations, and
static compile time checking. Seems win-win.

Sorry for 'assuming your problems', feel free to ignore. Interesting situation
though.

------
galaktor
Younger IoC frameworks aim for configuration in code, allowing for a much more
dynamic usage.

Examples (c#) * Autofac * Ninject

~~~
jakubholynet
We use Guice which also allows that. But that doesn't address some of the key
points he makes, such as \- runtime x compile time wiring \- wiring is based
on types so injecting differently set up instances is difficult (we have a
hell of Providers and different annotations to pick the right kind of instance
injected) \- non-transparency of the wiring process (sice it is performed by
the magical IoC container)

I agree with a lot of what he writes. At the same time I believe there are
cases where I would appreciate some kind of automation for wiring (f.ex. if I
want a fresh instance for each session or request). And there are certainly
cases when runtime wiring - as in the mentioned case of plugins - is useful.

~~~
galaktor
I'm mostly familiar with Autofac, and there are many other ways to wire your
app other than by type

* by interface * by enum * by parametrized constructor (Func<..>) * by (arbitrary) string * per process / per thread / per whatnot

------
InvisibleCities
First of all, the author doesn't hate IoC and Containers, he hates XML
registration (with good reason). I can't say anything about Java, but in C#,
when you use modern IoC frameworks like StructureMap and AutoFac, all
registration of components takes place in code, using generics and lambdas.
This allows you to easily wrap your services in interfaces, de-coupling code
and making things much more testable, especially if you use a good mocking
framework like Rhino. When you combine DI/IoC with ideas like the Onion
Archtecture ([http://jeffreypalermo.com/blog/the-onion-architecture-
part-1...](http://jeffreypalermo.com/blog/the-onion-architecture-part-1/)),
writing readable, testable, flexible, maintainable applications becomes
supremely easy.

------
FreshCode
Do I understand correctly that the writer's main concern is that DI
configuration is done in XML files, or that configuration takes place at run-
time, instead of compile-time?

~~~
filpen
I also don't get what the author's issues are. Half of the article seems to be
against XML configuration, and I don't come from a Java background but it
seems that there are containers for Java that do not necessarily require an
XML configuration, or is it not the case?

~~~
twistedpair
Hmm... guess the author is not familiar with @Autowired, @Resource,
@Component... etc. You don't need XML fun. And, he complains about 2 of the
same type... behold @Autowired(name="bar"), @Autowired(name="bah"). Miracle?
No, just DI.

------
tkellogg
Maybe you should be using C#. As a community we fight hard to reject xml
configuration, favoring type safe lambda expressions instead. Anything that
ignores the type safe guarantees that C# offers quickly does. There was
briefly a spring.net but it quickly died for this reason.

~~~
SideburnsOfDoom
Agreed. Is the author's problem with IoC or with XML config? hard to tell, but
they're really not the same thing.

IoC containers in C# have rejected config in XML, in favour of config in code,
using either generics and lambdas (e.g. register
Component.For<IFoo>.ImplementedBy<Bar> ) or via scanning (e.g.
AllTypes.FromAssembly(x).BasedOn<Foo>().WithService.FirstInterface() ).

Spring.net was an exception and in comparison it really sucked.

IoC Config in code is much better. But can't this be done in java too?

~~~
mercurial
That's what Guice does, and newer versions of Spring too (though I'm not sure
if you can go full Java and drop the XML entirely).

------
michaelochurch
Java culture (IDE-dependence, AbstractFactoryVisitorFactory patterns, Maven
and XML monstrosities) is hideous. It's based on the idea that reading code is
a lost cause. You can no longer trust code, so you need all these wonky tool
configurations to compensate for the fact that you're trying to make an army
of inept programmers build something that is (unless it fails) going to become
the next generation's legacy bloatbomb.

~~~
twistedpair
Always love all the Java hate on ycomb. I'm not sure how a dynamically code
hotswapping Ruby app with 10k classes and 1k domain objects works, but I
suspect many of the same patterns emerge as have been solved in Java.

~~~
michaelochurch
Large single programs should almost never exist. There are exceptions, but the
typical bloated business app is not one of them.

Managerial idiots like overambitious single-program IT projects because it
makes it easier to allocate "headcount" when the programmer-to-program
relationship is inverted (many programmers to one program, instead of the
right way, which is one programmer working on many programs).

The truth is that _every_ programming approach fails you when you do this. For
one example, static typing fails on versioning issues and compile-speed
problems, while dynamic typing ends up with silent failures and integration
bugs.

There is one case I can think of where large single programs work, and that's
in the database space. You have a lot of requirements (transactional
integrity, concurrency, performance in a heterogeneous world) and they all
have to work together. It has also taken _decades_ for some of the brightest
technical minds out there to get it right.

~~~
hythloday
Large networks of small programs fail in exactly the same way: static typing
fails on versioning issues (an RPC call carries inherently less type
information than a function call) and compile-speed problems (compiling 200
small services can take just as long as compiling one behemoth). We also don't
have mature tooling for the "network program" you're talking about.

I don't know what your metric of "large program" is, but AAA games often weigh
in at 10-100 million lines and are typically architected as a single large
codebase with auxiliary small programs, and doing them any other way is not a
sensible approach.

------
martinced
IoC is an usual technique and buzzword from the C#/Java + XML + ORM + SQL
hell.

There are many programmers working in the Real-World [TM], powering great apps
and webapps, using saner technologies who have never heard of the term.

I wrote my own IoC container (a clone of picocontainer IIRC) to see what the
fuss was about when the term started to become fashionable. No big deal. It
can help reproduce various states (for examples in testing environments) to
more easily test your app.

Sure people will say: "You need an IoC container to do DI, what you're talking
about is DI, not IoC".

But, fundamentally, it is once again related to "state" and the difficulty to
recreate a state in {dev,pre-prod,prod,whatever}.

So it's once again a "solution" missing the bigger picture.

Sure, people stuck in the "stateful OO" mindset will love IoC and, honestly,
if you're stuck in such an hell IoC can be useful. With the caveat that IoC
makes it much harder to reason about what's going on when some shit hits the
fan.

"Every problem can be solved with another layer of abstraction, except the
problem of too many layers of abstraction"

But there's light at the end of the tunnel. There are other ways to design
great apps.

And to make you feel even better: being "smart" as nothing to do with knowing
every technology out there ; )

~~~
SideburnsOfDoom
Are you saying that IoC implies that you also must use XML and an ORM? That
really isn't so.

