com.alicizax.unity.framework/Runtime/ABase/Base/Service/Unity/MonoServiceBehaviour.cs
2026-03-26 10:49:41 +08:00

100 lines
3.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
namespace AlicizaX
{
/// <summary>
/// Mono 服务基类(不自动注册,适合需要手动控制注册时机的场景)。
/// </summary>
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() { }
}
/// <summary>
/// Mono 服务基类(自动注册到 <typeparamref name="TScope"/>)。
/// <para>
/// 场景服务:<c>_dontDestroyOnLoad = false</c>(默认),销毁时自动注销。<br/>
/// 跨场景服务:<c>_dontDestroyOnLoad = true</c>,首个实例持久化并注册;
/// 后续场景中出现的重复实例自动销毁自身。
/// </para>
/// <para>
/// 子类通过 <see cref="OnAwake"/> 执行额外的 Awake 逻辑,
/// 通过 <see cref="OnServiceInitialize"/> 执行注册后的初始化,
/// 通过 <see cref="OnServiceDestroy"/> 执行注销前的清理。
/// </para>
/// </summary>
public abstract class MonoServiceBehaviour<TScope> : MonoServiceBehaviour
where TScope : class
{
[SerializeField] private bool _dontDestroyOnLoad = false;
// 注意:使用 Start 而非 Awake 注册,确保 GameServiceRoot.Awake创建 World必然先于此执行。
// DefaultExecutionOrder 会影响所有生命周期(含 Awake用 Start 可彻底规避执行顺序陷阱。
private void Awake()
{
if (_dontDestroyOnLoad)
DontDestroyOnLoad(gameObject);
OnAwake();
}
private void Start()
{
var scope = AppServices.GetOrCreateScope<TScope>();
// 跨场景重复实例检测:契约已被占用则销毁自身
if (scope.HasContract(GetType()))
{
Destroy(gameObject);
return;
}
scope.Register(this);
}
private void OnDestroy()
{
if (!IsInitialized) return;
if (!AppServices.HasWorld) return;
if (!AppServices.TryGetScope<TScope>(out var scope)) return;
scope.Unregister(this);
}
/// <summary>
/// 在 Awake 阶段执行(早于 Start 中的自动注册)。
/// 适合缓存组件引用等不依赖服务系统的初始化。
/// </summary>
protected virtual void OnAwake() { }
}
}