I have a thorough background in .NET but have been using Python and Ruby lately. I found myself pondering how to best provide dependencies to objects that need them in Ruby.
At first thought, I did not actually think DI and IoC frameworks would be required to interact with dependencies because of the leniency of dynamic languages (a la redefinition, mixins, stubs, etc). Then, however, I came across answers as to why DI/IoC frameworks are not needed in dynamic languages. The reasons provided don't sit too well with me. I'm hoping I can see an example that might clear things up.
In Why are IOC containers unnecessary with dynamic languages we see that a dependent class (non-injected), say X
, can be stubbed or mocked in a test. Sure, but that requires us to know our System Under Test
is depending on something called X
. If our System Under Test
suddenly depends on N
instead of X
, we must now remember to mock N
instead of X
. The benefit of using DI is we'd never accidentally run a test with production dependencies because we'd always be passing in mocked dependencies.
In everyone's favorite goto resource for all things DI + Ruby, LEGOs, Play-Doh, and Programming, we see an example of subclassing a System Under Test to mock dependencies. Alternatively, we can use constructor injection. Okay, so B
depends on A
. We call B.get_dependency
which provides B
with an instance of A
. But what if A
depends on N
which depends on X
? Must we call get_dependency
on each successive object in the chain?
Fabio mentions we can just use mixins/monkeypatch. So X
is mixedin to N
. But The issue is what if X
depends on A
which depends on B
? Do we just use mixins for every dependency down the chain? I see how that can work but it could get messy and confusing quickly.
Side note: Many users say DI frameworks are not needed in dynamic languages. However, Angular.JS has really benefited from implementing a pretty solid DI system. Angular is built on JavaScript, a dynamic language. Is this approach comparable to Ruby or Python?
Please keep in mind I'm not saying I want to force DI/IoC into Ruby, Python, etc.
Dependency Injection can exist between two objects, for instance, a flashlight and a battery. The flashlight needs the battery to function. However, any changes made to the battery, such as switching it with another brand/set of batteries, does not mean the dependent object (flashlight) also needs to be changed.
Two popular dependency injection frameworks are Spring and Google Guice. The usage of the Spring framework for dependency injection is described in Dependency Injection with the Spring Framework - Tutorial. Also Eclipse RCP is using dependency injection.
Types of Dependency Injection The injector class injects dependencies broadly in three ways: through a constructor, through a property, or through a method. Constructor Injection: In the constructor injection, the injector supplies the service (dependency) through the client class constructor.
In object-oriented programming (OOP) software design, dependency injection (DI) is the process of supplying a resource that a given piece of code requires. The required resource, which is often a component of the application itself, is called a dependency.
While many think DI is not needed, I agree with you, that it's indeed needed a lot; but sometimes it gets mixed with other techniques Python provides. I suggest you to look at venusian, it may kind of verbose, but if you come from .NET you'll see the relation. In a word: venusian allows you to annotate your methods without changing their behavior. Thus, you may write venusian decorators so that your unit-testing does not get affected. Pyramid uses venusian to annotate views, for instance.
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