Skip to content

Commit c29300c

Browse files
Merge pull request #3 from tanitaka-tech/perf/module
improve performance(17.54%)
2 parents 92c9500 + 9ae0052 commit c29300c

8 files changed

+96
-158
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "com.tanitaka-tech.nested-di-container",
33
"displayName": "Nested DI Container",
4-
"version": "0.0.0",
4+
"version": "0.1.0",
55
"unity": "2022.3",
66
"author": "tanitaka-tech",
77
"description": "",

src/NestedDIContainer/Runtime/DependencyBinder.cs

+6-12
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,20 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Linq;
43

54
namespace TanitakaTech.NestedDIContainer
65
{
76
public readonly ref struct DependencyBinder
87
{
9-
private readonly ScopeId _scopeId;
10-
private readonly Dictionary<ScopeId, IScope> _scopes;
11-
private readonly Modules _modules;
8+
private readonly ScopeContainer _scopeContainer;
129

13-
public DependencyBinder(ScopeId scopeId, Dictionary<ScopeId, IScope> scopes, Modules modules)
10+
public DependencyBinder(ScopeContainer scopeContainer)
1411
{
15-
_scopeId = scopeId;
16-
_scopes = scopes;
17-
_modules = modules;
12+
_scopeContainer = scopeContainer;
1813
}
1914

2015
public void ExtendScope(IExtendScope scope)
2116
{
22-
GlobalProjectScope.Inject(scope, GlobalProjectScope.Scopes[_scopeId]);
17+
_scopeContainer.Inject(scope);
2318
scope.Construct(this);
2419
}
2520

@@ -29,10 +24,9 @@ public T ExtendScope<T>() where T : IExtendScope
2924
var constructor = type.GetConstructors().First();
3025
var parameters = constructor.GetParameters();
3126
var parameterValues = new object[parameters.Length];
32-
_scopes.TryGetValue(_scopeId, out var scope);
3327
for (int i = 0; i < parameters.Length; i++)
3428
{
35-
parameterValues[i] = _modules.Resolve(parameters[i].ParameterType, scope);
29+
parameterValues[i] = _scopeContainer.Resolve(parameters[i].ParameterType);
3630
}
3731
var instance = (T)Activator.CreateInstance(type, parameterValues);
3832

@@ -49,7 +43,7 @@ public TResult ExtendScopeWithResult<T, TResult>() where T : IExtendScopeWithRes
4943

5044
public void Bind(Type type, object instance)
5145
{
52-
GlobalProjectScope.Modules.Bind(_scopeId, type, instance);
46+
_scopeContainer.Bind(type, instance);
5347
}
5448

5549
public void Bind<T>(T instance) => Bind(typeof(T), instance);

src/NestedDIContainer/Runtime/GlobalProjectScope.cs

-62
This file was deleted.

src/NestedDIContainer/Runtime/GlobalProjectScope.cs.meta

-3
This file was deleted.

src/NestedDIContainer/Runtime/IScope.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
public interface IScope : IInjectable
44
{
55
void Construct(DependencyBinder binder, object config);
6-
ScopeId ScopeId { get; set; }
7-
ScopeId? ParentScopeId { get; set; }
6+
ScopeId ScopeId { get; }
7+
ScopeId? ParentScopeId { get; }
8+
ScopeContainer ScopeContainer { get; }
89
}
910
}

src/NestedDIContainer/Runtime/Modules.cs

-78
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Reflection;
4+
using NestedDIContainer.Unity.Runtime;
5+
6+
namespace TanitakaTech.NestedDIContainer
7+
{
8+
public class ScopeContainer
9+
{
10+
private readonly Dictionary<IntPtr, object> _value = new Dictionary<IntPtr, object>();
11+
private readonly IScope _scope;
12+
private readonly ScopeContainer _parentScopeContainer;
13+
public IScope Scope => _scope;
14+
public IScope ParentScope => _parentScopeContainer?.Scope;
15+
16+
public ScopeContainer(IScope scope, ScopeContainer parentScopeContainer)
17+
{
18+
_scope = scope;
19+
_parentScopeContainer = parentScopeContainer;
20+
}
21+
22+
public void Bind(Type type, object module)
23+
{
24+
var key = type.TypeHandle.Value;
25+
if (!_value.TryAdd(key, module))
26+
{
27+
throw new ConstructException($"Module already exists: {type}, {_scope}");
28+
}
29+
}
30+
31+
public void Remove(Type type)
32+
{
33+
var key = type.TypeHandle.Value;
34+
(_value[key] as IDisposable)?.Dispose();
35+
_value.Remove(key);
36+
}
37+
38+
public void RemoveScope()
39+
{
40+
_value.Clear();
41+
}
42+
43+
public T Resolve<T>()
44+
{
45+
return (T)Resolve(typeof(T));
46+
}
47+
48+
public object Resolve(Type type)
49+
{
50+
var typePtr = type.TypeHandle.Value;
51+
if (_value.TryGetValue(typePtr, out var module))
52+
return module;
53+
54+
if (_parentScopeContainer != null)
55+
{
56+
return _parentScopeContainer.Resolve(type);
57+
}
58+
throw new ConstructException($"Module not found: {type}");
59+
}
60+
61+
private const BindingFlags MemberBindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly;
62+
public void Inject(object injectableObject)
63+
{
64+
var type = injectableObject.GetType();
65+
var fields = type.GetFields(MemberBindingFlags);
66+
foreach (var field in fields)
67+
{
68+
var injectAttr = field.GetCustomAttribute<InjectAttribute>();
69+
if (injectAttr != null)
70+
{
71+
field.SetValue(injectableObject, Resolve(field.FieldType));
72+
}
73+
}
74+
75+
var props = type.GetProperties(MemberBindingFlags);
76+
foreach (var prop in props)
77+
{
78+
var injectAttr = prop.GetCustomAttribute<InjectAttribute>();
79+
if (injectAttr != null)
80+
{
81+
prop.SetValue(Scope, Resolve(prop.PropertyType));
82+
}
83+
}
84+
}
85+
}
86+
}

0 commit comments

Comments
 (0)