Initial commit

This commit is contained in:
2026-06-02 18:57:47 -04:00
commit 59d26a915d
268 changed files with 41240 additions and 0 deletions
+18
View File
@@ -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;
}
}
}
+2
View File
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 08b41999af4aec5459aa82b9a53bcf46
+16
View File
@@ -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
+28
View File
@@ -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
+59
View File
@@ -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
+8
View File
@@ -0,0 +1,8 @@
namespace BracerLib.DI
{
public enum DependencyLifetime
{
Transient = 0,
Singleton
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 3d180c5acba365c4c9381bc61d6c6781
+59
View File
@@ -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