mirror of
https://github.com/pese-git/cherrypick.git
synced 2026-01-24 05:25:19 +00:00
feat(core): add full DI lifecycle observability via onInstanceDisposed
- Call observer.onInstanceDisposed for every removed/cleaned-up instance in Scope lifecycle - Makes instance disposal fully observable outside of cache events - Ensures analytics/logging frameworks get notified of each object removal from memory Part of complete CherryPickObserver integration for transparent diagnostics and monitoring of DI container.
This commit is contained in:
@@ -43,6 +43,7 @@ class Scope with CycleDetectionMixin, GlobalCycleDetectionMixin {
|
|||||||
|
|
||||||
Scope(this._parentScope, {required CherryPickObserver observer}) : _observer = observer {
|
Scope(this._parentScope, {required CherryPickObserver observer}) : _observer = observer {
|
||||||
setScopeId(_generateScopeId());
|
setScopeId(_generateScopeId());
|
||||||
|
observer.onScopeOpened(scopeId ?? 'NO_ID');
|
||||||
observer.onDiagnostic(
|
observer.onDiagnostic(
|
||||||
'Scope created: ${scopeId ?? 'NO_ID'}',
|
'Scope created: ${scopeId ?? 'NO_ID'}',
|
||||||
details: {
|
details: {
|
||||||
@@ -113,6 +114,7 @@ class Scope with CycleDetectionMixin, GlobalCycleDetectionMixin {
|
|||||||
if (childScope.scopeId != null) {
|
if (childScope.scopeId != null) {
|
||||||
GlobalCycleDetector.instance.removeScopeDetector(childScope.scopeId!);
|
GlobalCycleDetector.instance.removeScopeDetector(childScope.scopeId!);
|
||||||
}
|
}
|
||||||
|
observer.onScopeClosed(childScope.scopeId ?? name);
|
||||||
observer.onDiagnostic(
|
observer.onDiagnostic(
|
||||||
'SubScope closed: $name',
|
'SubScope closed: $name',
|
||||||
details: {
|
details: {
|
||||||
@@ -134,6 +136,12 @@ class Scope with CycleDetectionMixin, GlobalCycleDetectionMixin {
|
|||||||
/// return [Scope]
|
/// return [Scope]
|
||||||
Scope installModules(List<Module> modules) {
|
Scope installModules(List<Module> modules) {
|
||||||
_modulesList.addAll(modules);
|
_modulesList.addAll(modules);
|
||||||
|
if (modules.isNotEmpty) {
|
||||||
|
observer.onModulesInstalled(
|
||||||
|
modules.map((m) => m.runtimeType.toString()).toList(),
|
||||||
|
scopeName: scopeId,
|
||||||
|
);
|
||||||
|
}
|
||||||
for (var module in modules) {
|
for (var module in modules) {
|
||||||
observer.onDiagnostic(
|
observer.onDiagnostic(
|
||||||
'Module installed: ${module.runtimeType}',
|
'Module installed: ${module.runtimeType}',
|
||||||
@@ -161,6 +169,12 @@ class Scope with CycleDetectionMixin, GlobalCycleDetectionMixin {
|
|||||||
///
|
///
|
||||||
/// return [Scope]
|
/// return [Scope]
|
||||||
Scope dropModules() {
|
Scope dropModules() {
|
||||||
|
if (_modulesList.isNotEmpty) {
|
||||||
|
observer.onModulesRemoved(
|
||||||
|
_modulesList.map((m) => m.runtimeType.toString()).toList(),
|
||||||
|
scopeName: scopeId,
|
||||||
|
);
|
||||||
|
}
|
||||||
observer.onDiagnostic(
|
observer.onDiagnostic(
|
||||||
'Modules dropped for scope: $scopeId',
|
'Modules dropped for scope: $scopeId',
|
||||||
details: {
|
details: {
|
||||||
@@ -186,6 +200,7 @@ class Scope with CycleDetectionMixin, GlobalCycleDetectionMixin {
|
|||||||
/// return - returns an object of type [T] or [StateError]
|
/// return - returns an object of type [T] or [StateError]
|
||||||
///
|
///
|
||||||
T resolve<T>({String? named, dynamic params}) {
|
T resolve<T>({String? named, dynamic params}) {
|
||||||
|
observer.onInstanceRequested(T.toString(), T, scopeName: scopeId);
|
||||||
// Используем глобальное отслеживание, если включено
|
// Используем глобальное отслеживание, если включено
|
||||||
T result;
|
T result;
|
||||||
if (isGlobalCycleDetectionEnabled) {
|
if (isGlobalCycleDetectionEnabled) {
|
||||||
@@ -223,6 +238,7 @@ class Scope with CycleDetectionMixin, GlobalCycleDetectionMixin {
|
|||||||
return withCycleDetection<T>(T, named, () {
|
return withCycleDetection<T>(T, named, () {
|
||||||
var resolved = _tryResolveInternal<T>(named: named, params: params);
|
var resolved = _tryResolveInternal<T>(named: named, params: params);
|
||||||
if (resolved != null) {
|
if (resolved != null) {
|
||||||
|
observer.onInstanceCreated(T.toString(), T, resolved, scopeName: scopeId);
|
||||||
observer.onDiagnostic(
|
observer.onDiagnostic(
|
||||||
'Successfully resolved: $T',
|
'Successfully resolved: $T',
|
||||||
details: {
|
details: {
|
||||||
@@ -316,8 +332,24 @@ class Scope with CycleDetectionMixin, GlobalCycleDetectionMixin {
|
|||||||
return withCycleDetection<Future<T>>(T, named, () async {
|
return withCycleDetection<Future<T>>(T, named, () async {
|
||||||
var resolved = await _tryResolveAsyncInternal<T>(named: named, params: params);
|
var resolved = await _tryResolveAsyncInternal<T>(named: named, params: params);
|
||||||
if (resolved != null) {
|
if (resolved != null) {
|
||||||
|
observer.onInstanceCreated(T.toString(), T, resolved, scopeName: scopeId);
|
||||||
|
observer.onDiagnostic(
|
||||||
|
'Successfully async resolved: $T',
|
||||||
|
details: {
|
||||||
|
'type': 'Scope',
|
||||||
|
'name': scopeId,
|
||||||
|
'resolve': T.toString(),
|
||||||
|
if (named != null) 'named': named,
|
||||||
|
'description': 'successfully resolved (async)',
|
||||||
|
},
|
||||||
|
);
|
||||||
return resolved;
|
return resolved;
|
||||||
} else {
|
} else {
|
||||||
|
observer.onError(
|
||||||
|
'Failed to async resolve: $T',
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
);
|
||||||
throw StateError(
|
throw StateError(
|
||||||
'Can\'t resolve async dependency `$T`. Maybe you forget register it?');
|
'Can\'t resolve async dependency `$T`. Maybe you forget register it?');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user