update builtin DI

This commit is contained in:
Mikhail 2024-04-28 18:36:14 +08:00
parent 80a6963699
commit 32444868e1
7 changed files with 75 additions and 52 deletions

View File

@ -1,42 +1,32 @@
using System; using System;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS.Internal
{ {
public class InjectionBranch internal class InjectionBranch
{ {
private readonly Injector _source; private readonly Injector _source;
private readonly Type _type; private readonly Type _type;
private InjectionNodeBase[] _nodes = new InjectionNodeBase[2]; private InjectionNodeBase[] _nodes = new InjectionNodeBase[2];
private int _nodesCount = 0; private int _nodesCount = 0;
private bool _isDeclared = false;
public Type Type public Type Type
{ {
get { return _type; } get { return _type; }
} }
public bool IsDeclared public InjectionBranch(Injector source, Type type)
{
get { return _isDeclared; }
}
public InjectionBranch(Injector source, Type type, bool isDeclared)
{ {
_source = source; _source = source;
_isDeclared = isDeclared;
_type = type; _type = type;
} }
public void SetDeclaredTrue()
{
_isDeclared = true;
}
public void Inject(object obj) public void Inject(object obj)
{ {
for (int i = 0; i < _nodesCount; i++) for (int i = 0; i < _nodesCount; i++)
{ {
_nodes[i].Inject(obj); _nodes[i].Inject(obj);
} }
if (obj is IInjectionBlock container) if (obj is IInjectionBlock block)
{ {
container.InjectTo(new BlockInjector(_source)); block.InjectTo(_source);
} }
} }
public void AddNode(InjectionNodeBase node) public void AddNode(InjectionNodeBase node)

View File

@ -16,7 +16,10 @@ namespace DCFApixels.DragonECS
public abstract void Inject(object obj); public abstract void Inject(object obj);
public abstract void Init(EcsPipeline pipeline); public abstract void Init(EcsPipeline pipeline);
} }
public sealed class InjectionNode<T> : InjectionNodeBase }
namespace DCFApixels.DragonECS.Internal
{
internal sealed class InjectionNode<T> : InjectionNodeBase
{ {
private EcsProcess<IEcsInject<T>> _process; private EcsProcess<IEcsInject<T>> _process;
public InjectionNode(Type type) : base(type) { } public InjectionNode(Type type) : base(type) { }

View File

@ -1,4 +1,5 @@
using System; using DCFApixels.DragonECS.Internal;
using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
@ -22,8 +23,11 @@ namespace DCFApixels.DragonECS
private Dictionary<Type, InjectionNodeBase> _nodes = new Dictionary<Type, InjectionNodeBase>(32); private Dictionary<Type, InjectionNodeBase> _nodes = new Dictionary<Type, InjectionNodeBase>(32);
private bool _isInit = false; private bool _isInit = false;
public EcsPipeline Pipelie { get { return _pipeline; } }
private Injector() { } private Injector() { }
#region Inject/AddNode
public void Inject<T>(T obj) public void Inject<T>(T obj)
{ {
object raw = obj; object raw = obj;
@ -32,18 +36,43 @@ namespace DCFApixels.DragonECS
{ {
if (typeof(T) == type) if (typeof(T) == type)
{ {
InitNode(new InjectionNode<T>(type)); if (_nodes.ContainsKey(type) == false)
branch = new InjectionBranch(this, type, true); {
InitNode(new InjectionNode<T>(type));
}
branch = new InjectionBranch(this, type);
InitBranch(branch); InitBranch(branch);
} }
else else
{ {
branch = new InjectionBranch(this, type, false); bool hasNode = _nodes.ContainsKey(type);
InitBranch(branch); if (hasNode == false && obj is IInjectionUnit unit)
{
unit.OnInitInjectionBranch(new InjectionBranchIniter(this));
hasNode = _nodes.ContainsKey(type);
}
if (hasNode)
{
branch = new InjectionBranch(this, type);
InitBranch(branch);
}
else
{
throw new EcsInjectionException($"To create an injection branch, no injection node of {type.Name} was found. To create a node, use the AddNode<{type.Name}>() method directly in the injector or in the implementation of the IInjectionUnit for {type.Name}.");
}
} }
} }
branch.Inject(raw); branch.Inject(raw);
} }
public void AddNode<T>()
{
Type type = typeof(T);
if (_nodes.ContainsKey(type) == false)
{
InitNode(new InjectionNode<T>(type));
}
}
#endregion
#region Internal #region Internal
private void InitBranch(InjectionBranch branch) private void InitBranch(InjectionBranch branch)
@ -68,7 +97,7 @@ namespace DCFApixels.DragonECS
_nodes.Add(node.Type, node); _nodes.Add(node.Type, node);
foreach (var item in _branches) foreach (var item in _branches)
{ {
var type = item.Key; //var type = item.Key;
var branch = item.Value; var branch = item.Value;
if (node.Type.IsAssignableFrom(branch.Type)) if (node.Type.IsAssignableFrom(branch.Type))
{ {
@ -108,7 +137,7 @@ namespace DCFApixels.DragonECS
if (IsCanInstantiated(type)) if (IsCanInstantiated(type))
#endif #endif
{ {
InitBranch(new InjectionBranch(this, type, true)); InitBranch(new InjectionBranch(this, type));
} }
return true; return true;
} }

View File

@ -1,29 +0,0 @@
namespace DCFApixels.DragonECS
{
public readonly struct BlockInjector
{
private readonly Injector _injectionGraph;
public BlockInjector(Injector injectionGraph)
{
_injectionGraph = injectionGraph;
}
public void Inject<T>(T obj)
{
_injectionGraph.Inject(obj);
}
// public void InjectNoBoxing<T>(T data) where T : struct
// {
// _injectionGraph.InjectNoBoxing(data);
// }
//#if !REFLECTION_DISABLED
// public void InjectRaw(object obj)
// {
// _injectionGraph.InjectRaw(obj);
// }
//#endif
}
public interface IInjectionBlock
{
void InjectTo(BlockInjector i);
}
}

View File

@ -0,0 +1,23 @@
namespace DCFApixels.DragonECS
{
public interface IInjectionBlock
{
void InjectTo(Injector inj);
}
public readonly struct InjectionBranchIniter
{
private readonly Injector _injector;
public InjectionBranchIniter(Injector injector)
{
_injector = injector;
}
public void AddNode<T>()
{
_injector.AddNode<T>();
}
}
public interface IInjectionUnit
{
void OnInitInjectionBranch(InjectionBranchIniter initer);
}
}

View File

@ -24,6 +24,13 @@ namespace DCFApixels.DragonECS
public EcsRunnerImplementationException(string message) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message) { } public EcsRunnerImplementationException(string message) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message) { }
public EcsRunnerImplementationException(string message, Exception inner) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message, inner) { } public EcsRunnerImplementationException(string message, Exception inner) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message, inner) { }
} }
[Serializable]
public class EcsInjectionException : Exception
{
public EcsInjectionException() { }
public EcsInjectionException(string message) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message) { }
public EcsInjectionException(string message, Exception inner) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message, inner) { }
}
} }
namespace DCFApixels.DragonECS.Internal namespace DCFApixels.DragonECS.Internal