Classes that implement one of the generic IArgs<T…> interfaces can be provided with arguments during initialization (up to a maximum of twelve).
Methods such as Instantiate<TObject, T…> and AddComponent<TComponent, T…> can only be used to create instances of classes that implement one of the IArgs<T…> interfaces.
A contract to receive arguments
Any object that implements an IArgs<T…> interface makes a promise to receive arguments that have been injected for them during their initialization process using the InitArgs.TryGet method.
It is recommended that the arguments are retrieved during the Awake event function in most cases. This has the benefit of always only being executed once per object and occuring after the deserialization process has already finished.
Other possible options include the OnEnable and OnAfterDeserialize functions.
Technically it is also possible for MonoBehaviours to receive their dependencies in the constructor. However it is important to understand that the constructor gets called before the deserialization process, which means that the values of any serialized fields into which you assign your dependencies could get overridden during deserialization. If you only create your instances procedurally at runtime or only assign values to non-serialized fields, this can still be a workable solution, but beware that is is easy to make mistakes if you decide to go this route.
The Start event function is not considered to be part of the initialization process because it only gets executed during the next frame after the instance has been created.
If an Object that implements IArgs<T…> but does not receive the arguments that are passed to it an InitArgumentsNotReceivedException will be thrown. However, if the Object implements IInitializable<T…> the arguments can be injected through the Init method, even if the client fails to receive the arguments independently, and in this case no exception will be thrown.
Note: The Awake event function does not get called for components on inactive GameObjects. Because of this it is advisable for component classes to implement IInitializable<T…> and not just IArgs<T…> in most cases.