Website Loader
Fork me on GitHub
Homepage Top Icon

TYPHOON

A new dependency injection container for Objective-C

Status? It's ready to use!

Homepage Bottom Icon

WHO IS BEHIND IT?

Read More About Us

"My passion is to present complex requirements in a way that is simple and intuitive to the user." -- Jasper Blues

Meet The Contributors

Typhoon - The Dependency Injection Framework for Objective-C and Cocoa

Our Team

Jasper Blues

Author

As a kid, I used to build radios, boolean circuits, amplifiers and things out of spare parts. Today, I enjoy the creative utilization of technology to achieve solutions in business.

Our Team

Jeffrey Roberts

Feedback and Testing.

I am a highly experienced professional software developer always focusing on improving my craft.

Our Team

John Blanco

XML Library

There is no greater feeling than creation, and no finer creation than a great app.

Our Team

AskOvi

Web Development

Askovi offers web design, web development, internet marketing and IT services for businesses and organizations all across the globe.

READ MORE ABOUT TYPHOON

Read More About Us

Find out why Typhoon is cooking up a storm
Everything you need to know in the following description...

Description

What is Dependency Injection?

Dependency Injection

Many people have trouble getting the hang of dependency injection, at first. And I think part of the problem is that it is actually so simple that we're inclined to look for something more complicated. "Surely that there has to be more to it?!", so to say. So, with that in mind, imagine that you're writing an app that gives weather reports. You need a cloud-service (excuse the pun ;) )

to provide the data, and at first you go for a free weather report provider, but in future you'd like to integrate a weather service with better accuracy and more features. So, as do all good object-oriented developers, you make a WeatherClient protocol and back it initially with an implementation based on the free, online data provider.

Without dependency injection, you might have a View Controller like this:

-(id) init 
{
 self = [super init];
 if (self) 
 {
 //The class using some collaborating class builds its own assistant.
 //it might be one of several classes using the weatherClient. 
  _weatherClient = [GoogleWeatherClientImpl alloc] initWithParameters:xyz];
 }
 return self;
}

The thing with this approach is, if you wanted to change to another weather client implementation you'd have to go and find all the places in your code that use the old one, and move them over to the new one. Each time, making sure to pass in the correct initialization parameters. A very common approach is to have a centrally configured singleton:

_weatherClient = [GoogleWeatherClient sharedInstance];

With either of the above approaches, in order to test your view controller, you now have to test its collaborating class (the weather client) at the same time, and this can get tricky, especially as your application gets more complex. Imagine testing Class A, depends on Class B, depends on Class C, depends on .... Not much fun! Sure, you could patch out the singleton with a mock or a stub, but this requires peeking inside the code to find the dependencies. Besides taking time that could be better spent else-where, this ends up becoming "glass-box" testing as opposed to "black-box"

testing. Isn't it better to be able to test the external interface to a class, without having worry about what's going on inside? And you have to remember un-patch again at the end of the test-case or risk strange breakages to other tests, where its difficult to pin-point what the real problem is might be. So with dependency injection, rather than having objects make their own collaborators, we have them supplied to the class instance via an initializer or property setter.

And now, it simply becomes:

-(id) initWithWeatherClient:(id<WeatherClient>)weatherClient
{
 self = [super init];
 if (self) 
 {
     _weatherClient = weatherClient;
 }
 return self;
}

Is that all they mean by 'injected'?

Yes it is. Right now, you might be thinking "Geez! That's a pretty fancy name for something so plain." Well, you'd be right. But let's look at the implications on our application architecture: If you do this with significant collaborators throughout your app, it means that the GoogleWeatherClientImpl is now declared in a single place - the top-level assembly, so-to-speak. And all of the classes that need to use some kind of id<WeatherClient> will have it passed in. This means that:

  • If you want to change from one implementation to another, you need only change a single declaration.
  • Classes are easier to test, because we can supply simple mocks and stubs in place of concrete collaborators. Or the real collaborators, but configured to be used in a test scenario. (One of my design goals).
  • It promotes separation of concerns and a clear contract between classes. Its easy to see what each class needs in order to do its job.
  • Your app is easier to maintain and can accommodate new requirements.

Your Dependency Injection Options

If you proceed with the Dependency Injection pattern (assuming you're not one of the remaining "flat-earthers", who believe that Objective-C somehow magically alleviates the need for common-sense: "Oh, I don't do DI, I use swizzling class-clusters!"), then there are basically two options:

You can do dependency injection without a framework to help you. It is simple after all, and in fact I recommend you do this, at least as an exercise in software design. And yes, it is certainly possble that this will be adequate. But, I think its good to have help, if you can get it. You can also write tests without a test framework, mocks with out a mock library, software without a compiler.

So, going down the framework route, there's been quite a lot of action in Objective-C land, over the last three years. In fact, there are now around 15 Dependency Injection frameworks, many following in the footsteps of Google Guice. The authors have done a great job (Objection is especially good). However, I wanted an approach that allows the following:

Design Goals & Features

Features

Dependencies declared in any order. (The order that makes sense to humans).

Allows both dependency injection as well as configuration management

Ability to configure components for use in Test vs Production scenarios

Encourages polymorphism and makes it easy to have multiple configurations of the same base-class or protocol.

Supports both auto-wiring by type and wiring-by-reference.

Application assembly is encapsulated in a convenient document.

Non-invasive. Its not necessary to change any of your classes to use (or stop using) Typhoon.

Supports both initializer and property injection.

Flexibility - different approaches of dependency injection for different scenarios.

Works with the code-completion and refactoring tools in your IDE.

Lean - It has a very low footprint, so is appropriate for CPU and memory constrained devices.

Typhoon is being used by Mod Productions
Two very exciting applications currently in development. Stay tuned for release.

SAMPLE APPLICATION

Read More About Us

Explore how an app is built with Typhoon
Code is so much neater

Pocket Forecast

An example application built with Typhoon

FEATURES

Returns weather reports from a remote cloud service.

Caches weather reports locally, for later off-line use.

Stores (creates, reads, updates deletes) the cities that the user is interested in receiving reports for.

Can use metric or imperial units.

Running the sample

Clone this repository, open the Xcode project in your favorite IDE, and run it. It'll say you need an API key.

Get an API key from WorldWeatherOnline

Using your API key, set the application configuration.

Run the App in the simulator or on your device and proceed to the exercises here.

Start using Typhoon! Check out the User Guide.

Typhoon is nice on Xcode, even better with AppCode

appcode

It's Q&A Time!

Read More About Us

Got any questions?

Frequently Asked Questions

Something's not clear? Check Below!
We tried to answer any question you might have.

Q. Compatibility

A. Typhoon can be used with OSX and iOS. It has not been tested with GnuStep. It was built with ARC, but should also work with garbage collection and 32 bit environments.

Q. Isn't Objective-C a dynamic language?

A.Yes, and I love categories, method swizzling, duck-typing, class clusters, associative references in categories, and all that cool stuff. None of these are replacements for DI. They were certainly required in order to implement the kind of DI container I wanted (look at the code).

And to quote Barry Wark, of Physion Consulting -- "After re-reading Brad Cox's paper, I agree... he is a hero. But a system that allows late binding is not the same as DI".

I don't know of an expert arguing that Dependency Injection is not required, although in the case of the Ruby programming language the current consensus is that you don't need a library to do it. . . Jim Weirich creator of poular tools like Rake and Rspec did create a dependency injection container called Dim.

Q. Doesn't Dependency Injection Just Shift Coupling Elsewhere?

A.If by elsewhere you mean from everywhere to one place, and (in the case of statically compiled languages) from compile-time to runtime . . . then yes! That is the purpose of dependency injection.

Q. Is this all of Spring in Objective-C?

A.No, its just a light-weight, Spring-style DI container. I personally think that Spring is an excellent DI container, and it's huge popularity and availability in several languages says so. With regards to other Spring Portfolio products: some I like, and some I don't.

Q. Doesn't XML Suck?

A.No, not really. It gets the job done. Please read this. If you don't like it you can use the block-based assembly (recommended) or auto-wiring.

Q. How much resources does the container use on my device at start-up.

A.Profiling results coming soon. In the meantime - not much. Certainly less than parsing a web page with a UIWebView. About the same as parsing a JSON response from a network request. . . Afterwards, the resulting efficiencies with memory management and prototype-scoped view controllers will pay off.

Q. Can Typhoon inject view controllers?

A.Yes both initializers and properties, xibs or no xibs. You can also use it to build complex views, if you like. Take a look at the sample app.

Q. What's with the name Typhoon?

A.Over the 2012-13 new year, I had a family holiday booked at one of our lovely beaches. . but it turns out there was a late-in-season Typhoon. So I stayed home and wrote this instead. . . Also it was inspired by the Spring Framework. In temperate climates we have Spring, Summer, Autumn & Winter. But here in the Philippines we have hot-season, sizzling-hot-season and Typhoon-season ;).

CONTACT US TODAY

Read More About Us

Help build this community
Get in touch with me below!

Get In Touch

Feature Requests and Contributions are very welcome!

THANK YOU!
We have received your message.
Contact Name
Contact Email
Phone Number
Website
You're interested in?
How did you hear about us?