Over 11,000 five-star assets

Rated by 85,000+ customers

Supported by 100,000+ forum members

Every asset moderated by Unity

1/17
Init(args) is a next-gen DI framework for Unity, that combines exceptional flexibility with unprecedented ease-of-use.
Render pipeline compatibility
The Built-in Render Pipeline is Unity’s default render pipeline. It is a general-purpose render pipeline that has limited options for customization. The Universal Render Pipeline (URP) is a Scriptable Render Pipeline that is quick and easy to customize, and lets you create optimized graphics across a wide range of platforms. The High Definition Render Pipeline (HDRP) is a Scriptable Render Pipeline that lets you create cutting-edge, high-fidelity graphics on high-end platforms.
Unity VersionBuilt-inURPHDRP
2021.3.45f1
Compatible
Compatible
Compatible
Description

Init(args) in a nutshell


Init(args) is a dependency injection framework for Unity, unlike any other you've experienced before... It gives you all the mind-opening flexibility that a great DI framework should, but does all of this with ease-of-use that goes way beyond that of other DI frameworks!


Init(args) is so powerful that it will help you effortlessly transform your codebase into a sea of robust, modular and easily-testable components - yet also so nimble and intuitive, you'll want to keep using it even during rapid prototyping!


Why you should use Init(args)


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 your component! As such, the philosophy with Init(args) has been not to throw the baby out with the bathwater, but to build on top of that solid foundation, and unleash its full potential.


One way in Unity to acquire references to objects your components depend on, is using serialized fields. This enables users to configure dependencies by simply dragging-and-dropping them in using the Inspector! As fantastic as this is, it also has some severe limitations, rendering it unusable in certain situations:

  • It doesn't support interfaces.
  • It doesn't support referencing objects in other scenes.
  • It doesn't support referencing prefab instances that are created at runtime.
  • It doesn't support swapping a service shared between multiple clients with a different one in one go.
  • It doesn't support assigning a localized text into a string field.
  • It doesn't support assigning an addressable asset reference into a Sprite field.
  • It doesn't support assigning a randomized sound into an AudioClip field.

etc.


As you hit walls like these, you're forced to leave the elegant realm of Inspector-assigned dependencies, and go add some smelly code to your components to work around them: singletons, FindObjectOfType, GetComponentInChildren, AssetReferenceAtlasedSprite... and so on. While this hodgepodge, just-wing-it approach can get the job done, it tends to also come with some devious technical debt, that can end up coming back to bite you hard in the long term:

  • It obfuscates the dependencies of your components. You'll always need to read the entire code for all your components, to determine what other objects they rely on to function.
  • It clutters your components with code that isn't in any way related to their main responsibility. This hurts readability and maintainability, and makes it easier for bugs to creep in.
  • It can have performance implications. GetComponent is considerably slower than using a serialized field. Executing the Instance property on singletons again and again adds up.
  • Flexibility takes a plummet; all instances of your components are hardwired to use the same service.
  • It tightly couples your codebase to specific third party packages. Your components will only work with a particular localization solution, event system etc.

And even when you manage to piece together a pretty respectable component using a combination of these methods, it will still most likely be impossible to write any unit tests for it :(


Init(args) can resolve all of these issues for you.


Pure Dependency Injection


Init(args) gives you the ability to always use pure dependency injection, in all the ways and places, where it used to be impossible:

  • Drag-and-drop references across scenes.
  • Drag-and-drop components into interface fields.
  • Drag-and-drop a soft reference to a prefab instance into a component field.
  • Pass any arguments to a component when using Instantiate.
  • Pass any arguments to a component when using AddComponent.
  • Create multiple components, and pass arguments to them - including to each other - when using new GameObject.

And your components will always receive all their dependencies at the very beginning of the loading process, so they'll already be ready-to-be-used during the Awake and OnEnable events!


And not only this, but all services and clients will also automatically be initialized in optimal order, so that you won't encounter any execution order related issues! You can say good bye to manually fiddling with Script Execution Order settings :)


As a cherry on top, Init(args) will also automatically validate that clients receive all the services they depend on. In Edit Mode, you'll get a helpful warning message in the Console, if a missing reference is detected inside a prefab. At runtime, you'll see an error message, if any component is loaded without having access to all the services it needs.


Automated Dependency Injection


In addition to giving you all the tools you'll ever need for pure dependency injection, Init(args) can also help you by automatically initializing shared service objects, and making sure they get delivered to all components that need them across all your scenes and prefabs!


Creating a service is as simple as clicking a context menu item on a component, dragging-and-dropping a scriptable object into a component, or adding a single attribute to a class in code!


Finally there is a way to create globally shared services, that is just as easy as using the Singleton pattern (even easier, actually), but without any of the downsides that come with that pattern!


Interface support?

Check.


Unit-testable?

Check.


Ability to change a subset of clients to use some other services?

Check.


Features:

  1. Use Interfaces! - pick any type from a dropdown or drag-and-drop a reference.
  2. Value Providers - reference runtime-loaded prefab instances, acquire localized strings, get a random value from a list... the possibilities are endless!
  3. Cross-Scene References - Drag-and-drop references across scenes.
  4. Null Argument Guard - get warned about any Missing References in both Edit Mode and at runtime.
  5. Service Tag - Turn any component into a shared Service from the context menu.
  6. Services component - Turn any asset into a shared Service by dragging it in.
  7. [Service] attribute - Easily create globally shared services that are automatically injected to clients.
  8. Instantiate with arguments.
  9. AddComponent with arguments.
  10. new GameObject with multiple components and arguments.
  11. Smart Execution Order - Objects are initialized in order based on their dependencies to avoid execution order related issues.
  12. Wrappers - Attach plain old C# objects to GameObjects.
  13. Service Debugger Window - See a list of all the active Services at any given time.
  14. Find All Clients - Locate all the clients of a Service using a context menu item.
  15. Find Service - Locate the game object / asset / script of the Service that will be received by a client with a single click.

Also Included: A demo scene with a fully functional example game!



Links

Forum - Have any questions or ideas for new features? Discuss here.

Documentation - Online Documentation for Init(args).

Scripting Reference - Descriptions of all classes and class members in Init(args).

Technical details

Instantiate with arguments


Player player = playerPrefab.Instantiate(inputManager);


Add Component with arguments


Player player = gameObject.AddComponent<Player, IInputManager>(inputManager);


Create ScriptableObject with arguments


DialogueAsset dialogue = Create.Instance<DialogueAsset, Guid>(id);


new GameObject with arguments


new GameObject<Player, BoxCollider>("Player")

.Init1(inputManager, Second.Component);


Services


[Service(typeof(IInputManager))]

public class InputManager : IInputManager


Wrappers - attach plain old class objects to GameObjects


Player player = new Player();

gameObject.AddComponent<PlayerComponent, Player>(player);


Very simple to learn


public class Player : MonoBehaviour<IInputManager>

{

    private IInputManager inputManager;


    protected override void Init(IInputManager inputManager)

    {

        this.inputManager = inputManager;

    }

}



Init(args)

(13)
159 users have favourite this asset
(159)
$20
Seat
1
Updated price and taxes/VAT calculated at checkout
Refund policy
This asset is covered by the Unity Asset Store Refund Policy. Please see section 2.9.3 of the EULA for details.
Secure checkout:
Supported payment methods: Visa, Mastercard, Maestro, Paypal, Amex
License type
File size
1.6 MB
Latest version
1.4.1
Latest release date
Feb 24, 2025
Original Unity version
2021.3.45
Support
Visit site
Quality assets
Over 11,000 five-star assets
Trusted
Rated by 85,000+ customers
Community support
Supported by 100,000+ forum members
Unity logo
Language
Feedback
Partners Program
Partners
USD
EUR
Copyright © 2025 Unity Technologies
All prices are exclusive of tax
USD
EUR