Initial commit
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
|
||||
namespace BracerLib.DI
|
||||
{
|
||||
public struct Dependency
|
||||
{
|
||||
public Type Type { get; }
|
||||
public FactoryFunc Factory { get; }
|
||||
public DependencyLifetime Lifetime { get; }
|
||||
|
||||
public Dependency(Type type, FactoryFunc provider, DependencyLifetime lifetime)
|
||||
{
|
||||
Type = type;
|
||||
Factory = provider;
|
||||
Lifetime = lifetime;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 08b41999af4aec5459aa82b9a53bcf46
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BracerLib.DI
|
||||
{
|
||||
public class DependencyCollection : IEnumerable<Dependency>
|
||||
{
|
||||
private readonly IList<Dependency> dependencies = new List<Dependency>();
|
||||
|
||||
public void Add(Dependency dependency) => dependencies.Add(dependency);
|
||||
|
||||
public IEnumerator<Dependency> GetEnumerator() => dependencies.GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => dependencies.GetEnumerator();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a09894721d4f3714aa39bc4335147866
|
||||
@@ -0,0 +1,28 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace BracerLib.DI
|
||||
{
|
||||
[DefaultExecutionOrder(-1)]
|
||||
public abstract class DependencyContext : MonoBehaviour
|
||||
{
|
||||
private DependencyProvider dependencyProvider;
|
||||
protected readonly DependencyCollection dependencyCollection = new();
|
||||
|
||||
protected abstract void Setup();
|
||||
|
||||
protected abstract void Configure();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Setup();
|
||||
|
||||
dependencyProvider = new DependencyProvider(dependencyCollection);
|
||||
|
||||
var children = GetComponentsInChildren<MonoBehaviour>(true);
|
||||
foreach (var child in children)
|
||||
dependencyProvider.Inject(child);
|
||||
|
||||
Configure();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: af6df49e6c26ffe41a2c34e13afdb851
|
||||
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace BracerLib.DI
|
||||
{
|
||||
public delegate object FactoryFunc(DependencyProvider provider);
|
||||
|
||||
public static class DependencyFactory
|
||||
{
|
||||
public static FactoryFunc FromClass<T>() where T : class, new()
|
||||
{
|
||||
return provider =>
|
||||
{
|
||||
var type = typeof(T);
|
||||
var obj = FormatterServices.GetUninitializedObject(type);
|
||||
|
||||
provider.Inject(obj);
|
||||
|
||||
type.GetConstructor(Type.EmptyTypes)?.Invoke(obj, null);
|
||||
|
||||
return (T)obj;
|
||||
};
|
||||
}
|
||||
|
||||
public static FactoryFunc FromGameObject<T>(T instance) where T : MonoBehaviour
|
||||
{
|
||||
return dependencies =>
|
||||
{
|
||||
var children = instance.GetComponentsInChildren<MonoBehaviour>(true);
|
||||
foreach (var child in children)
|
||||
dependencies.Inject(child);
|
||||
|
||||
return instance;
|
||||
};
|
||||
}
|
||||
|
||||
public static FactoryFunc FromPrefab<T>(T prefab) where T : MonoBehaviour
|
||||
{
|
||||
return provider =>
|
||||
{
|
||||
var prefabObj = prefab.gameObject;
|
||||
var wasActive = prefabObj.activeSelf;
|
||||
prefabObj.SetActive(false);
|
||||
var instance = Object.Instantiate(prefab);
|
||||
prefabObj.SetActive(wasActive);
|
||||
var children = instance.GetComponentsInChildren<MonoBehaviour>(true);
|
||||
|
||||
foreach (var child in children)
|
||||
provider.Inject(child);
|
||||
|
||||
instance.gameObject.SetActive(wasActive);
|
||||
|
||||
return instance.GetComponent<T>();
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4dd8b23ba952434428cdbc308db727b1
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace BracerLib.DI
|
||||
{
|
||||
public enum DependencyLifetime
|
||||
{
|
||||
Transient = 0,
|
||||
Singleton
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d180c5acba365c4c9381bc61d6c6781
|
||||
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace BracerLib.DI
|
||||
{
|
||||
public class DependencyProvider
|
||||
{
|
||||
private IDictionary<Type, Dependency> dependencyMap = new Dictionary<Type, Dependency>();
|
||||
private IDictionary<Type, object> singletons = new Dictionary<Type, object>();
|
||||
|
||||
public DependencyProvider(DependencyCollection collection)
|
||||
{
|
||||
foreach (var d in collection)
|
||||
dependencyMap.Add(d.Type, d);
|
||||
}
|
||||
|
||||
public object Get(Type type)
|
||||
{
|
||||
if (!dependencyMap.ContainsKey(type))
|
||||
throw new ArgumentException($"Type is not a dependency: {type.FullName}");
|
||||
|
||||
var dependency = dependencyMap[type];
|
||||
switch (dependency.Lifetime)
|
||||
{
|
||||
case DependencyLifetime.Transient: return dependency.Factory(this);
|
||||
case DependencyLifetime.Singleton:
|
||||
if (!singletons.ContainsKey(type))
|
||||
singletons.Add(type, dependency.Factory(this));
|
||||
|
||||
return singletons[type];
|
||||
default: throw new ArgumentOutOfRangeException($"Unavailable lifetime for dependency: {type.FullName}");
|
||||
}
|
||||
}
|
||||
|
||||
public T Get<T>() => (T)Get(typeof(T));
|
||||
|
||||
public object Inject(object dependant)
|
||||
{
|
||||
var type = dependant.GetType();
|
||||
while (type != null)
|
||||
{
|
||||
var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly |
|
||||
BindingFlags.Instance);
|
||||
foreach (var f in fields)
|
||||
{
|
||||
if (f.GetCustomAttribute<InjectFieldAttribute>(false) == null)
|
||||
continue;
|
||||
|
||||
f.SetValue(dependant, Get(f.FieldType));
|
||||
}
|
||||
|
||||
type = type.BaseType;
|
||||
}
|
||||
|
||||
return dependant;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0857e79315720b44eb82767785bfa5b4
|
||||
@@ -0,0 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace BracerLib.DI
|
||||
{
|
||||
public class InjectFieldAttribute : Attribute { }
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f10c710f6a498a468c7c3d5a3f7f429
|
||||
Reference in New Issue
Block a user