Recently, I have been trying to understand what is the difference between using the Service Locator "anti-pattern" and using the Castle Windsor container. I have found some info here and there on the Internet and I have summarized what I have learned so far in an unfinished blog post.
EDIT: Until now I have been thinking that Dependency Injection is all one would need to guarantee separation. But everywhere I look I see a push in the direction of containers such as Castle Windsor. I would like to clearly understand the reasons. Please... Explain this to me like I'm a 6 year old :)
Funny you should ask to have it explained like you were six years old; here's an explanation like you were five years old :)
everywhere I look I see a push in the direction of containers such as Castle Windsor
Frankly, I think the reason for that is that most people actually don't understand what Dependency Injection is, which means that instead of grasping the concept of Inversion of Control, they go looking for a replacement for the new
keyword they're already used to. Then they find a DI Container and (mis)use it as a Service Locator. Unfortunately, that's very easy to do.
This is the reason why, in my book, I explain all the DI concepts without coupling the explanation to any single DI Container. That's actually the majority of the book.
Service Locator and Dependency Injection are two fundamentally different attempts at achieving loose coupling. Service Locator has many disadvantages, and offers no advantages not also offered by DI. This is why I think it's safe to call Service Locator an anti-pattern.
You don't need a DI Container to use DI; in fact, I would say that unless you take a rather sophisticated approach, it's probably better to avoid one.
Well a service locator may just be a wrapper around a particular inversion of control container such as Castle Windsor. The point is that the only place in which your code should (ideally) reference the container is at your composition root.
Because inversion of control containers support dependency chaining, when you resolve your root type from the container, all of its dependencies will be injected, and any descendent dependencies.
If you then wish to create further types at run time, then you can use factories, which could also have a reference to your container if you wish to take advantage of the dependency chaining offered by the container and the container mappings of interfaces against implementations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With