Last active
January 31, 2019 09:43
-
-
Save Zammy/dcf06b66a36a965fd0b1932d862b8696 to your computer and use it in GitHub Desktop.
Service locator pattern in C#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using UniRx; | |
public interface IService | |
{ | |
} | |
public interface IInitializable | |
{ | |
void Init(); | |
} | |
public interface ILateInitializable | |
{ | |
void LateInit(); | |
} | |
public interface IDestroyable | |
{ | |
void Destroy(); | |
} | |
public interface IAppPause | |
{ | |
void OnAppPause(bool pause); | |
} | |
public interface IAppQuit | |
{ | |
void OnAppQuit(); | |
} | |
public interface ITickable | |
{ | |
void Tick(float deltaTime); | |
} | |
public interface ITickableUnscaled | |
{ | |
void TickUnscaled(float deltaTime); | |
} | |
public class ServiceLocator : Singleton<ServiceLocator> | |
{ | |
List<Tuple<int, IService>> _services = new List<Tuple<int, IService>>(); | |
readonly Subject<IService> _onServiceRegisteredSubject = new Subject<IService>(); | |
public IObservable<T> OnServiceRegistered<T>() where T : IService | |
{ | |
var service = GetService<T>(); | |
if (service != null) | |
{ | |
return Observable.Return(service); | |
} | |
return _onServiceRegisteredSubject | |
.Where(s => typeof(T).IsAssignableFrom(s.GetType())) | |
.Select(s => (T)s); | |
} | |
public void RegisterService(IService service, int priority = 0) | |
{ | |
if (_services.Any(t => t.Item2 == service)) | |
{ | |
throw new ArgumentException(service.GetType().Name + " already registered! Unregister previous instance!"); | |
} | |
_services.Add(new Tuple<int, IService>(priority, service)); | |
_onServiceRegisteredSubject.OnNext(service); | |
} | |
public void UnregisterService(IService service) | |
{ | |
for (int i = 0; i < _services.Count; i++) | |
{ | |
if (_services[i].Item2 == service) | |
{ | |
_services.RemoveAt(i); | |
return; | |
} | |
} | |
} | |
public void UnregisterService<T>() where T : IService | |
{ | |
_services.RemoveAll(s => s.Item2 is T); | |
} | |
public T GetService<T>() | |
{ | |
for (int i = 0; i < _services.Count; i++) | |
{ | |
if (typeof(T).IsAssignableFrom(_services[i].Item2.GetType())) | |
{ | |
return (T)_services[i].Item2; | |
} | |
} | |
return default(T); | |
} | |
public void InitServices() | |
{ | |
_services = _services.OrderBy(t => t.Item1).ToList(); | |
foreach (var tuple in _services) | |
{ | |
var service = tuple.Item2 as IInitializable; | |
if (service != null) | |
{ | |
service.Init(); | |
} | |
} | |
} | |
public void LateInitServices() | |
{ | |
foreach (var tuple in _services) | |
{ | |
var service = tuple.Item2 as ILateInitializable; | |
if (service != null) | |
{ | |
service.LateInit(); | |
} | |
} | |
} | |
public void DestroyServices() | |
{ | |
foreach (var tuple in _services) | |
{ | |
var service = tuple.Item2 as IDestroyable; | |
if (service != null) | |
{ | |
service.Destroy(); | |
} | |
} | |
_services.Clear(); | |
} | |
public void OnAppPauseServices(bool pause) | |
{ | |
foreach (var tuple in _services) | |
{ | |
var service = tuple.Item2 as IAppPause; | |
if (service != null) | |
{ | |
service.OnAppPause(pause); | |
} | |
} | |
} | |
public void AppQuitServices() | |
{ | |
foreach (var tuple in _services) | |
{ | |
var service = tuple.Item2 as IAppQuit; | |
if (service != null) | |
{ | |
service.OnAppQuit(); | |
} | |
} | |
UnityEngine.Application.Quit(); | |
} | |
public void TickServices(float deltaTime, float unscaledDeltaTime) | |
{ | |
foreach (var tuple in _services) | |
{ | |
var scaled = tuple.Item2 as ITickable; | |
if (scaled != null) | |
{ | |
scaled.Tick(deltaTime); | |
} | |
var unscaled = tuple.Item2 as ITickableUnscaled; | |
if (unscaled != null) | |
{ | |
unscaled.TickUnscaled(unscaledDeltaTime); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment