using UnityEngine; namespace AlicizaX { /// /// Mono 服务基类(不自动注册,适合需要手动控制注册时机的场景)。 /// public abstract class MonoServiceBehaviour : MonoBehaviour, IMonoService { public ServiceContext Context { get; private set; } public bool IsInitialized { get; private set; } protected ServiceWorld World => Context.World; protected ServiceScope Scope => Context.Scope; void IService.Initialize(ServiceContext context) { if (IsInitialized) throw new System.InvalidOperationException($"{GetType().FullName} is already initialized."); Context = context; IsInitialized = true; OnServiceInitialize(); } void IService.Destroy() { if (!IsInitialized) return; OnServiceDestroy(); IsInitialized = false; Context = default; } protected virtual void OnServiceInitialize() { } protected virtual void OnServiceDestroy() { } } /// /// Mono 服务基类(自动注册到 )。 /// /// 场景服务:_dontDestroyOnLoad = false(默认),销毁时自动注销。
/// 跨场景服务:_dontDestroyOnLoad = true,首个实例持久化并注册; /// 后续场景中出现的重复实例自动销毁自身。 ///
/// /// 子类通过 执行额外的 Awake 逻辑, /// 通过 执行注册后的初始化, /// 通过 执行注销前的清理。 /// ///
public abstract class MonoServiceBehaviour : MonoServiceBehaviour where TScope : class { [SerializeField] private bool _dontDestroyOnLoad = false; // 注意:使用 Start 而非 Awake 注册,确保 GameServiceRoot.Awake(创建 World)必然先于此执行。 // DefaultExecutionOrder 会影响所有生命周期(含 Awake),用 Start 可彻底规避执行顺序陷阱。 private void Awake() { OnAwake(); } private void Start() { var scope = AppServices.GetOrCreateScope(); // 跨场景重复实例检测:契约已被占用则销毁自身 if (scope.HasContract(GetType())) { Destroy(gameObject); return; } // Defer DontDestroyOnLoad until after the duplicate check so rejected // duplicates are never moved to the DontDestroyOnLoad scene. if (_dontDestroyOnLoad) DontDestroyOnLoad(gameObject); scope.Register(this); } private void OnDestroy() { if (!IsInitialized) return; if (!AppServices.HasWorld) return; if (!AppServices.TryGetScope(out var scope)) return; scope.Unregister(this); } /// /// 在 Awake 阶段执行(早于 Start 中的自动注册)。 /// 适合缓存组件引用等不依赖服务系统的初始化。 /// protected virtual void OnAwake() { } } }