1
0
Fork 0
LaboratoryProtection/Assets/PMaker/Scripts/IoC/IoC.cs

269 lines
7.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace PMaker.DependencyInjection
{
public static class IoC
{
private static IoCContainer _container = new IoCContainer();
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void Init()
{
_container = new IoCContainer();
#if UNITY_EDITOR
var obj = new GameObject("IoCContainer");
obj.AddComponent<IoCContainer.Mono>().container = _container;
GameObject.DontDestroyOnLoad(obj);
#endif
}
#region singleton
public static void AddSingleton<T>(T instance) where T : class
{
_container.AddSingleton(instance);
}
public static void AddSingleton(Type type, object instance)
{
_container.AddSingleton(type, instance);
}
public static void RemoveSingleton<T>() where T : class
{
_container.RemoveSingleton<T>();
}
public static void RemoveSingleton(Type type)
{
_container.RemoveSingleton(type);
}
public static T GetSingleton<T>() where T : class
{
return _container.GetSingleton<T>();
}
public static void ClearSingleton()
{
_container.ClearSingletons();
}
#endregion
#region instance
public static void AddInstance<T>(T instance) where T : class
{
_container.AddInstance(instance);
}
public static void RemoveInstance<T>(T instance) where T : class
{
_container.RemoveInstance(instance);
}
public static void RemoveInstance(Type type, object instance)
{
_container.RemoveInstance(type, instance);
}
public static void RemoveInstances<T>() where T : class
{
_container.RemoveInstances<T>();
}
public static void RemoveInstances(Type type)
{
_container.RemoveInstances(type);
}
public static IEnumerable<T> GetInstance<T>() where T : class
{
return _container.GetInstances<T>();
}
public static void ClearAllInstances()
{
_container.ClearAllInstances();
}
#endregion
public static bool TryGetSingleton<T>(out T instance) where T : class
{
instance = _container.GetSingleton<T>();
return instance != null;
}
}
public interface ISingletonCollection
{
void AddSingleton<T>(T instance) where T : class;
void AddSingleton(Type type, object instance);
void RemoveSingleton<T>() where T : class;
void RemoveSingleton(Type type);
void ClearSingletons();
T GetSingleton<T>() where T : class;
}
public interface IInstanceCollection
{
void AddInstance<T>(T instance) where T : class;
void AddInstance(Type type, object instance);
void RemoveInstance<T>(T instance) where T : class;
void RemoveInstance(Type type, object instance);
void RemoveInstances<T>() where T : class;
void RemoveInstances(Type type);
void ClearAllInstances();
IEnumerable<T> GetInstances<T>() where T : class;
}
public partial class IoCContainer : ISingletonCollection, IInstanceCollection
{
private Dictionary<Type, object> _singletonMapper;
private Dictionary<Type, HashSet<object>> _instanceMapper;
public IoCContainer()
{
this._singletonMapper = new Dictionary<Type, object>();
this._instanceMapper = new Dictionary<Type, HashSet<object>>();
}
#region singleton
public void RemoveSingleton(Type type)
{
this._singletonMapper.Remove(type);
}
public void AddSingleton(Type type, object instance)
{
this._singletonMapper.Add(type, instance);
}
public void AddSingleton<T>(T instance) where T : class
{
this._singletonMapper.Add(typeof(T), instance);
}
public void RemoveSingleton<T>() where T : class
{
this._singletonMapper.Remove(typeof(T));
}
public T GetSingleton<T>() where T : class
{
this._singletonMapper.TryGetValue(typeof(T), out var instance);
return instance as T;
}
public void ClearSingletons()
{
this._singletonMapper.Clear();
}
#endregion
#region instance
public void AddInstance<T>(T instance) where T : class
{
var type = instance.GetType();
if (this._instanceMapper.TryGetValue(type, out var set))
{
set.Add(instance);
}
else
{
this._instanceMapper.Add(type, new HashSet<object>() { instance });
}
}
public void AddInstance(Type type, object instance)
{
if (this._instanceMapper.TryGetValue(type, out var set))
{
set.Add(instance);
}
else
{
this._instanceMapper.Add(type, new HashSet<object>() { instance });
}
}
public void RemoveInstance<T>(T instance) where T : class
{
this.RemoveInstance(typeof(T), instance);
}
public void RemoveInstance(Type type, object instance)
{
if (this._instanceMapper.TryGetValue(type, out var set))
{
set.Remove(instance);
}
else
{
}
}
public IEnumerable<T> GetInstances<T>() where T : class
{
var type = typeof(T);
if (this._instanceMapper.TryGetValue(type, out var set))
{
return set.Select(_ => _ as T);
}
return null;
}
public void RemoveInstances<T>() where T : class
{
var type = typeof(T);
if (this._instanceMapper.TryGetValue(type, out var set))
{
set.Clear();
}
}
public void RemoveInstances(Type type)
{
if (this._instanceMapper.TryGetValue(type, out var set))
{
set.Clear();
}
}
public void ClearAllInstances()
{
this._instanceMapper.Clear();
}
#endregion
}
#if UNITY_EDITOR
public partial class IoCContainer
{
public class Mono : BaseBehaviour
{
[SerializeField]
[Sirenix.OdinInspector.ReadOnly]
public Dictionary<Type, object> SingletonMapper { get => container._singletonMapper; set => container._singletonMapper = value; }
[SerializeField]
[Sirenix.OdinInspector.ReadOnly]
public Dictionary<Type, HashSet<object>> InstanceMapper { get => container._instanceMapper; set => container._instanceMapper = value; }
public IoCContainer container;
}
}
#endif
}