Introduction
Saneject is an editor-time injectionEditor-time injectionSaneject workflow that resolves dependencies and writes them into serialized objects in the Unity Editor, before entering Play Mode. framework for Unity. You declare bindingsBindingInstruction declared in a Scope that tells Saneject what to resolve, how to inject it, and where to search. in ScopeScopeMonoBehaviour that declares bindings for a part of your hierarchy. components, run an injection runInjection runOne execution of the injection pipeline for a chosen selection, context walk filter, and active set of targets. in the editor, and Saneject writes resolved dependencies directly into serialized members in scenes and prefabs. This keeps dependency wiring close to Unity's native serialization model: dependencies remain visible in the Inspector, runtime startup stays lightweight, and gameplay code can still be structured around interfaces and explicit dependencies.
What Saneject is optimized for
Saneject is designed for teams that want DI structure without giving up Unity's serialized workflows.
- Keep dependencies explicit in serialized data and in the Inspector.
- Use interfaces in gameplay code while still working with serialized interfacesSerialized interface
SerializeInterfacemember (IService,IService[], orList<IService>) that Saneject persists through a generated hiddenObjectbacking member.. - Use structured, deterministic injection runsInjection runOne execution of the injection pipeline for a chosen selection, context walk filter, and active set of targets. across scenes and prefabs.
- Control large injection passes from editor tooling instead of runtime bootstrap code.
- Keep runtime overhead low for dependency wiring.
How it works
During an injection runInjection runOne execution of the injection pipeline for a chosen selection, context walk filter, and active set of targets., Saneject resolves dependencies in the editor and writes values directly into serialized members, including [Inject] fields, [field: Inject] auto-property backing fieldsAuto-property backing fieldCompiler-generated field that stores an auto-property value. Saneject can inject these fields with [field: Inject]., and methods marked with [Inject].
- You mark some fields, properties, or methods with
[Inject]. - You declare bindingsBindingInstruction declared in a
Scopethat tells Saneject what to resolve, how to inject it, and where to search. inScope.DeclareBindings()to describe where dependencies should come from. - You run injection in the editor for the scene, prefab, or selection you want to process.
- Saneject builds an injection graphInjection graphHierarchy model built from selected root hierarchies. It contains transform, component, scope, binding, and injection-member information used by the edit-time pipeline., validates bindingsBindingInstruction declared in a
Scopethat tells Saneject what to resolve, how to inject it, and where to search., resolves dependencies, writes the results into serialized members, and logs a summary for the run.
When Saneject is a good fit
Saneject is a good fit when you want deterministic, editor-driven dependency wiring that behaves like normal Unity serialization at runtime. It is especially useful when your project needs interface-heavy gameplay code, clear Inspector-visible dependencies, or repeatable validation across scenes and prefabs.
The tradeoff is that dependency wiring becomes part of the authoring workflow. Instead of relying on a runtime container to compose everything dynamically at startup, you run injection ahead of time and treat serialized references as the runtime result.