com.kylin.di 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/.github/workflows/publish.yml +22 -0
  2. package/CHANGELOG.md +17 -0
  3. package/CLAUDE.md +58 -0
  4. package/LICENSE +21 -0
  5. package/README.md +704 -0
  6. package/Runtime/Attributes/InjectAttribute.cs +11 -0
  7. package/Runtime/Attributes/InjectAttribute.cs.meta +2 -0
  8. package/Runtime/Attributes/ViewModelAttribute.cs +17 -0
  9. package/Runtime/Attributes/ViewModelAttribute.cs.meta +2 -0
  10. package/Runtime/Attributes.meta +8 -0
  11. package/Runtime/Core/DIBehaviour.cs +70 -0
  12. package/Runtime/Core/DIBehaviour.cs.meta +2 -0
  13. package/Runtime/Core/LifetimeScope.cs +264 -0
  14. package/Runtime/Core/LifetimeScope.cs.meta +2 -0
  15. package/Runtime/Core.meta +8 -0
  16. package/Runtime/DI/DependencyBuilder.cs +114 -0
  17. package/Runtime/DI/DependencyBuilder.cs.meta +2 -0
  18. package/Runtime/DI/DependencyInjector.cs +104 -0
  19. package/Runtime/DI/DependencyInjector.cs.meta +2 -0
  20. package/Runtime/DI/InstanceFactory.cs +36 -0
  21. package/Runtime/DI/InstanceFactory.cs.meta +2 -0
  22. package/Runtime/DI/KDI.cs +54 -0
  23. package/Runtime/DI/KDI.cs.meta +2 -0
  24. package/Runtime/DI/Registration.cs +29 -0
  25. package/Runtime/DI/Registration.cs.meta +2 -0
  26. package/Runtime/DI/Scope.cs +183 -0
  27. package/Runtime/DI/Scope.cs.meta +2 -0
  28. package/Runtime/DI/ScopeBuilder.cs +68 -0
  29. package/Runtime/DI/ScopeBuilder.cs.meta +2 -0
  30. package/Runtime/DI/ScopeExtensions.cs +70 -0
  31. package/Runtime/DI/ScopeExtensions.cs.meta +2 -0
  32. package/Runtime/DI.meta +8 -0
  33. package/Runtime/Debug/ClosureAnalyzer.cs +377 -0
  34. package/Runtime/Debug/ClosureAnalyzer.cs.meta +2 -0
  35. package/Runtime/Debug/ClosureProfilerWindow.cs +435 -0
  36. package/Runtime/Debug/ClosureProfilerWindow.cs.meta +2 -0
  37. package/Runtime/Debug/SubscriberInfo.cs +661 -0
  38. package/Runtime/Debug/SubscriberInfo.cs.meta +3 -0
  39. package/Runtime/Debug.meta +3 -0
  40. package/Runtime/Kylin.DI.asmdef +14 -0
  41. package/Runtime/Kylin.DI.asmdef.meta +7 -0
  42. package/Runtime/SubscribableProperty/Reaction.cs +61 -0
  43. package/Runtime/SubscribableProperty/Reaction.cs.meta +2 -0
  44. package/Runtime/SubscribableProperty/SubscribableCollection.cs +325 -0
  45. package/Runtime/SubscribableProperty/SubscribableCollection.cs.meta +3 -0
  46. package/Runtime/SubscribableProperty/SubscribableCollectionExtensions.cs +24 -0
  47. package/Runtime/SubscribableProperty/SubscribableCollectionExtensions.cs.meta +3 -0
  48. package/Runtime/SubscribableProperty/SubscribableCommand.cs +52 -0
  49. package/Runtime/SubscribableProperty/SubscribableCommand.cs.meta +2 -0
  50. package/Runtime/SubscribableProperty/SubscribableDictionary.cs +350 -0
  51. package/Runtime/SubscribableProperty/SubscribableDictionary.cs.meta +3 -0
  52. package/Runtime/SubscribableProperty/SubscribableProperty.cs +119 -0
  53. package/Runtime/SubscribableProperty/SubscribableProperty.cs.meta +2 -0
  54. package/Runtime/SubscribableProperty/SubscribablePropertyExtensions.cs +39 -0
  55. package/Runtime/SubscribableProperty/SubscribablePropertyExtensions.cs.meta +3 -0
  56. package/Runtime/SubscribableProperty/SubscribablePropertyLinq.cs +86 -0
  57. package/Runtime/SubscribableProperty/SubscribablePropertyLinq.cs.meta +2 -0
  58. package/Runtime/SubscribableProperty.meta +8 -0
  59. package/Runtime/Update/IFixedUpdatable.cs +16 -0
  60. package/Runtime/Update/IFixedUpdatable.cs.meta +2 -0
  61. package/Runtime/Update/ILateUpdatable.cs +16 -0
  62. package/Runtime/Update/ILateUpdatable.cs.meta +2 -0
  63. package/Runtime/Update/IUpdatable.cs +16 -0
  64. package/Runtime/Update/IUpdatable.cs.meta +2 -0
  65. package/Runtime/Update/IUpdatePriority.cs +15 -0
  66. package/Runtime/Update/IUpdatePriority.cs.meta +2 -0
  67. package/Runtime/Update/UpdateLoopManager.cs +240 -0
  68. package/Runtime/Update/UpdateLoopManager.cs.meta +2 -0
  69. package/Runtime/Update.meta +8 -0
  70. package/Runtime.meta +8 -0
  71. package/package.json +19 -0
@@ -0,0 +1,22 @@
1
+ name: Publish to npmjs
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ jobs:
9
+ publish:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+
14
+ - uses: actions/setup-node@v4
15
+ with:
16
+ node-version: '20'
17
+ registry-url: 'https://registry.npmjs.org'
18
+
19
+ - name: Publish package
20
+ run: npm publish
21
+ env:
22
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/CHANGELOG.md ADDED
@@ -0,0 +1,17 @@
1
+ # Changelog
2
+
3
+ ## [1.0.0] - 2026-03-15
4
+
5
+ ### Added
6
+ - Scope-based DI container with hierarchical parent-child resolution
7
+ - Field injection via `[Inject]` attribute
8
+ - Lifetime management: Singleton, Scoped, Transient
9
+ - `LifetimeScope` MonoBehaviour for Unity scene integration
10
+ - `DIBehaviour` base class with Push injection and CompositeDisposable
11
+ - Dynamic object creation: `scope.Instantiate()`, `scope.InjectGameObject()`
12
+ - Managed update loop: `IUpdatable`, `IFixedUpdatable`, `ILateUpdatable`
13
+ - SubscribableProperty reactive system with LINQ extensions
14
+ - SubscribableCollection and SubscribableDictionary
15
+ - Closure Profiler and Subscribable Property Debugger editor tools
16
+ - All-or-nothing injection (partial injection prevention)
17
+ - Warning for `[Inject]` fields on types missing `IInjectable`
package/CLAUDE.md ADDED
@@ -0,0 +1,58 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ KDI (Kylin Dependency Injection) is a Unity 6 package (`com.kylin.di`) — a minimal scope-based DI framework with field-only injection and built-in reactive properties. Core DI logic is ~500 lines. Assembly name: `Kylin.DI`, root namespace: `Kylin`.
8
+
9
+ This is a Unity Package Manager (UPM) package, not a standalone project. There are no build/test/lint commands to run directly — it compiles within a Unity project that references it.
10
+
11
+ ## Architecture
12
+
13
+ ### DI Pipeline (Runtime/DI/)
14
+
15
+ The injection flow is: `LifetimeScope.Configure()` → `ScopeBuilder.Build()` → `Scope` created → `LifetimeScope.InjectChildren()` pushes `[Inject]` fields into child transforms.
16
+
17
+ - **KDI** — Static facade. Holds the `RootScope` reference. Auto-resets via `[RuntimeInitializeOnLoadMethod]`.
18
+ - **ScopeBuilder** — Collects `Registration` entries via fluent `Bind<T>().To<TImpl>().AsScoped()` API. Freezes after `Build()`. Enforces Singleton-only-in-RootScope rule at build time.
19
+ - **DependencyBuilder<T>** — Fluent builder returned by `ScopeBuilder.Bind<T>()`. Lifetime chain terminates with `AsSingleton()`/`AsScoped()`/`AsTransient()`/`FromInstance()`.
20
+ - **Scope** — Implements `IScope`. Holds `Dictionary<Type, Registration>` (frozen) and `Dictionary<Type, object>` (cached instances). Resolution walks parent chain. Circular reference detection uses `[ThreadStatic] HashSet<Type>`. Dispose cascades children → instances (IDisposable + UpdateLoopManager unregister).
21
+ - **Registration** — Data class: ServiceType, ImplementationType, Instance, Lifetime, Factory.
22
+ - **DependencyInjector** — Static. Two-phase inject: resolve all fields first, then set all at once (atomic). `ConcurrentDictionary<Type, FieldInfo[]>` cache walks inheritance up to MonoBehaviour/object. Warns on `[Inject]` fields without `IInjectable`.
23
+ - **InstanceFactory** — `Expression.Lambda.Compile()` cached factory for parameterless constructors.
24
+ - **ScopeExtensions** — `IScope.Instantiate()` and `IScope.InjectGameObject()` for runtime prefab spawning with DI.
25
+
26
+ ### Unity Integration (Runtime/Core/)
27
+
28
+ - **LifetimeScope** — Abstract MonoBehaviour. Subclass and override `Configure(ScopeBuilder)`. Parent set via Inspector `_parent` field. Auto-initializes in `Awake` (configurable). Static registry uses `Transform.IsChildOf` (native) instead of `GetComponentInParent` (managed) for scope lookup. Push injection stops at child LifetimeScope boundaries.
29
+ - **DIBehaviour** — Abstract MonoBehaviour implementing `IInjectable`. Provides `_cd` (CompositeDisposable) for subscription cleanup on `OnDisable`, and `Scope` property for runtime access.
30
+
31
+ ### Key Marker Interfaces
32
+
33
+ - `IDependencyObject` — Required on types registered via `To<T>()` or `FromInstance()`.
34
+ - `IInjectable` — Required for `[Inject]` field injection to work. Without it, fields are silently skipped (with a warning).
35
+ - `IPostInjectable` — Optional. `PostInject()` called after all `[Inject]` fields are set.
36
+
37
+ ### Reactive System (Runtime/SubscribableProperty/)
38
+
39
+ `SubscribableProperty<T>` — Observable value with `Subscribe(callback, invokeInitial)` → `IDisposable`. Uses `EqualityComparer<T>.Default` for change detection. Supports Unity serialization (`ISerializationCallbackReceiver`). External serialization (MessagePack, JSON etc.) is supported via separate adapter packages (`com.kylin.di.messagepack`). Namespace: `Kylin.SubscribableProperty`.
40
+
41
+ Also includes: `SubscribableCollection<T>`, `SubscribableDictionary<TKey,TValue>`, `SubscribableCommand`, and LINQ extensions (`Select`, etc.).
42
+
43
+ ### Update Loop (Runtime/Update/)
44
+
45
+ `UpdateLoopManager` — Singleton MonoBehaviour (`DontDestroyOnLoad`). Non-MonoBehaviour classes implementing `IUpdatable`/`IFixedUpdatable`/`ILateUpdatable` are auto-registered when resolved through a Scope. Supports `IUpdatePriority` (lower value = earlier execution). Registration/unregistration is deferred via a pending queue processed each frame.
46
+
47
+ Interface method names are prefixed: `KDIUpdate`, `KDIFixedUpdate`, `KDILateUpdate`.
48
+
49
+ ## Design Constraints
50
+
51
+ - **Field injection only** — No constructor injection. All DI-managed types must have a public parameterless constructor.
52
+ - **Singleton only in RootScope** — `AsSingleton()` in a child scope throws at build time.
53
+ - **Push injection model** — LifetimeScope walks child transforms; components don't pull their own dependencies.
54
+ - **Scope freeze** — `ScopeBuilder` cannot accept registrations after `Build()`.
55
+
56
+ ## Language
57
+
58
+ Source code comments and log messages are in Korean. Follow this convention when modifying existing code.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kylin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.