Changelog
May 21, 2026 · View on GitHub
Version 1.2.0
Added
- Added
FromInstances(IEnumerable<T>)locator methods for component and asset bindings. These bind an existing collection of instances directly, allowingBindComponents<T>().FromInstances(...)andBindAssets<T>().FromInstances(...).
Tests
- Added tests for
FromInstanceslocator methods.
Version 1.1.1
Fixes
- Fixed an issue where an asset binding specifying a null instance was considered invalid, causing an incompatible asset type error, instead of a missing dependency error.
Tests
- Added a regression test for asset binding validation with null instance, ensuring null instance binding is not invalidated.
Version 1.1.0
Changes
- ID-qualified injection sites now require a matching
ToID(...)binding. Unqualified bindings only match injection sites without an ID. - If an
[Inject("id")]site previously relied on an unqualified binding, add.ToID("id")to the binding or remove the ID from the injection site.
Fixes
- Fixed
ToTarget<T>matching for inherited and nested targets..ToTarget<Base>()now matches derived target types,.ToTarget<Derived>()also applies to inherited injection members on the same derived target, and nested serializable injection targets are matched by their nested owner type. - Fixed binding validation for duplicate or ambiguous qualifier combinations that could resolve the same injection site.
Version 1.0.5
Fixes
- Fixed inherited private injection sites being skipped during graph construction.
- Component traversal now walks each declaring type in the inheritance chain, allowing private base class fields, methods, and auto-property backing fields to be discovered reliably.
Tests
- Added inheritance injection coverage for public and private base class fields, methods, and properties.
Version 1.0.4
Added
- Added Inject toolbar support for Unity 6000.3 and newer using Unity's
MainToolbarAPI. - Kept a legacy Inject toolbar implementation for earlier supported Unity versions that do not expose the new toolbar API.
Improved
- Optimized both Inject toolbar implementations to use proper editor callbacks instead of polling.
- Simplified the legacy toolbar flow while preserving the required fallback attachment approach for older Unity versions.
Version 1.0.3
Fixes
- Fixed
GlobalScopepersistence when domain reload is disabled.- Added an editor Play Mode lifecycle reset that clears
GlobalScopeon Enter Edit Mode after Play Mode exit. - Prevents stale global registrations from leaking into the next run.
- Ensures
BindGlobal<T>()and runtime proxy singleton registrations behave correctly regardless of domain reload settings.
- Added an editor Play Mode lifecycle reset that clears
- Fixed sample game player-build failures caused by legacy hide flags on shipped scopes.
- Removed serialized
DontSaveInBuildflags that remained onPlayerScope,GameSceneScope, andUISceneScope. - Ensures the demo scenes register globals and finalize runtime proxies correctly in player builds, including the additive scene flow.
- Removed serialized
Version 1.0.2
Fixes
- Updated sample game
GameSceneScopeto use a direct prefab reference instead of loading by asset path. - Fixed an issue where the Enemy prefab failed to load when importing the sample via UPM due to changed asset paths.
Version 1.0.1
Fixes
- Removed dependency on Newtonsoft.Json that caused compile errors when importing the package into a clean Unity project.
- Replaced serialization in ProjectSettings with Unity's built-in JsonUtility to ensure the package works out of the box without external dependencies.
Version 1.0.0
Full framework rewrite
- Saneject 1.0.0 is a full rewrite of the framework rather than an incremental update.
- The core architecture has been rebuilt around a clearer editor-time pipeline: graph construction, context-aware filtering, binding validation, dependency resolution, injection, runtime proxy preparation, and structured logging.
- Runtime has been reduced to a lightweight startup handoff where scopes register global components and swap runtime proxies before normal gameplay startup.
- With this release, Saneject leaves beta and is now considered production ready.
Major changes
- Reworked
Scopeand binding APIs aroundDeclareBindings(), typed binding families for components, assets and globals, stricter validation, and clearer qualifier/filter behavior. - Added a more explicit context model for scene objects, prefab instances and prefab assets, with more solid context-aware traversal, filtering, and resolution than the legacy system.
- Rebuilt the editor tooling around the new architecture, including stronger context tooling, a more capable scope inspector, improved logging/validation, batch injection, settings, and runtime proxy utilities.
- Replaced the old proxy workflow with the new
RuntimeProxysystem. Legacy proxies forwarded interface calls through generated code inside the proxy itself, while the new model injects an intentional placeholder that is swapped with the real instance during early startup. Generated proxy interface members now throw if the placeholder is accessed before swap, which makes the bridge more stable and predictable. - Added comprehensive architecture and API documentation, plus a broader test suite covering bindings, graph traversal, contexts, injection, scopes, proxies, inspectors, and runtime behavior.
Breaking changes
- This is not a drop-in upgrade from the 0.x beta line. Existing projects should expect migration work.
- Custom
Scopeclasses must now overrideDeclareBindings()instead of the previous scope binding method. - The old
ProxyObject/FromProxy()workflow has been replaced byRuntimeProxy/FromRuntimeProxy(). - Several APIs have been cleaned up or renamed, including
FromAnywhereInScene()toFromAnywhere(), and proxy generation terminology moving fromProxyObject/[GenerateProxyObject]toRuntimeProxy/[GenerateRuntimeProxy]. - Global registration no longer uses
SceneGlobalContainer; scopes now serialize and register their own global components directly intoGlobalScopeduring startup. - Settings are now split more clearly into machine-local
User Settingsand sharedProject Settings. Options that affect project-wide injection behavior and correctness now live underProjectSettings/Saneject/and be version controlled, while cosmetic and workflow-specific preferences remain local and stored inEditorPrefs. - Custom tooling or integrations built against older internal inspectors, menus, Roslyn tooling, or editor/runtime internals will likely need updates.
Summary
This release marks the end of Saneject's beta period. The new foundation is clearer, stricter and more maintainable, with production-ready editor-time injection, better context handling, stronger tooling, and a more stable and predictable runtime bridge for the cases Unity cannot serialize directly.
Version 0.21.1
Fixes
- Fixed minor logging issues during injection where scene and prefab logs were swapped.
- Fixed missing logs in the batch injector.
Tests
- Expanded test coverage to validate injection behavior with
Use Context Isolationdisabled.
Version 0.21.0
Context isolation overhaul
- Replaced the previous context filtering implementation with a clearer, stricter and fully deterministic model.
- Context isolation now applies consistently to dependency resolution, hierarchy traversal, scope parent resolution and object injection.
- Scenes, prefab instances and prefab assets are treated as hard-isolated contexts when filtering is enabled.
- Each prefab instance in a scene is its own context, even when multiple instances come from the same prefab asset.
- Nested prefabs are isolated from their parents and siblings, regardless of prefab source.
- Scene injection fully ignores prefab instances, prefab components and prefab scopes.
- Prefab injection fully ignores scene objects, scene components and scene scopes.
- Scene objects nested under prefabs are now injected correctly during scene injection.
- Prefab instances no longer partially see scene scopes or bindings.
- Fixed multiple edge cases where injection traversal stopped incorrectly or leaked across boundaries.
Dependency resolution improvements
- Dependency candidates are now filtered strictly by context before assignment.
- Rejected candidates are collected and reported together in a single, contextual error message.
- ScriptableObjects and other non-GameObject assets remain context-agnostic and can resolve from any context.
- Method injection fully respects the same context filtering rules as field injection.
Scope resolution changes
- Scope parent resolution now respects context isolation.
- Parent scopes are only assigned if they exist within the same context.
- Scene scopes nested under prefabs correctly resolve to the nearest valid scene scope ancestor.
- Prefab scopes no longer inherit parent scopes across prefab or scene boundaries.
Scope inspector improvements
- Scope inspector now displays the full scope hierarchy path with a clear visual indication of context boundaries.
- Out-of-context scopes are dimmed and include tooltips explaining why they are ignored during injection.
- Improved multi-selection handling, including mixed scene- and prefab selection states.
- Shows how many hierarchies or prefabs will be affected by the current injection operation.
Tests
- Refactored and expanded dependency context filtering tests to cover scenes, prefab instances, prefab assets, scriptable objects and method injection.
- Added various scope context isolation tests covering scene injection, prefab injection, nested prefabs, sibling prefabs and mixed hierarchies.
- Added scope parent resolution tests validating correct behavior across complex alternating scene- and prefab hierarchies.
- Adjusted and fixed existing tests to reflect the new, stricter isolation rules.
Summary
This release hardens Saneject's context isolation model. Injection behavior is now consistent, predictable and aligned with Unity's serialization constraints, eliminating multiple edge cases and making scene and prefab reuse safer.
Version 0.20.1
Fixes
- Fixed missing serialization sync when multiple classes in an inheritance hierarchy use
SerializeInterface, by generatingvirtualmethods for base classes andnewmethods for derived classes so thatOnBeforeSerializeandOnAfterDeserializechain correctly across the hierarchy.
Version 0.20.0
New Inspector (faster, cleaner, more reliable)
- Replaced the old inspector API with a new data-driven system that behaves much closer to Unity's native inspectors.
- All serialized fields are now discovered in a single structured pass, which removes a lot of brittle special-case logic.
- Interface fields and properties now show Unity's default PropertyField UI, so attributes like Header, Tooltip and others finally work as expected.
- Collections (arrays/lists) use Unity's built-in rendering inside a disabled scope instead of a custom drawer.
- Nested serializable classes are drawn more consistently thanks to the unified PropertyData pipeline.
- Result: a cleaner inspector that is easier to extend, easier to debug and more predictable.
Improved SerializeInterface code generation
- Major refactor of the SerializeInterfaceGenerator to make the generated code cleaner and more robust.
- User attributes on interface fields and auto-properties are now copied correctly to the generated backing fields, enabling full Unity inspector support.
- Generator now uses fully qualified names everywhere to avoid namespace conflicts.
- InterfaceBackingFieldAttribute has been simplified to store only the interface type, since InjectAttribute is now copied directly onto the generated field.
- PropertyInjector now reads real Inject attributes instead of custom metadata, reducing duplication and improving accuracy.
Full support for auto-property interface fields
- Added proper support for attributes on auto-properties using [field: SerializeInterface].
- The generator now targets the property's compiler-generated backing field (
k__BackingField), ensuring attributes behave the same as on normal fields. - Auto-properties now support Header, Tooltip, Inject and other attributes with no extra work from the user.
Bug fixes
- "Show Injected Fields/Properties" user setting no longer toggles non-injected serialized interfaces.
- Suppress missing errors via Inject-attribute now works on serialized interfaces.
Summary
This release is mostly invisible to end users but significantly improves Saneject's stability and internal consistency. Interface serialization, inspector rendering and attribute handling are now far more reliable, which also makes future features easier to build.
Version 0.19.0
New batch injection system
- Introducing the Batch Injector, a new editor window for injecting multiple scenes and prefabs across your entire project in one click, which can be quite the time-saver as your project grows. Drag scenes and prefabs into the window, toggle them on or off and choose between injecting scenes, prefabs or everything in a single pass.
- Toggle items on or off to decide exactly which assets will be included when you run a batch injection.
- Inject scenes, inject prefabs or inject everything with dedicated buttons so you can target only what you need.
- Status indicators show whether each asset succeeded, warned or failed during the last injection, helping you spot issues at a glance.
- Sorting and search let you quickly find or organize assets when working with large projects.
- Context menu actions let you bulk-select, enable, disable, remove entries, clear injection status or inject only the selected assets for fast list management.
- GUID based tracking keeps entries stable even if assets move or get renamed in the project.
- Confirmation dialogs let you avoid accidental large batch operations, with per-operation control in User Settings.
- Save prompts ensure you don't lose unsaved scene changes before injection starts.
- Log pinging lets you click a log entry to highlight the scene or prefab it refers to, speeding up debugging.
- Scope-level injection logs show which scopes ran and what was injected for each asset, making results transparent.
- Batch injection summaries give a final report of everything processed, including counts for scenes, prefabs, scopes, fields, methods, globals and suppressed errors.
Tests
- Added BatchInjectionTests to validate dependency resolution across multiple scenes and prefabs when using the new Batch Injector.
Version 0.18.0
Features
- Added support for optional error suppression
- You can now mark
[Inject(suppressMissingErrors: true)]to silence expected missing bindings or dependencies. - Suppressed issues are still counted and clearly noted below the injection summary log for full transparency.
- Mostly useful for advanced edge cases, e.g., shared components used in multiple contexts where some references are intentionally null.
- You can now mark
Fixes
- Fix incorrect
memberNameparameter for method injection- Updated
MethodInjectorto passmethod.Nameinstead of parameter name (p.Name) as thememberNamevalue during method injection. - Ensures
.ToMember("...")correctly targets method names when using method injection.
- Updated
Refactor
- The large
DependencyInjectorclass has been refactored into smaller, modular classes with clear, isolated responsibilities, reusable methods, which makes the system easier to maintain.
Version 0.17.0
Features
ToTarget<T>now correctly supports nested serializable classes. Previously it only evaluated against the rootMonoBehaviour, but it now recognizes and targets nested class instances as well.- Added method injection support (
[Inject]on methods). Useful for configuration or injection into third party components.- Supports single, array and
List<T>parameters. - Works alongside field injection - methods are invoked after fields are injected.
- Fully supported in nested
[Serializable]classes. - Parameters participate in full binding resolution (context filtering, qualifiers, proxy resolution).
- Supports single, array and
Improvements
- Injection logs and stats now include injected method count.
- Improved serialization handling for nested method injection targets.
Tests
- Added unit tests for
ToTargetqualification with nested serialized classes. - Added unit tests for method injection, covering single, array and list parameter injection paths.
Version 0.16.1
Security patch
- Upgraded the project to Unity 6000.0.59f2 to address the Unity security vulnerability CVE-2025-59489.
- This update ensures the project uses a patched Unity runtime that resolves the untrusted search path issue.
- This change only affects users who clone and open the Unity project directly using the previous Unity version listed in ProjectSettings. Opening the project with the updated Unity 6000.0.59f2 or later is safe.
- Users who install Saneject via UPM or a .unitypackage file are not affected and don't need to take any action.
Version 0.16.0
Features
- Display scope path in Inspector
- Shows the chain of parent scopes from the topmost scope down to the current one.
- Added a Show Scope Path toggle in User Settings.
- Includes jump-to-scope buttons for quick navigation.
- Inspector tooltip support for
[SerializeInterface][Tooltip]text on a[SerializeInterface]field is now reflected on its generated backing field.
- Binding identity strings now list the names of their targets and members, making log messages clearer and helping distinguish bindings whose uniqueness comes from those specific targets or members.
- Added global binding context filtering
- Skip prefab components by default when registering in SceneGlobalContainer (can be turned off in user settings - but not recommended).
- Injection logic now tracks invalid bindings for clearer debugging.
- Added MonoBehaviour script field to inspectors
- Both
ScopeEditorandSceneGlobalContainerEditornow show the standard "Script" field with improved spacing and headers.
- Both
Fixes
- Nicified type names in
SceneGlobalContainerEditorinspector: raw type names are now shown with user-friendly formatting and spaces, matching the default Unity inspector.
Improvements
- Enhanced error handling and logging for global dependency resolution
- Error messages include the global binding identity for better debugging clarity.
- Duplicate bindings and resolution failures now provide more detailed context.
Version 0.15.0
Changes
- Allow injecting abstract
UnityEngine.Objecttypes, aligning with Unity's ownGetComponentAPIs. - Simplified the filter surface API for component and asset bindings:
- Removed built-in syntactic sugar methods (
WhereNameIs,WhereSiblingIndexIs, etc.). - Added more hierarchy predicate-based base methods (
Where,WhereComponent,WhereTransform,WhereGameObject, etc.). - Benefits: smaller API surface while retaining flexibility, less mental load, more powerful composition.
- Trade-off: slightly more boilerplate when writing filters.
- To mitigate boilerplate:
- The filter system is now extensible with user-defined syntactic sugar methods.
- Developers can implement only the helpers they need, keeping the API lean while retaining ergonomics.
- Example sugar helpers are provided as an importable UPM sample ("Component Filter Extensions") demonstrating how to extend the filter API (works the same way for both component and asset filters).
- Removed built-in syntactic sugar methods (
Tests
- Added new tests for
ComponentFilterBuilderbase and relation methods, covering both concrete and interface bindings. - Added tests for
AssetFilterBuilderto ensure consistent behavior across asset filters. - Added tests for the included sample extension methods.
- Removed old tests for deprecated sugar methods.
Version 0.14.0
Features
- Added contextual right-click menu item in the Inspector: Filter Logs By This Component.
Copies the component's full transform path into the Console search bar.- For regular components, filters logs by their hierarchy path.
- For
Scopecomponents, automatically filters by the scope's type name.
This makes it easy to isolate errors and warnings for a single component or scope in large projects.
Version 0.13.1
Fixes
- Fixed a bug where fields marked with
[Inject("id")]could be resolved by bindings without an ID.
Now ID-qualified fields only match bindings that explicitly declare the same ID, ensuring deterministic injection.
Tests
- Added unit tests for both component and asset bindings to assert that non-ID bindings do not resolve into ID-qualified fields.
Version 0.13.0
Changes
Make binding ID a qualifier with multiple match support
- Converted binding ID from a single string into a qualifier set, aligned with target and member qualifiers.
- IDs can now stack via
.ToId("A", "B")and the binding will match if any of the IDs match, just like the other qualifiers. - Updated binding equality rules: bindings with overlapping IDs are treated as duplicates to preserve deterministic resolution.
- Extended unit tests to cover equality and HashSet deduplication behavior for bindings with multiple and overlapping IDs.
Introduce target qualifier methods (ToTarget, ToMember)
- Moved
WhereTargetIsandWhereMemberNameIsout of filter builders and into binding builders. Filters should constrain dependency candidates, while these methods constrain the injection target. - Renamed them to
ToTargetandToMemberfor clarity. Added overloads to support both singular and multiple qualifiers. - Updated all internal references and tests to use the new qualifier methods.
- Updated sample game bindings to use the qualifiers where applicable.
Switch global bindings to dedicated GlobalBindingBuilder
- Added
GlobalBindingBuilder<TComponent>to replaceComponentBindingBuilderfor global bindings. - Global bindings do not support qualifiers (
ToId,ToTarget,ToMember) or.FromProxy(), since globals are promoted into aSceneGlobalContainerand proxies already resolve from the global scope. - Locator methods remain identical to component bindings and still return a
ComponentFilterBuilder<TComponent>so filters work the same way. - Updated
ScopeAPI and tests to use the new builder forBindGlobal<T>().
Version 0.12.0
Features
- Injection error logs now include the full path to the injected field, making it easier to pinpoint where a failure occurred.
- Injection stats now track the number of missing dependencies in addition to missing and invalid bindings.
- Added log severity levels (Info, Warning, Error) to injection stats logs.
- Added a new Scope creation tool:
- Available via
Saneject/Create New ScopeorAssets/Create/Saneject/Create New Scope. - Generates a new
Scopeclass with the correct boilerplate code. - Namespace generation can be toggled in User Settings with the option Generate Scope Namespace From Folder (uses folder path relative to
Assets/).
- Available via
- Added new
WhereMemberNameIsfilter for component and asset bindings:- This allows bindings to target specific injected fields or properties by name for fine-grained control and can in many case replace ID boilerplate.
- Unit tests added for both component and asset versions.
Changes
- Binding target filters (
WhereTargetIs<T>) now evaluate withAnyinstead ofAll.
This allows chaining multiple filters to mean "inject intoT1orT2" instead of requiring all filters simultaneously. - Binding uniqueness & equality updated:
Binding.Equalsnow treats target-type and member-name filters as overlap-based (subset/superset considered equal if they can apply to the same injection site).GetHashCodewas adjusted accordingly (hash depends on presence of these filters rather than their full contents).- This tightens duplicate detection: e.g.,
WhereTargetIs<MonoA>()is considered a duplicate ofWhereTargetIs<MonoA>().WhereTargetIs<MonoB>(); same forWhereMemberNameIs("monoA")vsWhereMemberNameIs("monoA","monoB"). - Added/updated unit tests to cover overlap equality for both target-type and member-name filters, including assignability (base/derived) cases.
- Scope inspector Inject button now injects only the selected hierarchy instead of the entire scene. This makes it easier to process smaller hierarchies and view context-relevant logs. Full-scene injection is still available via scene right-click and the Saneject menu.
- Fully abort injection when proxy script creation is pending
- Updated
CreateMissingProxyStubsto return a flag when proxy generation is required. - Injection now aborts early if proxies are pending, since Unity recompilation halts the process anyway.
- Reduces irrelevant logs during proxy generation by deferring them until the next injection pass.
- Improved progress display and clarity of messages when proxy creation interrupts injection.
- Updated
- Updated sample game
EnemyManager: now spawns enemies from a prefab at runtime instead of injecting scene children, keeping the sample compatible with context filtering enabled and aligned with recommended usage.
Fixes
- Fixed an issue where missing dependencies were not counted correctly in the injection stats.
- Restored property drawing for
[field: ...]auto-properties inSanejectInspector, so[SerializeField]and[SerializeInterface]properties (with or without[Inject], including in nested classes) now draw correctly again. - Fixed a bug in FilterBySameContext where prefab asset injection (via Inspector on a prefab selected in the Project window) incorrectly treated child objects as separate contexts. Now all components inside a prefab asset normalize to the prefab asset root, ensuring they are considered part of the same context. This fixes broken injection when pressing Inject on a prefab asset without opening the prefab.
- Fixed singular/plural words in injection stats logs.
Version 0.11.0
Features
- Added
FromFolderasset binding locator that loads all assets of a given type from a project folder and its subfolders.
Tests
- Added unit tests for
FromFoldercovering both concrete and interface bindings.
Version 0.10.2
Fixes
- Fixed a bug that prevented interface only binding
BindComponent<IInterface>().FromAnywhereInScene()from working.
Version 0.10.1
Changes
- Added prefab-to-prefab isolation to context filtering.
- Prefab instances can no longer resolve components from other prefab instances.
- Prefab assets can no longer resolve components from other prefab assets.
- This ensures prefab-scoped dependencies remain stable and do not leak across unrelated prefabs.
Tests
- Extended ContextFilteringTests to cover:
- Rejection of cross-prefab references when filtering is enabled.
- Rejection of prefab asset references when filtering is enabled.
- Confirmation that cross-context links are allowed when filtering is disabled.
- Verified prefab isolation does not interfere with scene or proxy workflows.
Version 0.10.0
Features
- Added new user setting Filter By Same Context (default: enabled).
- When enabled, Saneject filters out prefab components when injecting into scene objects, and filters out scene components when injecting into prefabs. This enforces context isolation and avoids broken references.
- When disabled, scene ↔ prefab references are allowed as an escape hatch. This is not recommended because such links are not serialized reliably; removing a prefab instance from the scene will silently break the dependency.
- For proper cross-context references, the recommended workflow is to use ProxyObjects (
BindComponent<TInterface, TConcrete>().FromProxy()).
Changes
- Improved error logging when a binding fails to resolve:
- Logs now include candidate types that were rejected due to scene/prefab context mismatch.
- Error messages provide guidance to either use ProxyObjects or disable context filtering in user settings (with a warning).
- Cleaner dev UX for injection errors: all rejected candidates for a binding are reported together in a single message instead of spamming per-candidate logs.
- Rename
BindingIdentityHelpertoBindingSignatureHelperand refactor related methods. - Add checker material to sample game ground plane to make player movement visible.
Tests
- Added ContextFilteringTests to verify that scene ↔ prefab resolution is blocked when filtering is enabled, and allowed when filtering is disabled.
Version 0.9.1
Changes
- Move global binding prefab validation out of
DependencyInjectorand intoBindingValidator.
Fixes
- Fix global bindings always flagged as unused.
- Display invalid bindings count in injection stats log.
Tests
Wrote new tests:
- Test that global binding on prefab scope is correctly invalidated.
- Test that all used bindings are correctly marked
IsUsed = true.
Version 0.9.0
New Features
- Added
BindComponent<TInterface, TConcrete>().FromProxy()binding locator that greatly simplifies working with proxies. At injection time, the system will create the stub and proxy asset instance for you and inject the asset. This is now the recommended workflow for normal use cases. Much faster and less context-switching than creating manual instances, as multiple proxies can be created declaratively in one injection pass. - For advanced use cases, you can still create manual proxy ScriptableObject instances with different resolution strategies. This workflow has been improved as well. Previously it was a tedious multi-step process per proxy (generate stub, domain reload, wait, generate asset). Now both stub and proxy asset generate in one click.
- User settings: customizable path for generated proxy output.
- User settings: toggle to clear log before injection, useful for seeing only logs related to the current context.
Changes
- Renamed
InterfaceProxyObjecttoProxyObjectfor simplicity and conciseness. Required coordinated renames across Roslyn, code generation, and stub generation. - Refactored binding validation into a separate
BindingValidatorclass instead of having it inside theBindingitself. - Wrote a
BindingIdentityHelperthat constructs a consistent binding identity string for logging, making logs more scannable. - Cleaned up and streamlined log and validation messages.
- Updated demo game to use
FromProxy().
Validation & Testing
- Added new validation checks related to the
FromProxy()method. - Added unit test for
FromProxy(). Stub generation cannot be tested directly, since it triggers a domain reload (which kills the test process), but loading and creating the proxy asset is verified in CI.
Version 0.8.3
- Fixed bug where
SceneGlobalContainerfailed to unregister fromGlobalScopeon scene unload if the instance was null.
Version 0.8.2
Packaging
- Added Unity Package Manager (UPM) support.
- Package can now be installed directly via Git URL:
https://github.com/alexanderlarsen/Saneject.git?path=UnityProject/Saneject/Assets/Plugins/Saneject - No changes to runtime or editor functionality.
- Fixed a bug in
SceneGlobalContainerthat made it break in sample imported via UPM.
Version 0.8.1
CI/Testing
- Added assembly definition files for runtime and test code to ensure CI discovers and runs tests consistently across Unity versions.
- Moved test
Resourcesfolder into a folder covered by an assembly definition soResources.Loadworks in CI. - Updated test setup to automatically bypass injection confirmation prompts when running in batch mode, fixing mass test failures in CI.
- Confirmed automated tests now pass for all supported Unity versions.
Editor
- No functional changes to runtime/editor features, only improvements to test reliability and CI integration.
Version 0.8.0
Saneject is now confirmed to work from 2022.3.12f LTS.
Backwards Compatibility
- Swap
TextMeshProUGUIcomponents and references withUnityEngine.UI.Text. - Removed new Unity input system and updated demo scripts to use old input system.
- Added extension
GetComponentIndexCompatwith preprocessor version check, so versions older than Unity 2022 versions don't callcomponent.GetComponentIndex()that doesn't exist.
Editor
- Renamed
MonoBehaviourInspectortoMonoBehaviourFallbackInspectorand made it a true fallback so it only applies when no more specific custom inspector exists. - Added
SanejectInspectorpublic API for integrating Saneject's injection-aware inspector features into custom editors. - Introduced unified
SanejectInspector.DrawDefaultmethod to restore the full Saneject inspector UI/UX in a single call from any custom inspector.
CI/Testing
- Added automated test runs for oldest/newest 2022 LTS, 6.0 LTS, plus latest 6.1 and 6.2.
Version 0.7.1
- Allow
[Inject]attribute to be used with public fields without[SerializeField]. - Small refactor in the
Scopebinding API:BindComponent<TComponent>()and single generic variations are nowBindComponent<T>(), to make it clearer thatTcan be both interface and concrete.
Version 0.7.0
API Changes
- Refactored binding API to be more type-safe via generics. The API now returns only appropriate binding methods depending on whether you're binding assets or components.
- Added support for collection bindings using
BindMultipleComponents<T>(),BindMultipleComponents<TInterface, TConcrete>(), and shorthand aliasesBindComponents<T>()andBindComponents<TInterface, TConcrete>(). - Added support for multiple bindings of the same type, allowing interface injection with different concretes based on the injection target using
.WhereTargetIs<T>(). - Enforced stricter resolution rules: interface bindings no longer resolve concrete fields.
- Added support for interface-only bindings, e.g.
BindComponent<IInterface>(), useful for resolving collections of different concrete implementations. - Removed dependency injector caching due to problems with target filtering and multi-binding resolution.
Scope.GetBindingRecursivelyUpwards()now respects target filters and no longer returns the first match unconditionally.
Validation & Error Handling
- Improved validation and error handling across the binding system.
- Binding configuration issues (missing, conflicting, unused bindings) are now reported in a single pass without halting the injection flow.
- Added extended validation for binding declarations to detect invalid or contradictory configurations.
Inspector & UI
- Removed legacy property drawers. All field rendering is now handled by
MonoBehaviourInspectorandSanejectInspector. - Inspector draws injected collections (arrays/lists) as read-only, grayed-out UI with no editing controls.
- Interface field sync logic (
ISerializationCallbackReceiver.OnBeforeSerialize) is now generated by Roslyn and no longer depends onPropertyDrawer, improving robustness. - Tooltips added to all toggles in
UserSettingsEditorWindow. - Serialize interface backing fields and generated serialization methods are now hidden from IntelliSense to prevent accidental misuse.
Testing
- Added 225 unit tests covering core functionality and edge cases. All tests are passing.
Bug Fixes
- Fixed a bug where
[SerializeInterface]did not work correctly in nested[Serializable]classes. - Fixed a bug where interface bindings incorrectly resolved concrete fields.
Version 0.6.0
Roslyn Analyzers & Code Fixes
- Added a new Roslyn analyzer (
AttributesAnalyzer.dll) that validates:[Inject]fields must also have[SerializeField]or[SerializeInterface].[SerializeInterface]can only be applied to fields of interface type.
- Added code fixes that offer context-aware actions to add, remove or correct attribute usage.
- Updated Roslyn tools documentation and reorganized project structure for clarity.
See Roslyn Tools in Saneject for more details.