forked from zxl/LaboratoryProtection
269 lines
7.1 KiB
C#
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
|
|
} |