Init(args) is a Dependency Injection solution for Unity, designed from the ground up to seamlessly blend in with the traditional Unity workflow that you are well-acquainted with.
What is Init(args)?
Init(args) is a dependency injection framework for Unity, built with a keen focus on ensuring all aspects of the toolset blend in seamlessly with the native editor experience.
What problems does Init(args) solve?
The Unity Editor’s scene-based workflow is a powerful tool, and the ability to drag-and-drop references to fields in the Inspector is already a great foundation for injecting dependencies to Objects! As such, the aim with Init(args) has not been to reinvent the wheel on this front, but rather to fix various shortcomings it has and unlock its full potential.
In vanilla Unity, all components are responsible for finding references to the objects they depend on. One way to accomplish this is by adding serialized fields, which enables users to assign references using the Inspector. As cool as this is, it has its limitations, and can’t be used in every situation:
Can’t assign Objects to interface fields.
Can’t assign Objects across scenes or prefabs.
Dragging the same managers to components again and again is laborious.
To swap a manager to a different one you have to manually update references in all components.
Can’t assign dynamic values, which makes working with things like localized texts, addressable assets and randomized values more difficult.
Due to these limitations, components often have to combine the usage of serialized fields with other means of resolving dependencies: singletons, GetComponent, GetComponentInChildren, FindObjectOfType, FindWithTag, static methods… and so on. This hodgepodge way of fetching the dependencies of components also has its own problems:
It can add a lot of unnecessary noise to your components’ code.
Dependencies can be hidden anywhere within the code.
Dependencies are usually hardwired to specific classes.
Dependencies are located using hardwired search methods.
And even where you are able to piece together a relatively dignified component using some combination of these methods, it will still most likely be virtually impossible to write any unit tests for it!
Init(args) can resolve all of these issues for you.
Keeping It Simple
With Init(args) you won’t have to spend large amounts of time learning about perplexing concepts, like bindings, containers, decorators or contexts… in fact, you can use just the Inspector to fulfill most of your dependency injection needs! – but with so much more flexibility than ever before.
And what about when you do want to initialize objects with arguments in code? Here as well, you can make use of all the commands you are already familiar with, like AddComponent and Instantiate – just with the added ability to pass in some arguments.
This small but significant change means that your components are no longer closed islands, black boxes with hidden dependencies; when you instantiate a component with its dependencies, you can feel assured that it will work. This also means that writing unit testing for your components becomes so frictionless and easy, that creating them can become downright addictive!
Pure Dependency Injection