chore: initial commit
This commit is contained in:
49
Assets/Scripts/Core/ServiceLocator.cs
Normal file
49
Assets/Scripts/Core/ServiceLocator.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user