00:00:06.720
So now, first, I assume that most of you really know what dependency injection is. Just a quick refresher: dependency injection, if you boil it down to a very simple sentence, means an object does not take what it needs; it gets what it needs. I know that's not a very scientific or academic definition, but I think it serves the purpose.
00:00:15.519
If you look at my example, take the happy service. The happy service can only tell you if you're happy, not depending on the weather. If it has a weather service, you need to initialize the weather service for the happy service. In this approach, you have the weather service in the constructor for the happy service. However, please don't do that, as it's problematic for testing.
00:00:39.920
When you want to test the happy service in isolation, you would automatically be testing the weather service as well. Those two classes should not be tightly coupled. As we all know, tight coupling is undesirable. One way to solve this issue is to inject the weather service instance into the constructor of the happy service, ensuring that your happy service always has access to it. This makes testing easier, as you can simply create a mock weather service that always returns true or false, allowing you to test your happy service independently from the weather service.
00:01:20.400
Now, dependency injection in Ruby is an interesting topic. There are actually a few frameworks available, such as Needle, which was recently started by a guy at GitHub, and there's Mindy. However, if you search for dependency injection in Ruby, you'll find that most people say you don't need it, as Ruby has some built-in functionality to handle this. Quite honestly, I do not completely agree; I think there is a place for dependency injection.
00:01:47.280
I came up with my own little framework for dependency injection, which is built upon a gem called Method Decorator. You can see how I use this 'plus requires' in the initialize method of my happy service. The 'plus requires' comes from this awesome Method Decorator gem. If you aren't familiar with it, please check it out; just go to GitHub and search for method decorators—it will be the first result. It's created by a guy named Michael Fairly, whom I deeply admire.
00:02:15.599
This little 'plus requires' method is executed before and after you call the constructor for the happy service. This means that when you initialize my happy service, it will automatically get an instance variable called weather service that is set with a weather service. It will also receive a setter for that weather service, so you can change it on the fly. You might then wonder where I obtain my weather service from. I retrieve it from the initialize method of my weather service. I use 'provides' around it, which informs my dependency injection container—totally hidden from you—that this is my weather service.
00:02:49.120
You might also notice that in the weather service, I employ yet another location service. In my signing method, I ask my location service, 'Hey, is it sunny?' If we are in Boulder, the answer is yes; it's sunny. Testing your happy service is now super easy. You can mock out your weather service, create an instance of the happy service, set the weather service instance variable with your mock, and test whatever you need. This approach allows for loose coupling between the two services and enhances testability.
00:03:10.480
There are a few disadvantages to consider. Some people might say it's harder to debug because you may not know where your other service comes from. It might feel like magic that appears out of thin air. While that is a valid point, I believe the advantages outweigh this minor disadvantage. However, there are a few limitations that I am currently working around. For instance, each class needs to have an initialize method, allowing you to implement the required provides around it, and each class must extend the service provider module.
00:03:54.640
And that's it! Here’s my GitHub and my contact information. Please feel free to send me any questions you may have via email. I think we have about 30 seconds left for questions.
00:04:31.320
Sweet.