Skip to content

Commit 4105657

Browse files
committed
resolved #83
1 parent 3322d6b commit 4105657

File tree

8 files changed

+214
-40
lines changed

8 files changed

+214
-40
lines changed

src/CatLib.Core.Tests/Support/Container/BindDataTests.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,15 @@ public void CanOnRelease()
177177
public void CheckIllegalRelease()
178178
{
179179
var container = new Container();
180-
var bindData = container.Bind("CheckIllegalRelease", (app, param) => "hello world", false);
180+
var bindData = container.Bind("CheckIllegalRelease", (app, param) => "hello world", true);
181181

182182
ExceptionAssert.Throws<ArgumentNullException>(() =>
183183
{
184184
bindData.OnRelease(null);
185185
});
186186

187+
bindData.Unbind();
188+
bindData = container.Bind("CheckIllegalRelease", (app, param) => "hello world", false);
187189
ExceptionAssert.Throws<RuntimeException>(() =>
188190
{
189191
bindData.OnRelease((obj) =>

src/CatLib.Core.Tests/Support/Container/ContainerTests.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2618,6 +2618,55 @@ public void TestExistsThisSet()
26182618
container["hello"] = 123;
26192619
Assert.AreEqual(123, container.Make("hello"));
26202620
}
2621+
2622+
[TestMethod]
2623+
public void TestOnAfterResolving()
2624+
{
2625+
var container = new Container();
2626+
var val = 0;
2627+
container.OnAfterResolving((_) =>
2628+
{
2629+
Assert.AreEqual(10, val);
2630+
val = 20;
2631+
});
2632+
container.OnAfterResolving((_,__) =>
2633+
{
2634+
Assert.AreEqual(20, val);
2635+
val = 30;
2636+
});
2637+
container.OnResolving((_, __) =>
2638+
{
2639+
Assert.AreEqual(0, val);
2640+
val = 10;
2641+
});
2642+
2643+
container["hello"] = "hello";
2644+
Assert.AreEqual("hello", container["hello"]);
2645+
Assert.AreEqual(30, val);
2646+
}
2647+
2648+
[TestMethod]
2649+
public void TestOnAfterResolvingLocal()
2650+
{
2651+
var container = new Container();
2652+
var val = 0;
2653+
container.Bind("hello", (_, __) => "world").OnAfterResolving(() =>
2654+
{
2655+
Assert.AreEqual(10, val);
2656+
val = 20;
2657+
}).OnAfterResolving((_) =>
2658+
{
2659+
Assert.AreEqual(20, val);
2660+
val = 30;
2661+
}).OnResolving(() =>
2662+
{
2663+
Assert.AreEqual(0, val);
2664+
val = 10;
2665+
});
2666+
2667+
Assert.AreEqual("world", container["hello"]);
2668+
Assert.AreEqual(30, val);
2669+
}
26212670
#endregion
26222671

26232672
/// <summary>

src/CatLib.Core/Support/Container/BindData.cs

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ internal sealed class BindData : Bindable<IBindData>, IBindData
3434
/// </summary>
3535
private List<Action<IBindData, object>> resolving;
3636

37+
/// <summary>
38+
/// 在服务构建修饰器之后的修饰器
39+
/// </summary>
40+
private List<Action<IBindData, object>> afterResolving;
41+
3742
/// <summary>
3843
/// 服务构造修饰器
3944
/// </summary>
@@ -102,18 +107,18 @@ public IBindData Tag(string tag)
102107
/// <returns>服务绑定数据</returns>
103108
public IBindData OnResolving(Action<IBindData, object> closure)
104109
{
105-
Guard.NotNull(closure, nameof(closure));
106-
lock (SyncRoot)
107-
{
108-
GuardIsDestroy();
109-
110-
if (resolving == null)
111-
{
112-
resolving = new List<Action<IBindData, object>>();
113-
}
110+
AddClosure(closure, ref resolving);
111+
return this;
112+
}
114113

115-
resolving.Add(closure);
116-
}
114+
/// <summary>
115+
/// 解决服务时事件之后的回调
116+
/// </summary>
117+
/// <param name="closure">解决事件</param>
118+
/// <returns>服务绑定数据</returns>
119+
public IBindData OnAfterResolving(Action<IBindData, object> closure)
120+
{
121+
AddClosure(closure, ref afterResolving);
117122
return this;
118123
}
119124

@@ -124,23 +129,13 @@ public IBindData OnResolving(Action<IBindData, object> closure)
124129
/// <returns>服务绑定数据</returns>
125130
public IBindData OnRelease(Action<IBindData, object> closure)
126131
{
127-
Guard.NotNull(closure, nameof(closure));
128132
if (!IsStatic)
129133
{
130134
throw new LogicException(
131135
$"Service [{Service}] is not Singleton(Static) Bind , Can not call {nameof(OnRelease)}().");
132136
}
133-
lock (SyncRoot)
134-
{
135-
GuardIsDestroy();
136-
137-
if (release == null)
138-
{
139-
release = new List<Action<IBindData, object>>();
140-
}
141137

142-
release.Add(closure);
143-
}
138+
AddClosure(closure, ref release);
144139
return this;
145140
}
146141

@@ -162,6 +157,16 @@ internal object TriggerResolving(object instance)
162157
return Container.Trigger(this, instance, resolving);
163158
}
164159

160+
/// <summary>
161+
/// 执行服务修饰器之后的回调
162+
/// </summary>
163+
/// <param name="instance">服务实例</param>
164+
/// <returns>服务实例</returns>
165+
internal object TriggerAfterResolving(object instance)
166+
{
167+
return Container.Trigger(this, instance, afterResolving);
168+
}
169+
165170
/// <summary>
166171
/// 执行服务释放处理器
167172
/// </summary>
@@ -171,5 +176,27 @@ internal object TriggerRelease(object instance)
171176
{
172177
return Container.Trigger(this, instance, release);
173178
}
179+
180+
/// <summary>
181+
/// 增加一个事件
182+
/// </summary>
183+
/// <param name="closure">闭包</param>
184+
/// <param name="list">事件列表</param>
185+
private void AddClosure(Action<IBindData, object> closure, ref List<Action<IBindData, object>> list)
186+
{
187+
Guard.NotNull(closure, nameof(closure));
188+
189+
lock (SyncRoot)
190+
{
191+
GuardIsDestroy();
192+
193+
if (list == null)
194+
{
195+
list = new List<Action<IBindData, object>>();
196+
}
197+
198+
list.Add(closure);
199+
}
200+
}
174201
}
175202
}

src/CatLib.Core/Support/Container/BindDataExtend.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,36 @@ public static IBindData OnResolving(this IBindData bindData, Action action)
4848
});
4949
}
5050

51+
/// <summary>
52+
/// 解决服务事件之后的回调
53+
/// </summary>
54+
/// <param name="bindData">绑定数据</param>
55+
/// <param name="action">解决事件</param>
56+
/// <returns>服务绑定数据</returns>
57+
public static IBindData OnAfterResolving(this IBindData bindData, Action<object> action)
58+
{
59+
Guard.Requires<ArgumentNullException>(action != null);
60+
return bindData.OnAfterResolving((_, instance) =>
61+
{
62+
action(instance);
63+
});
64+
}
65+
66+
/// <summary>
67+
/// 解决服务事件之后的回调
68+
/// </summary>
69+
/// <param name="bindData">绑定数据</param>
70+
/// <param name="action">解决事件</param>
71+
/// <returns>服务绑定数据</returns>
72+
public static IBindData OnAfterResolving(this IBindData bindData, Action action)
73+
{
74+
Guard.Requires<ArgumentNullException>(action != null);
75+
return bindData.OnAfterResolving((_, instance) =>
76+
{
77+
action();
78+
});
79+
}
80+
5181
/// <summary>
5282
/// 当静态服务被释放时
5383
/// </summary>

src/CatLib.Core/Support/Container/Container.cs

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ public class Container : IContainer
5656
/// </summary>
5757
private readonly List<Action<IBindData, object>> resolving;
5858

59+
/// <summary>
60+
/// 在服务构建修饰器之后的修饰器
61+
/// </summary>
62+
private readonly List<Action<IBindData, object>> afterResloving;
63+
5964
/// <summary>
6065
/// 静态服务释放时的修饰器
6166
/// </summary>
@@ -146,6 +151,7 @@ public Container(int prime = 64)
146151
instancesReverse = new Dictionary<object, string>(prime * 4);
147152
binds = new Dictionary<string, BindData>(prime * 4);
148153
resolving = new List<Action<IBindData, object>>((int)(prime * 0.25));
154+
afterResloving = new List<Action<IBindData, object>>((int)(prime * 0.25));
149155
release = new List<Action<IBindData, object>>((int)(prime * 0.25));
150156
extenders = new Dictionary<string, List<Func<object, IContainer, object>>>((int)(prime * 0.25));
151157
resolved = new HashSet<string>();
@@ -686,14 +692,13 @@ public object Instance(string service, object instance)
686692
{
687693
throw new LogicException($"Service [{service}] is not Singleton(Static) Bind.");
688694
}
689-
instance = ((BindData)bindData).TriggerResolving(instance);
690695
}
691696
else
692697
{
693698
bindData = MakeEmptyBindData(service);
694699
}
695700

696-
instance = TriggerOnResolving(bindData, instance);
701+
instance = TriggerOnResolving((BindData)bindData, instance);
697702

698703
if (instance != null
699704
&& instancesReverse.TryGetValue(instance, out string realService)
@@ -787,12 +792,7 @@ public IContainer OnFindType(Func<string, Type> finder, int priority = int.MaxVa
787792
/// <returns>当前容器实例</returns>
788793
public IContainer OnRelease(Action<IBindData, object> closure)
789794
{
790-
Guard.NotNull(closure, nameof(closure));
791-
lock (syncRoot)
792-
{
793-
GuardFlushing();
794-
release.Add(closure);
795-
}
795+
AddClosure(closure, release);
796796
return this;
797797
}
798798

@@ -803,12 +803,18 @@ public IContainer OnRelease(Action<IBindData, object> closure)
803803
/// <returns>当前容器对象</returns>
804804
public IContainer OnResolving(Action<IBindData, object> closure)
805805
{
806-
Guard.NotNull(closure, nameof(closure));
807-
lock (syncRoot)
808-
{
809-
GuardFlushing();
810-
resolving.Add(closure);
811-
}
806+
AddClosure(closure, resolving);
807+
return this;
808+
}
809+
810+
/// <summary>
811+
/// 解决服务时事件之后的回调
812+
/// </summary>
813+
/// <param name="closure">解决事件</param>
814+
/// <returns>服务绑定数据</returns>
815+
public IContainer OnAfterResolving(Action<IBindData, object> closure)
816+
{
817+
AddClosure(closure, afterResloving);
812818
return this;
813819
}
814820

@@ -838,6 +844,7 @@ public IContainer OnRebound(string service, Action<object> callback)
838844
{
839845
rebound[service] = list = new List<Action<object>>();
840846
}
847+
841848
list.Add(callback);
842849
}
843850
return this;
@@ -1700,9 +1707,23 @@ private string AliasToService(string service)
17001707
/// <param name="bindData">服务绑定数据</param>
17011708
/// <param name="instance">服务实例</param>
17021709
/// <returns>被修饰器修饰后的服务实例</returns>
1703-
private object TriggerOnResolving(IBindData bindData, object instance)
1710+
private object TriggerOnResolving(BindData bindData, object instance)
17041711
{
1705-
return Trigger(bindData, instance, resolving);
1712+
instance = bindData.TriggerResolving(instance);
1713+
instance = Trigger(bindData, instance, resolving);
1714+
return TriggerOnAfterResolving(bindData, instance);
1715+
}
1716+
1717+
/// <summary>
1718+
/// 触发全局解决修饰器之后的修饰器回调
1719+
/// </summary>
1720+
/// <param name="bindData">服务绑定数据</param>
1721+
/// <param name="instance">服务实例</param>
1722+
/// <returns>被修饰器修饰后的服务实例</returns>
1723+
private object TriggerOnAfterResolving(BindData bindData, object instance)
1724+
{
1725+
instance = bindData.TriggerAfterResolving(instance);
1726+
return Trigger(bindData, instance, afterResloving);
17061727
}
17071728

17081729
/// <summary>
@@ -1865,7 +1886,7 @@ private object Resolve(string service, params object[] userParams)
18651886

18661887
instance = bindData.IsStatic
18671888
? Instance(bindData.Service, instance)
1868-
: TriggerOnResolving(bindData, bindData.TriggerResolving(instance));
1889+
: TriggerOnResolving(bindData, instance);
18691890

18701891
resolved.Add(bindData.Service);
18711892
return instance;
@@ -2017,5 +2038,21 @@ private Func<ParameterInfo, object> MakeParamsMatcher(IParams[] tables)
20172038
return null;
20182039
};
20192040
}
2041+
2042+
/// <summary>
2043+
/// 增加一个闭包到指定的列表
2044+
/// </summary>
2045+
/// <param name="closure">闭包</param>
2046+
/// <param name="list">指定的列表</param>
2047+
private void AddClosure(Action<IBindData, object> closure, List<Action<IBindData, object>> list)
2048+
{
2049+
Guard.NotNull(closure, nameof(closure));
2050+
2051+
lock (syncRoot)
2052+
{
2053+
GuardFlushing();
2054+
list.Add(closure);
2055+
}
2056+
}
20202057
}
20212058
}

src/CatLib.Core/Support/Container/ContainerExtend.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,21 @@ public static IContainer OnResolving(this IContainer container, Action<object> c
772772
});
773773
}
774774

775+
/// <summary>
776+
/// 当服务被解决事件之后的回调
777+
/// </summary>
778+
/// <param name="container">服务容器</param>
779+
/// <param name="callback">回调函数</param>
780+
/// <returns>当前容器对象</returns>
781+
public static IContainer OnAfterResolving(this IContainer container, Action<object> callback)
782+
{
783+
Guard.Requires<ArgumentNullException>(callback != null);
784+
return container.OnAfterResolving((_, instance) =>
785+
{
786+
callback(instance);
787+
});
788+
}
789+
775790
/// <summary>
776791
/// 关注指定的服务,当服务触发重定义时调用指定对象的指定方法
777792
/// <para>调用是以依赖注入的形式进行的</para>

src/CatLib.Core/Support/Container/IBindData.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ public interface IBindData : IBindable<IBindData>
5656
/// <returns>服务绑定数据</returns>
5757
IBindData OnResolving(Action<IBindData, object> closure);
5858

59+
/// <summary>
60+
/// 解决服务时事件之后的回调
61+
/// </summary>
62+
/// <param name="closure">解决事件</param>
63+
/// <returns>服务绑定数据</returns>
64+
IBindData OnAfterResolving(Action<IBindData, object> closure);
65+
5966
/// <summary>
6067
/// 当服务被释放时
6168
/// </summary>

0 commit comments

Comments
 (0)