Files
zeling_v2/Assets/Scripts/Core/ServiceLocator.cs
2026-05-08 11:04:00 +08:00

50 lines
2.0 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 System;
using System.Collections.Generic;
using UnityEngine;
namespace BaseGames.Core
{
/// <summary>
/// 轻量服务定位器。通过类型键注册/查找服务,支持接口类型注册(依赖倒置)。
/// </summary>
public static class ServiceLocator
{
private static readonly Dictionary<Type, object> _services = new();
/// <summary>以接口类型 TInterface 注册实现 impl。</summary>
public static void Register<TInterface>(TInterface impl)
=> _services[typeof(TInterface)] = impl;
/// <summary>仅当尚未注册时才注册(防多场景重复注册同一服务)。</summary>
public static void RegisterIfAbsent<TInterface>(TInterface impl)
{
if (!_services.ContainsKey(typeof(TInterface)))
_services[typeof(TInterface)] = impl;
}
/// <summary>查找服务。未注册时抛出 InvalidOperationException。</summary>
public static TInterface Get<TInterface>()
{
if (_services.TryGetValue(typeof(TInterface), out var svc) && svc is TInterface typed)
return typed;
throw new InvalidOperationException(
$"[ServiceLocator] Service '{typeof(TInterface).Name}' is not registered. "
+ "Ensure GameServiceRegistrar.Awake() has run before this call.");
}
/// <summary>安全版 Get未注册时返回 fallback不报错适用于可选服务。</summary>
public static TInterface GetOrDefault<TInterface>(TInterface fallback = default)
=> _services.TryGetValue(typeof(TInterface), out var svc) && svc is TInterface typed
? typed : fallback;
#if UNITY_EDITOR
/// <summary>单元测试中替换服务实现。</summary>
public static void OverrideForTest<TInterface>(TInterface mock)
=> _services[typeof(TInterface)] = mock;
/// <summary>清空所有注册(测试用)。</summary>
public static void Reset() => _services.Clear();
#endif
}
}