Listing 7:
using System; using System.Collections.Generic; using UnityEngine; /// <summary> /// Simple service locator for <see cref="IApplicationService"/> instances. /// </summary> public class ServiceLocator { private ServiceLocator() { } /// <summary> /// currently registered services. /// </summary> private readonly Dictionary<string, IApplicationService> services = new Dictionary<string, IApplicationService>(); /// <summary> /// Gets the currently active service locator instance. /// </summary> public static ServiceLocator Current { get; private set; } /// <summary> /// Initalizes the service locator with a new instance. /// </summary> public static void Initiailze() { Current = new ServiceLocator(); } /// <summary> /// Gets the service instance of the given type. /// </summary> /// <typeparam name="T">The type of the service to lookup.</typeparam> /// <returns>The service instance.</returns> public T Get<T>() where T : IApplicationService { string key = typeof(T).Name; if (!services.ContainsKey(key)) { Debug.LogError($"{key} not registered with {GetType().Name}"); throw new InvalidOperationException(); } return (T)services[key]; } /// <summary> /// Registers the service with the current service locator. /// </summary> /// <typeparam name="T">Service type.</typeparam> /// <param name="service">Service instance.</param> public void Register<T>(T service) where T : IApplicationService { string key = typeof(T).Name; if (services.ContainsKey(key)) { Debug.LogError($"Attempted to register service of type {key} which is already registered with the {GetType().Name}."); return; } services.Add(key, service); } /// <summary> /// Unregisters the service from the current service locator. /// </summary> /// <typeparam name="T">Service type.</typeparam> public void Unregister<T>() where T : IApplicationService { string key = typeof(T).Name; if (!services.ContainsKey(key)) { Debug.LogError($"Attempted to unregister service of type {key} which is not registered with the {GetType().Name}."); return; } services.Remove(key); } }
Listing 9
using System.Collections.Generic; using UnityEngine; public class LevelService : MonoBehaviour, IApplicationService { public Level CurrentLevel; private LevelService() { CurrentLevel = Level.Beginner; } public void NextLevel() { if (CurrentLevel != Level.Expert) { CurrentLevel++; } } } public enum Level { Beginner = 0, Intermediate = 1, Advanced = 2, Expert = 3 }
Listing 10
using UnityEngine; public class PlayerService : MonoBehaviour, IApplicationService { private Level currentLevel; private LevelService currentLevelService; public string PlayerName; public int Score; public void Awake() { currentLevelService = ServiceLocator.Current.Get<LevelService>(); currentLevel = currentLevelService.CurrentLevel; } public void PlayerReachesNextLevel() { currentLevelService.NextLevel(); } }
Listing 11
using UnityEngine; public class Bootstrapper : MonoBehaviour { public void Initiailze() { // Initialize default service locator. ServiceLocator.Initiailze(); // Register all your services next. ServiceLocator.Current.Register(this.GetComponentInChildren<LevelService>()); ServiceLocator.Current.Register(this.GetComponentInChildren<PlayerService>()); } private void Awake() { this.Initiailze(); } }