Michael Long
2 min readSep 11, 2019

--

As someone who’s used DI systems and whose wrote his own (Resolver), I applaud any and all attempts to simplify and promote the concepts.

That said, I think there’s a couple of things to clear up.

First and easiest, your biggest knock against property injection lay in implementing the feature as an optional, with the corresponding increase in code complexity. This could be solved by making the property implicitly unwrapped, but regardless the fact remains that, either way, the code isn’t going to work correctly if the property isn’t provided, and that is the bigger issue.

Second, constructor injection may be preferred, but one can end up with a lot of boilerplate code and, somewhat worse, such a design exposes the internals of our object to those who might wish to use it.

That’s why people use DI systems like Swinject and Resolver, and why annotation systems like that described in Swift 5.1 Takes Dependency Injection to the Next Level are beneficial. These system deliver completely initialized objects to the objects that need them, and without exposing implementation details.

Finally, both constructor and property injection make your dependencies clear and that’s good. In either case, however, your object is still tightly coupled to ImageController. In fact, whether a shared instance or injected, it’s still bound to a single specific implementation of the ImageController object.

In short, the problem still isn’t solved.

The real solution to reducing coupling lies in injecting and binding interfaces, and in Swift you do that with protocols. To borrow from the 5.1 article…

protocol ImageResizing {
func resize(image: UIImage, size: CGSize)
}
class NoteController { @Injected var imageResizer: ImageResizing func createNote(text: String, imageThatNeedsResizing: UIImage) -> Note? {
let resizedImage = imageResizer.resize(image: imageThatNeedsResizing, size: CGSize(width: 10, height: 10))
return Note(text: text, image: resizedImage)
}
}

Now some object that implements the ImageResizing interface is injected automatically. It might be (and probably is) an ImageController, but it may not be.

Regardless, your NoteController doesn’t care and as long as something that provides the proper functionality is provided the coupling to the rest of the application is dramatically reduced.

--

--

Michael Long
Michael Long

Written by Michael Long

I write about Apple, Swift, and SwiftUI in particular, and technology in general. I'm also a Lead iOS Engineer at InRhythm, a modern digital consulting firm.

Responses (1)