Init(args)
Sisus
$20.00
Date |
Price |
---|---|
日期和时间 |
价钱($) |
12/22(2021) |
20.0 |
12/22(2021) |
10.0 |
01/05(2022) |
20.0 |
02/16(2022) |
12.49 |
05/23(2022) |
8.99 |
07/11(2022) |
9.0 |
09/14(2022) |
4.99 |
09/20(2022) |
19.99 |
09/28(2022) |
14.99 |
08/27(2024) |
20.0 |
11/19(2024) |
20.0 |
Jump AssetStore
Init(args) is a next-gen DI framework for Unity, that combines mind-opening flexibility with unprecedented ease-of-use.Init(args) in a nutshellInit(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 InjectionInit(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 InjectionIn 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:Use Interfaces! - pick any type from a dropdown or drag-and-drop a reference.Value Providers - reference runtime-loaded prefab instances, acquire localized strings, get a random value from a list... the possibilities are endless!Cross-Scene References - Drag-and-drop references across scenes.Null Argument Guard - get warned about any Missing References in both Edit Mode and at runtime.Service Tag - Turn any component into a shared Service from the context menu.Services component - Turn any asset into a shared Service by dragging it in.[Service] attribute - Easily create globally shared services that are automatically injected to clients.Instantiate with arguments.AddComponent with arguments.new GameObject with multiple components and arguments.Smart Execution Order - Objects are initialized in order based on their dependencies to avoid execution order related issues.Wrappers - Attach plain old C# objects to GameObjects.Service Debugger Window - See a list of all the active Services at any given time.Find All Clients - Locate all the clients of a Service using a context menu item.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).Instantiate with argumentsPlayer player = playerPrefab.Instantiate(inputManager);Add Component with argumentsPlayer player = gameObject.AddComponent(inputManager);Create ScriptableObject with argumentsDialogueAsset dialogue = Create.Instance(id);new GameObject with argumentsnew GameObject("Player").Init1(inputManager, Second.Component);Services[Service(typeof(IInputManager))]public class InputManager : IInputManagerWrappers - attach plain old class objects to GameObjectsPlayer player = new Player();gameObject.AddComponent(player);Very simple to learnpublic class Player : MonoBehaviour{ private IInputManager inputManager; protected override void Init(IInputManager inputManager) { this.inputManager = inputManager; }}