From b06b30ef29fe2b930ed1445f13fdfb26a288416c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=96=B5=E5=96=B5=E5=A4=A7=E4=BA=BA?= Date: Mon, 26 Nov 2018 15:21:44 +0800 Subject: [PATCH 1/9] resolved #79 --- .../Support/Container/BindDataTests.cs | 15 -- .../Support/Container/ContainerHelperTests.cs | 52 +++++ .../Support/Container/ContainerTests.cs | 155 ++++++++++----- src/CatLib.Core/CatLib/App.cs | 30 ++- src/CatLib.Core/Support/Container/BindData.cs | 55 +++--- .../Support/Container/BindDataExtend.cs | 2 - .../Support/Container/Container.cs | 187 +++++++++++++++--- .../Support/Container/ContainerExtend.cs | 27 ++- .../Support/Container/IBindData.cs | 8 +- .../Support/Container/IContainer.cs | 19 +- 10 files changed, 409 insertions(+), 141 deletions(-) diff --git a/src/CatLib.Core.Tests/Support/Container/BindDataTests.cs b/src/CatLib.Core.Tests/Support/Container/BindDataTests.cs index 805835c..0eb5fdc 100644 --- a/src/CatLib.Core.Tests/Support/Container/BindDataTests.cs +++ b/src/CatLib.Core.Tests/Support/Container/BindDataTests.cs @@ -224,21 +224,6 @@ public void TestAddOnResolvingWithExtendNoneInstance() Assert.AreEqual(true, call); } - /// - /// 是否能追加到解决事件 - /// - [TestMethod] - public void CanAddOnResolving() - { - var container = new Container(); - var bindData = new BindData(container, "CanAddOnResolving", (app, param) => "hello world", false); - - bindData.OnResolving((bind, obj) => null); - - var data = bindData.TriggerResolving(new Container()); - Assert.AreEqual(null, data); - } - /// /// 检查无效的解决事件传入参数 /// diff --git a/src/CatLib.Core.Tests/Support/Container/ContainerHelperTests.cs b/src/CatLib.Core.Tests/Support/Container/ContainerHelperTests.cs index c3f2232..1b5ee02 100644 --- a/src/CatLib.Core.Tests/Support/Container/ContainerHelperTests.cs +++ b/src/CatLib.Core.Tests/Support/Container/ContainerHelperTests.cs @@ -354,6 +354,58 @@ public void TestSetAlias() Assert.AreEqual("abc", container.Make()); } + public class TestOnResolvingClass + { + public string Name; + public TestOnResolvingClass() + { + + } + } + + [TestMethod] + public void TestOnResolving() + { + var container = new Container(); + container.Singleton().OnResolving((instance) => + { + var cls = (instance) as TestOnResolvingClass; + Assert.AreEqual(null, cls.Name); + cls.Name = "123"; + }); + + container.OnResolving((instance) => + { + var cls = (instance) as TestOnResolvingClass; + Assert.AreEqual("123", cls.Name); + cls.Name = "222"; + }); + + Assert.AreEqual("222", container.Make().Name); + } + + [TestMethod] + public void TestExtend() + { + var container = new Container(); + container.Extend((instance) => instance + " world"); + container.Bind(() => "hello"); + Assert.AreEqual("hello world", container.Make()); + } + + [TestMethod] + public void TestExtendContainer() + { + var container = new Container(); + container.Extend((instance, _) => + { + Assert.AreSame(container, _); + return instance + " world"; + }); + container.Bind(() => "hello"); + Assert.AreEqual("hello world", container.Make()); + } + /// /// 生成容器 /// diff --git a/src/CatLib.Core.Tests/Support/Container/ContainerTests.cs b/src/CatLib.Core.Tests/Support/Container/ContainerTests.cs index e8a11f4..84e2b82 100644 --- a/src/CatLib.Core.Tests/Support/Container/ContainerTests.cs +++ b/src/CatLib.Core.Tests/Support/Container/ContainerTests.cs @@ -1043,47 +1043,6 @@ public void CheckIllegalMake() }); } - /// - /// 解决器是否有效 - /// - [TestMethod] - public void CanMakeWithResolve() - { - var container = MakeContainer(); - var bind = container.Bind(); - - bind.OnResolving((bindData, obj) => "local resolve"); - container.OnResolving((bindData, obj) => obj + " global resolve"); - var isTrigger = false; - container.OnResolving((obj) => isTrigger = true); - - var result = container.Make(container.Type2Service(typeof(MakeTestClassDependency))); - - Assert.AreEqual(true, isTrigger); - Assert.AreEqual("local resolve global resolve", result); - } - - /// - /// 给与了错误的解决器,导致不正确的返回值 - /// - [TestMethod] - public void CheckMakeWithErrorResolve() - { - var container = MakeContainer(); - var bind = container.Bind(); - container.Bind().Alias("AliasName"); - var bind2 = container.Bind().Alias("AliasNameRequired"); - - bind.OnResolving((bindData, obj) => "local resolve"); - container.OnResolving((bindData, obj) => obj + " global resolve"); - bind2.OnResolving((bindData, obj) => "bind2"); - - ExceptionAssert.Throws(() => - { - container.Make(container.Type2Service(typeof(MakeTestClass))); - }); - } - /// /// 参数注入标记测试类 /// @@ -1808,7 +1767,6 @@ public void OnResolvingExistsObject() container.OnResolving((bind, obj) => { isCall = true; - return obj; }); Assert.AreEqual(false, isCall); @@ -2334,14 +2292,15 @@ public void TestInstanceAndDecorator() var container = new Container(); var oldObject = new object(); object newObject = null; - container.OnResolving((bindData, obj) => + container.Extend("Hello", (instance, c) => { + Console.WriteLine("new"); return newObject = new object(); }); - container.Instance("Hello", oldObject); - - Assert.AreSame(newObject, container["Hello"]); + container.Bind("Hello", (_, __) => oldObject); + var ins = container["Hello"]; + Assert.AreSame(newObject, ins); } [TestMethod] @@ -2527,6 +2486,110 @@ public void TestCannotWatch() { } + + [TestMethod] + public void TestExtend() + { + var container = new Container(); + container.Bind("hello", (_, __) => "hello"); + container.Extend("hello", (instance, c) => instance + " world"); + + Assert.AreEqual("hello world", container["hello"]); + } + + [TestMethod] + public void TestMultExtend() + { + var container = new Container(); + container.Bind("hello", (_, __) => "hello"); + container.Extend("hello", (instance, c) => instance + " world"); + container.Extend("hello", (instance, c) => instance + " miaomiao"); + + Assert.AreEqual("hello world miaomiao", container["hello"]); + } + + [TestMethod] + public void TestClearExtend() + { + var container = new Container(); + container.Bind("hello", (_, __) => "hello"); + container.Extend("hello", (instance, c) => instance + " world"); + container.Extend("hello", (instance, c) => instance + " miaomiao"); + + container.Bind("world", (_, __) => "hello"); + container.Extend("world", (instance, c) => instance + " world"); + container.Extend("world", (instance, c) => instance + " miaomiao"); + + Assert.AreEqual("hello world miaomiao", container["hello"]); + Assert.AreEqual("hello world miaomiao", container["world"]); + + container.ClearExtenders("hello"); + + Assert.AreEqual("hello", container["hello"]); + Assert.AreEqual("hello world miaomiao", container["world"]); + } + + [TestMethod] + public void TestClearExtendNotUse() + { + var container = new Container(); + container.Bind("hello", (_, __) => "hello"); + container.Extend("hello", (instance, c) => instance + " world"); + container.Extend("hello", (instance, c) => instance + " miaomiao"); + container.ClearExtenders("hello"); + Assert.AreEqual("hello", container["hello"]); + } + + [TestMethod] + public void TestExtendSingle() + { + var container = new Container(); + container.Singleton("hello", (_, __) => "hello"); + container.Extend("hello", (instance, c) => instance + " world"); + Assert.AreEqual("hello world", container["hello"]); + container.Extend("hello", (instance, c) => instance + " miaomiao"); + Assert.AreEqual("hello world miaomiao", container["hello"]); + + container.Release("hello"); + Assert.AreEqual("hello world", container["hello"]); + } + + [TestMethod] + public void TestIsResolvedExtend() + { + var container = new Container(); + container.Singleton("hello", (_, __) => "hello"); + container.Make("hello"); + container.Release("hello"); + + var data = ""; + container.OnRebound("hello", (instance) => + { + data = instance.ToString(); + }); + container.Extend("hello", (instance, c) => instance + " world"); + + Assert.AreEqual("hello world", data); + } + + public class TestExtendGivenMismatchedTypeClass + { + public TestExtendGivenMismatchedTypeClass(IContainer container) + { + + } + } + + [TestMethod] + [ExpectedException(typeof(UnresolvableException))] + public void TestExtendGivenMismatchedType() + { + var container = new Container(); + container.Singleton(() => container); + container.Singleton(); + container.Extend((instance) => "123"); + container.Make(); + } #endregion /// diff --git a/src/CatLib.Core/CatLib/App.cs b/src/CatLib.Core/CatLib/App.cs index eed05e7..97ed474 100644 --- a/src/CatLib.Core/CatLib/App.cs +++ b/src/CatLib.Core/CatLib/App.cs @@ -591,6 +591,30 @@ public static Func Factory(string service) return Handler.Factory(service); } + /// + /// 扩展容器中的服务 + /// 允许在服务构建的过程中配置或者替换服务 + /// 如果服务已经被构建,拓展会立即生效。 + /// + /// 服务名或别名 + /// 闭包 + public static void Extend(Func closure) + { + Handler.Extend(closure); + } + + /// + /// 扩展容器中的服务 + /// 允许在服务构建的过程中配置或者替换服务 + /// 如果服务已经被构建,拓展会立即生效。 + /// + /// 服务名或别名 + /// 闭包 + public static void Extend(Func closure) + { + Handler.Extend(closure); + } + /// /// 为服务设定一个别名 /// @@ -605,11 +629,11 @@ public static IContainer Alias(string alias, string service) /// /// 当服务被解决时触发的事件 /// - /// 回调函数 + /// 闭包函数 /// 当前容器实例 - public static IContainer OnResolving(Func func) + public static IContainer OnResolving(Action closure) { - return Handler.OnResolving(func); + return Handler.OnResolving(closure); } /// diff --git a/src/CatLib.Core/Support/Container/BindData.cs b/src/CatLib.Core/Support/Container/BindData.cs index 1c30d27..ee6ca03 100644 --- a/src/CatLib.Core/Support/Container/BindData.cs +++ b/src/CatLib.Core/Support/Container/BindData.cs @@ -32,7 +32,7 @@ internal sealed class BindData : Bindable, IBindData /// /// 服务构造修饰器 /// - private List> resolving; + private List> resolving; /// /// 服务构造修饰器 @@ -98,19 +98,21 @@ public IBindData Tag(string tag) /// /// 解决服务时触发的回调 /// - /// 解决事件 + /// 解决事件 /// 服务绑定数据 - public IBindData OnResolving(Func func) + public IBindData OnResolving(Action closure) { - Guard.NotNull(func, nameof(func)); + Guard.NotNull(closure, nameof(closure)); lock (SyncRoot) { GuardIsDestroy(); + if (resolving == null) { - resolving = new List>(); + resolving = new List>(); } - resolving.Add(func); + + resolving.Add(closure); } return this; } @@ -118,11 +120,11 @@ public IBindData OnResolving(Func func) /// /// 当静态服务被释放时 /// - /// 处理事件 + /// 处理事件 /// 服务绑定数据 - public IBindData OnRelease(Action action) + public IBindData OnRelease(Action closure) { - Guard.NotNull(action, nameof(action)); + Guard.NotNull(closure, nameof(closure)); if (!IsStatic) { throw new RuntimeException($"Service [{Service}] is not Singleton(Static) Bind , Can not call {nameof(OnRelease)}()."); @@ -130,11 +132,13 @@ public IBindData OnRelease(Action action) lock (SyncRoot) { GuardIsDestroy(); + if (release == null) { release = new List>(); } - release.Add(action); + + release.Add(closure); } return this; } @@ -150,36 +154,21 @@ protected override void ReleaseBind() /// /// 执行服务修饰器 /// - /// 服务实例 - /// 修饰后的服务实例 - internal object TriggerResolving(object obj) + /// 服务实例 + /// 服务实例 + internal object TriggerResolving(object instance) { - if (resolving == null) - { - return obj; - } - foreach (var func in resolving) - { - obj = func.Invoke(this, obj); - } - return obj; + return Container.Trigger(this, instance, resolving); } /// /// 执行服务释放处理器 /// - /// 服务实例 - internal void TriggerRelease(object obj) + /// 服务实例 + /// 服务实例 + internal object TriggerRelease(object instance) { - if (release == null) - { - return; - } - - foreach (var action in release) - { - action.Invoke(this, obj); - } + return Container.Trigger(this, instance, release); } } } \ No newline at end of file diff --git a/src/CatLib.Core/Support/Container/BindDataExtend.cs b/src/CatLib.Core/Support/Container/BindDataExtend.cs index c121d3f..59421a9 100644 --- a/src/CatLib.Core/Support/Container/BindDataExtend.cs +++ b/src/CatLib.Core/Support/Container/BindDataExtend.cs @@ -30,7 +30,6 @@ public static IBindData OnResolving(this IBindData bindData, Action acti return bindData.OnResolving((_, instance) => { action(instance); - return instance; }); } @@ -46,7 +45,6 @@ public static IBindData OnResolving(this IBindData bindData, Action action) return bindData.OnResolving((_, instance) => { action(); - return instance; }); } diff --git a/src/CatLib.Core/Support/Container/Container.cs b/src/CatLib.Core/Support/Container/Container.cs index fae1239..ad3e541 100644 --- a/src/CatLib.Core/Support/Container/Container.cs +++ b/src/CatLib.Core/Support/Container/Container.cs @@ -54,13 +54,18 @@ public class Container : IContainer /// /// 服务构建时的修饰器 /// - private readonly List> resolving; + private readonly List> resolving; /// /// 静态服务释放时的修饰器 /// private readonly List> release; + /// + /// 全局服务扩展方法 + /// + private readonly Dictionary>> extenders; + /// /// 类型查询回调 /// 当类型无法被解决时会尝试去开发者提供的查询器中查询类型 @@ -125,7 +130,7 @@ public class Container : IContainer /// /// 服务禁用字符 /// - private static readonly char[] ServiceBanChars = { '@', ':' ,'$'}; + private static readonly char[] ServiceBanChars = { '@', ':', '$' }; /// /// 构造一个容器 @@ -140,8 +145,9 @@ public Container(int prime = 64) instances = new Dictionary(prime * 4); instancesReverse = new Dictionary(prime * 4); binds = new Dictionary(prime * 4); - resolving = new List>((int)(prime * 0.25)); + resolving = new List>((int)(prime * 0.25)); release = new List>((int)(prime * 0.25)); + extenders = new Dictionary>>((int)(prime * 0.25)); resolved = new HashSet(); findType = new SortSet, int>(); findTypeCache = new Dictionary(prime * 4); @@ -569,6 +575,76 @@ public Func Factory(string service, params object[] userParams) return () => Make(service, userParams); } + /// + /// 扩展容器中的服务 + /// 允许在服务构建的过程中配置或者替换服务 + /// 如果服务已经被构建,拓展会立即生效。 + /// + /// 服务名或别名 + /// 闭包 + public void Extend(string service, Func closure) + { + Guard.NotEmptyOrNull(service, nameof(service)); + Guard.Requires(closure != null); + + lock (syncRoot) + { + GuardFlushing(); + service = AliasToService(service); + + if (instances.TryGetValue(service, out object instance)) + { + // 如果实例已经存在那么,那么应用扩展。 + // 扩展将不再被添加到永久扩展列表 + var old = instance; + instances[service] = instance = closure(instance, this); + + if (!old.Equals(instance)) + { + instancesReverse.Remove(old); + instancesReverse.Add(instance, service); + } + + TriggerOnRebound(service, instance); + return; + } + + if (!extenders.TryGetValue(service, out List> extender)) + { + extenders[service] = extender = new List>(); + } + + extender.Add(closure); + + if (IsResolved(service)) + { + TriggerOnRebound(service); + } + } + } + + /// + /// 移除指定服务的全部扩展 + /// + /// 服务名或别名 + public void ClearExtenders(string service) + { + lock (syncRoot) + { + GuardFlushing(); + service = AliasToService(service); + extenders.Remove(service); + + if (!IsResolved(service)) + { + return; + } + + Release(service); + TriggerOnRebound(service); + } + } + /// /// 静态化一个服务,实例值会经过解决修饰器 /// @@ -692,15 +768,15 @@ public IContainer OnFindType(Func finder, int priority = int.MaxVa /// /// 当静态服务被释放时 /// - /// 处理释放时的回调 + /// 处理释放时的回调 /// 当前容器实例 - public IContainer OnRelease(Action callback) + public IContainer OnRelease(Action closure) { - Guard.NotNull(callback, nameof(callback)); + Guard.NotNull(closure, nameof(closure)); lock (syncRoot) { GuardFlushing(); - release.Add(callback); + release.Add(closure); } return this; } @@ -708,15 +784,15 @@ public IContainer OnRelease(Action callback) /// /// 当服务被解决时,生成的服务会经过注册的回调函数 /// - /// 回调函数 + /// 回调函数 /// 当前容器对象 - public IContainer OnResolving(Func callback) + public IContainer OnResolving(Action closure) { - Guard.NotNull(callback, nameof(callback)); + Guard.NotNull(closure, nameof(closure)); lock (syncRoot) { GuardFlushing(); - resolving.Add(callback); + resolving.Add(closure); } return this; } @@ -785,7 +861,7 @@ public void Unbind(string service) } /// - /// 清空容器的所有实例,绑定,别名,标签,解决器 + /// 清空容器的所有实例,绑定,别名,标签,解决器,方法容器, 扩展 /// public virtual void Flush() { @@ -808,6 +884,7 @@ public virtual void Flush() binds.Clear(); resolving.Clear(); release.Clear(); + extenders.Clear(); resolved.Clear(); findType.Clear(); findTypeCache.Clear(); @@ -1204,7 +1281,7 @@ protected virtual object SpeculationServiceByParamName(Bindable makeServiceBindD /// 变量标签 protected virtual char[] GetVariableTags() { - return new [] {'$', '@'}; + return new[] { '$', '@' }; } /// @@ -1627,29 +1704,44 @@ private string AliasToService(string service) /// 触发全局解决修饰器 /// /// 服务绑定数据 - /// 服务实例 + /// 服务实例 /// 被修饰器修饰后的服务实例 - private object TriggerOnResolving(IBindData bindData, object obj) + private object TriggerOnResolving(IBindData bindData, object instance) { - foreach (var func in resolving) - { - obj = func(bindData, obj); - } - return obj; + return Trigger(bindData, instance, resolving); } /// /// 触发全局释放修饰器 /// /// 服务绑定数据 - /// 服务实例 + /// 服务实例 /// 被修饰器修饰后的服务实例 - private void TriggerOnRelease(IBindData bindData, object obj) + private object TriggerOnRelease(IBindData bindData, object instance) + { + return Trigger(bindData, instance, release); + } + + /// + /// 触发指定的事件列表 + /// + /// 服务绑定数据 + /// 服务实例 + /// 事件列表 + /// 服务实例 + internal object Trigger(IBindData bindData, object instance, List> list) { - foreach (var action in release) + if (list == null) { - action.Invoke(bindData, obj); + return instance; + } + + foreach (var closure in list) + { + closure(bindData, instance); } + + return instance; } /// @@ -1768,9 +1860,21 @@ private object Resolve(string service, params object[] userParams) try { var bindData = GetBindFillable(service); - var result = Inject(bindData, Build(bindData, userParams)); + + // 我们将要开始构建服务实例, + // 对于构建的服务我们会尝试进行依赖注入。 + instance = Build(bindData, userParams); + + // 如果我们为指定的服务定义了扩展器,那么我们需要依次执行扩展器, + // 并允许扩展器来修改或者覆盖原始的服务。 + instance = Extend(service, instance); + + instance = bindData.IsStatic + ? Instance(bindData.Service, instance) + : TriggerOnResolving(bindData, bindData.TriggerResolving(instance)); + resolved.Add(bindData.Service); - return result; + return instance; } finally { @@ -1780,22 +1884,39 @@ private object Resolve(string service, params object[] userParams) } } + /// + /// 为服务进行扩展 + /// + /// 服务名 + /// 服务实例 + /// 扩展后的服务 + private object Extend(string service, object instance) + { + if (!extenders.TryGetValue(service, out List> list)) + { + return instance; + } + + foreach (var extender in list) + { + instance = extender(instance, this); + } + + return instance; + } + /// /// 为对象进行依赖注入 /// /// 绑定数据 /// 对象实例 /// 注入完成的对象 - private object Inject(BindData bindData, object instance) + private object Inject(Bindable bindData, object instance) { GuardResolveInstance(instance, bindData.Service); AttributeInject(bindData, instance); - instance = bindData.IsStatic - ? Instance(bindData.Service, instance) - : TriggerOnResolving(bindData, bindData.TriggerResolving(instance)); - return instance; } @@ -1807,10 +1928,12 @@ private object Inject(BindData bindData, object instance) /// 服务实例 private object Build(BindData makeServiceBindData, object[] userParams) { - return makeServiceBindData.Concrete != null + var instance = makeServiceBindData.Concrete != null ? makeServiceBindData.Concrete(this, userParams) : CreateInstance(makeServiceBindData, SpeculatedServiceType(makeServiceBindData.Service), userParams); + + return Inject(makeServiceBindData, instance); } /// diff --git a/src/CatLib.Core/Support/Container/ContainerExtend.cs b/src/CatLib.Core/Support/Container/ContainerExtend.cs index b603aa1..753bccd 100644 --- a/src/CatLib.Core/Support/Container/ContainerExtend.cs +++ b/src/CatLib.Core/Support/Container/ContainerExtend.cs @@ -718,6 +718,32 @@ public static Func Factory(this IContainer container, params return () => (TService)container.Make(container.Type2Service(typeof(TService)), userParams); } + /// + /// 扩展容器中的服务 + /// 允许在服务构建的过程中配置或者替换服务 + /// 如果服务已经被构建,拓展会立即生效。 + /// + /// 服务名或别名 + /// 服务容器 + /// 闭包 + public static void Extend(this IContainer container, Func closure) + { + container.Extend(container.Type2Service(typeof(TService)), closure); + } + + /// + /// 扩展容器中的服务 + /// 允许在服务构建的过程中配置或者替换服务 + /// 如果服务已经被构建,拓展会立即生效。 + /// + /// 服务名或别名 + /// 服务容器 + /// 闭包 + public static void Extend(this IContainer container, Func closure) + { + container.Extend(container.Type2Service(typeof(TService)), (instance, _) => closure(instance)); + } + /// /// 当静态服务被释放时 /// @@ -742,7 +768,6 @@ public static IContainer OnResolving(this IContainer container, Action c return container.OnResolving((_, instance) => { callback(instance); - return instance; }); } diff --git a/src/CatLib.Core/Support/Container/IBindData.cs b/src/CatLib.Core/Support/Container/IBindData.cs index acfd982..78b0cdf 100644 --- a/src/CatLib.Core/Support/Container/IBindData.cs +++ b/src/CatLib.Core/Support/Container/IBindData.cs @@ -52,15 +52,15 @@ public interface IBindData : IBindable /// /// 解决服务时触发的回调 /// - /// 解决事件 + /// 解决事件 /// 服务绑定数据 - IBindData OnResolving(Func func); + IBindData OnResolving(Action closure); /// /// 当服务被释放时 /// - /// 处理事件 + /// 处理事件 /// 服务绑定数据 - IBindData OnRelease(Action action); + IBindData OnRelease(Action closure); } } diff --git a/src/CatLib.Core/Support/Container/IContainer.cs b/src/CatLib.Core/Support/Container/IContainer.cs index 312f87c..03867c4 100644 --- a/src/CatLib.Core/Support/Container/IContainer.cs +++ b/src/CatLib.Core/Support/Container/IContainer.cs @@ -162,7 +162,7 @@ public interface IContainer bool Release(string service); /// - /// 清空容器的所有实例,绑定,别名,标签,解决器,方法容器 + /// 清空容器的所有实例,绑定,别名,标签,解决器,方法容器, 扩展 /// void Flush(); @@ -214,18 +214,27 @@ public interface IContainer /// 当前容器对象 IContainer Alias(string alias, string service); + /// + /// 扩展容器中的服务 + /// 允许在服务构建的过程中配置或者替换服务 + /// 如果服务已经被构建,拓展会立即生效。 + /// + /// 服务名或别名 + /// 闭包 + void Extend(string service, Func closure); + /// /// 当服务被解决时触发的事件 /// - /// 回调函数 + /// 回调函数 /// 当前容器实例 - IContainer OnResolving(Func func); + IContainer OnResolving(Action closure); /// /// 当静态服务被释放时 /// - /// 处理释放时的回调 - IContainer OnRelease(Action action); + /// 处理释放时的回调 + IContainer OnRelease(Action closure); /// /// 当查找类型无法找到时会尝试去调用开发者提供的查找类型函数 From 0882dd5f58a828254603bec24630438bc6bc4344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=96=B5=E5=96=B5=E5=A4=A7=E4=BA=BA?= Date: Mon, 26 Nov 2018 15:49:50 +0800 Subject: [PATCH 2/9] resolved #81 --- .../Support/Container/Container.cs | 27 +++---------------- .../Support/Container/ContainerExtend.cs | 25 +++++++++++++++++ .../Support/Container/IContainer.cs | 14 +++------- 3 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/CatLib.Core/Support/Container/Container.cs b/src/CatLib.Core/Support/Container/Container.cs index ad3e541..4ba2463 100644 --- a/src/CatLib.Core/Support/Container/Container.cs +++ b/src/CatLib.Core/Support/Container/Container.cs @@ -798,7 +798,9 @@ public IContainer OnResolving(Action closure) } /// - /// 当一个已经被解决的服务发生重定义时触发 + /// 关注指定的服务,当服务触发重定义时调用指定对象的指定方法 + /// 调用是以依赖注入的形式进行的 + /// 服务的新建(第一次解决服务)操作并不会触发重定义 /// /// 服务名 /// 回调 @@ -826,29 +828,6 @@ public IContainer OnRebound(string service, Action callback) return this; } - /// - /// 关注指定的服务,当服务触发重定义时调用指定对象的指定方法 - /// 调用是以依赖注入的形式进行的 - /// 服务的新建(第一次解决服务)操作并不会触发重定义 - /// - /// 关注的服务名 - /// 当服务发生重定义时调用的目标 - /// 方法信息 - public void Watch(string service, object target, MethodInfo methodInfo) - { - Guard.Requires(methodInfo != null); - - if (!methodInfo.IsStatic) - { - Guard.Requires(target != null); - } - - OnRebound(service, (instance) => - { - Call(target, methodInfo, instance); - }); - } - /// /// 解除绑定服务 /// diff --git a/src/CatLib.Core/Support/Container/ContainerExtend.cs b/src/CatLib.Core/Support/Container/ContainerExtend.cs index 753bccd..cbaa311 100644 --- a/src/CatLib.Core/Support/Container/ContainerExtend.cs +++ b/src/CatLib.Core/Support/Container/ContainerExtend.cs @@ -11,6 +11,7 @@ using System; using System.Collections.Generic; +using System.Reflection; namespace CatLib { @@ -771,6 +772,30 @@ public static IContainer OnResolving(this IContainer container, Action c }); } + /// + /// 关注指定的服务,当服务触发重定义时调用指定对象的指定方法 + /// 调用是以依赖注入的形式进行的 + /// 服务的新建(第一次解决服务)操作并不会触发重定义 + /// + /// 服务容器 + /// 关注的服务名 + /// 当服务发生重定义时调用的目标 + /// 方法信息 + public static void Watch(this IContainer container, string service, object target, MethodInfo methodInfo) + { + Guard.Requires(methodInfo != null); + + if (!methodInfo.IsStatic) + { + Guard.Requires(target != null); + } + + container.OnRebound(service, (instance) => + { + container.Call(target, methodInfo, instance); + }); + } + /// /// 关注指定的服务,当服务触发重定义时调用指定对象的指定方法 /// 调用是以依赖注入的形式进行的 diff --git a/src/CatLib.Core/Support/Container/IContainer.cs b/src/CatLib.Core/Support/Container/IContainer.cs index 03867c4..3f561bc 100644 --- a/src/CatLib.Core/Support/Container/IContainer.cs +++ b/src/CatLib.Core/Support/Container/IContainer.cs @@ -245,23 +245,15 @@ public interface IContainer IContainer OnFindType(Func func, int priority = int.MaxValue); /// - /// 当一个已经被解决的服务,发生重定义时触发 + /// 关注指定的服务,当服务触发重定义时调用指定对象的指定方法 + /// 调用是以依赖注入的形式进行的 + /// 服务的新建(第一次解决服务)操作并不会触发重定义 /// /// 服务名 /// 回调 /// 服务容器 IContainer OnRebound(string service, Action callback); - /// - /// 关注指定的服务,当服务触发重定义时调用指定对象的指定方法 - /// 调用是以依赖注入的形式进行的 - /// 服务的新建(第一次解决服务)操作并不会触发重定义 - /// - /// 关注的服务名 - /// 当服务发生重定义时调用的目标 - /// 方法信息 - void Watch(string service, object target, MethodInfo methodInfo); - /// /// 在回调区间内暂时性的静态化服务实例 /// From bab3c0219aa288f4d65e063cf3f1cd307d64dbbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=96=B5=E5=96=B5=E5=A4=A7=E4=BA=BA?= Date: Mon, 26 Nov 2018 15:54:40 +0800 Subject: [PATCH 3/9] resolved #71 --- src/CatLib.Core.NetStandard/CatLib.Core.NetStandard.csproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/CatLib.Core.NetStandard/CatLib.Core.NetStandard.csproj b/src/CatLib.Core.NetStandard/CatLib.Core.NetStandard.csproj index 1a3c472..ba0a007 100644 --- a/src/CatLib.Core.NetStandard/CatLib.Core.NetStandard.csproj +++ b/src/CatLib.Core.NetStandard/CatLib.Core.NetStandard.csproj @@ -112,8 +112,11 @@ + + + From 92cf1760c691661c9fe77d847b2c5d20061804d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=96=B5=E5=96=B5=E5=A4=A7=E4=BA=BA?= Date: Mon, 26 Nov 2018 16:09:29 +0800 Subject: [PATCH 4/9] resolved #80 --- .../CatLib.Core.NetStandard.csproj | 1 + src/CatLib.Core/CatLib.Core.csproj | 1 + src/CatLib.Core/CatLib/Application.cs | 8 ++-- src/CatLib.Core/Support/Container/BindData.cs | 2 +- src/CatLib.Core/Support/Container/Bindable.cs | 4 +- .../Support/Container/Container.cs | 41 ++++++++-------- .../Support/Container/MethodContainer.cs | 6 +-- .../Support/Exception/LogicException.cs | 47 +++++++++++++++++++ src/CatLib.Core/Support/SortSet/SortSet.cs | 4 +- src/CatLib.Core/Support/Template/Managed.cs | 4 +- .../Support/Util/Extension/StreamExtension.cs | 2 +- src/CatLib.Core/Support/Util/Version.cs | 2 +- 12 files changed, 85 insertions(+), 37 deletions(-) create mode 100644 src/CatLib.Core/Support/Exception/LogicException.cs diff --git a/src/CatLib.Core.NetStandard/CatLib.Core.NetStandard.csproj b/src/CatLib.Core.NetStandard/CatLib.Core.NetStandard.csproj index ba0a007..e006d96 100644 --- a/src/CatLib.Core.NetStandard/CatLib.Core.NetStandard.csproj +++ b/src/CatLib.Core.NetStandard/CatLib.Core.NetStandard.csproj @@ -99,6 +99,7 @@ + diff --git a/src/CatLib.Core/CatLib.Core.csproj b/src/CatLib.Core/CatLib.Core.csproj index 141ccc7..9604ade 100644 --- a/src/CatLib.Core/CatLib.Core.csproj +++ b/src/CatLib.Core/CatLib.Core.csproj @@ -82,6 +82,7 @@ + diff --git a/src/CatLib.Core/CatLib/Application.cs b/src/CatLib.Core/CatLib/Application.cs index 5da6c5b..5f13edb 100644 --- a/src/CatLib.Core/CatLib/Application.cs +++ b/src/CatLib.Core/CatLib/Application.cs @@ -233,7 +233,7 @@ public virtual void Init() /// /// 初始化 /// - /// 没有调用Bootstrap(...)就尝试初始化时触发 + /// 没有调用Bootstrap(...)就尝试初始化时触发 protected IEnumerator CoroutineInit() { if (!bootstrapped) @@ -267,7 +267,7 @@ protected IEnumerator CoroutineInit() /// 注册服务提供者 /// /// 注册服务提供者 - /// 服务提供者被重复注册时触发 + /// 服务提供者被重复注册时触发 public virtual void Register(IServiceProvider provider) { StartCoroutine(CoroutineRegister(provider)); @@ -277,14 +277,14 @@ public virtual void Register(IServiceProvider provider) /// 注册服务提供者 /// /// 注册服务提供者 - /// 服务提供者被重复注册时触发 + /// 服务提供者被重复注册时触发 protected IEnumerator CoroutineRegister(IServiceProvider provider) { Guard.Requires(provider != null); if (IsRegisted(provider)) { - throw new RuntimeException($"Provider [{provider.GetType()}] is already register."); + throw new LogicException($"Provider [{provider.GetType()}] is already register."); } if (Process == StartProcess.Initing) diff --git a/src/CatLib.Core/Support/Container/BindData.cs b/src/CatLib.Core/Support/Container/BindData.cs index ee6ca03..f9f4e53 100644 --- a/src/CatLib.Core/Support/Container/BindData.cs +++ b/src/CatLib.Core/Support/Container/BindData.cs @@ -127,7 +127,7 @@ public IBindData OnRelease(Action closure) Guard.NotNull(closure, nameof(closure)); if (!IsStatic) { - throw new RuntimeException($"Service [{Service}] is not Singleton(Static) Bind , Can not call {nameof(OnRelease)}()."); + throw new LogicException($"Service [{Service}] is not Singleton(Static) Bind , Can not call {nameof(OnRelease)}()."); } lock (SyncRoot) { diff --git a/src/CatLib.Core/Support/Container/Bindable.cs b/src/CatLib.Core/Support/Container/Bindable.cs index fd794d6..8e207dd 100644 --- a/src/CatLib.Core/Support/Container/Bindable.cs +++ b/src/CatLib.Core/Support/Container/Bindable.cs @@ -85,7 +85,7 @@ internal void AddContextual(string needs, string given) } if (contextual.ContainsKey(needs)) { - throw new RuntimeException($"Needs [{needs}] is already exist."); + throw new LogicException($"Needs [{needs}] is already exist."); } contextual.Add(needs, given); } @@ -117,7 +117,7 @@ protected void GuardIsDestroy() { if (isDestroy) { - throw new RuntimeException("Current bind has be mark Destroy."); + throw new LogicException("Current bind has be mark Destroy."); } } } diff --git a/src/CatLib.Core/Support/Container/Container.cs b/src/CatLib.Core/Support/Container/Container.cs index 4ba2463..7fa1228 100644 --- a/src/CatLib.Core/Support/Container/Container.cs +++ b/src/CatLib.Core/Support/Container/Container.cs @@ -193,7 +193,7 @@ public void Tag(string tag, params string[] service) /// /// 标记名 /// 将会返回标记所对应的所有服务实例 - /// 不存在 + /// 不存在 /// null或者空字符串 public object[] Tagged(string tag) { @@ -202,7 +202,7 @@ public object[] Tagged(string tag) { if (!tags.TryGetValue(tag, out List services)) { - throw new RuntimeException($"Tag [{tag}] is not exist."); + throw new LogicException($"Tag [{tag}] is not exist."); } var result = new object[services.Count]; @@ -321,7 +321,7 @@ public bool IsAlias(string name) /// 别名 /// 映射到的服务名 /// 当前容器对象 - /// 别名冲突或者的绑定与实例都不存在 + /// 别名冲突或者的绑定与实例都不存在 /// ,null或者空字符串 public IContainer Alias(string alias, string service) { @@ -330,7 +330,7 @@ public IContainer Alias(string alias, string service) if (alias == service) { - throw new RuntimeException($"Alias is same as service name: [{alias}]."); + throw new LogicException($"Alias is same as service name: [{alias}]."); } alias = FormatService(alias); @@ -341,7 +341,7 @@ public IContainer Alias(string alias, string service) GuardFlushing(); if (aliases.ContainsKey(alias)) { - throw new RuntimeException($"Alias [{alias}] is already exists."); + throw new LogicException($"Alias [{alias}] is already exists."); } if (!binds.ContainsKey(service) && !instances.ContainsKey(service)) @@ -414,7 +414,7 @@ public IBindData Bind(string service, Type concrete, bool isStatic) Guard.NotNull(concrete, nameof(concrete)); if (IsUnableType(concrete)) { - throw new RuntimeException($"Bind type [{concrete}] can not built"); + throw new LogicException($"Bind type [{concrete}] can not built"); } return Bind(service, WrapperTypeBuilder(service, concrete), isStatic); } @@ -426,7 +426,7 @@ public IBindData Bind(string service, Type concrete, bool isStatic) /// 服务实现 /// 服务是否静态化 /// 服务绑定数据 - /// 绑定冲突 + /// 绑定冲突 /// null public IBindData Bind(string service, Func concrete, bool isStatic) { @@ -441,17 +441,17 @@ public IBindData Bind(string service, Func concret if (binds.ContainsKey(service)) { - throw new RuntimeException($"Bind [{service}] already exists."); + throw new LogicException($"Bind [{service}] already exists."); } if (instances.ContainsKey(service)) { - throw new RuntimeException($"Instances [{service}] is already exists."); + throw new LogicException($"Instances [{service}] is already exists."); } if (aliases.ContainsKey(service)) { - throw new RuntimeException($"Aliase [{service}] is already exists."); + throw new LogicException($"Aliase [{service}] is already exists."); } var bindData = new BindData(this, service, concrete, isStatic); @@ -550,7 +550,7 @@ public object Call(object target, MethodInfo methodInfo, params object[] userPar /// 服务名或别名 /// 用户传入的构造参数 /// null或者空字符串 - /// 出现循环依赖 + /// 出现循环依赖 /// 服务实例,如果构造失败那么返回null public object Make(string service, params object[] userParams) { @@ -651,7 +651,7 @@ public void ClearExtenders(string service) /// 服务名或别名 /// 服务实例,null也是合法的实例值 /// null或者空字符串 - /// 的服务在绑定设置中不是静态的 + /// 的服务在绑定设置中不是静态的 /// 被修饰器处理后的新的实例 public object Instance(string service, object instance) { @@ -669,7 +669,7 @@ public object Instance(string service, object instance) { if (!bindData.IsStatic) { - throw new RuntimeException($"Service [{service}] is not Singleton(Static) Bind."); + throw new LogicException($"Service [{service}] is not Singleton(Static) Bind."); } instance = ((BindData)bindData).TriggerResolving(instance); } @@ -938,7 +938,7 @@ public void Flash(Action callback, params KeyValuePair[] service // 所以我们抛出一个异常来终止该操作。 if (HasBind(service.Key)) { - throw new RuntimeException( + throw new LogicException( $"Flash service [{service.Key}] name has be used for {nameof(Bind)} or {nameof(Alias)}."); } } @@ -1162,7 +1162,6 @@ protected virtual object ResloveAttrClass(Bindable makeServiceBindData, string s { return result; } - throw; } } @@ -1332,11 +1331,11 @@ protected virtual UnresolvableException MakeUnresolvablePrimitiveException(strin /// /// 当前服务名 /// 运行时异常 - protected virtual RuntimeException MakeCircularDependencyException(string service) + protected virtual LogicException MakeCircularDependencyException(string service) { var message = $"Circular dependency detected while for [{service}]."; message += GetBuildStackDebugMessage(); - return new RuntimeException(message); + return new LogicException(message); } /// @@ -1368,7 +1367,7 @@ protected virtual void GuardUserParamsCount(int count) { if (count > 255) { - throw new RuntimeException("Too many parameters , must be less or equal than 255"); + throw new LogicException("Too many parameters , must be less or equal than 255"); } } @@ -1415,7 +1414,7 @@ protected virtual Type SpeculatedServiceType(string service) /// 服务绑定数据 /// 服务实例 /// 服务实例 - /// 属性是必须的或者注入类型和需求类型不一致 + /// 属性是必须的或者注入类型和需求类型不一致 protected virtual void AttributeInject(Bindable makeServiceBindData, object makeServiceInstance) { if (makeServiceInstance == null) @@ -1521,7 +1520,7 @@ protected virtual Func GetParamsMatcher(ref object[] user /// 服务实例的参数信息 /// 输入的构造参数列表 /// 服务所需参数的解决结果 - /// 生成的实例类型和需求类型不一致 + /// 生成的实例类型和需求类型不一致 protected virtual object[] GetDependencies(Bindable makeServiceBindData, ParameterInfo[] baseParams, object[] userParams) { if (baseParams.Length <= 0) @@ -1813,7 +1812,7 @@ private BindData MakeEmptyBindData(string service) /// 用户传入的构造参数 /// 服务实例,如果构造失败那么返回null /// null或者空字符串 - /// 出现循环依赖 + /// 出现循环依赖 /// 无法解决服务 /// 服务实例 private object Resolve(string service, params object[] userParams) diff --git a/src/CatLib.Core/Support/Container/MethodContainer.cs b/src/CatLib.Core/Support/Container/MethodContainer.cs index 182b40d..93fe3bc 100644 --- a/src/CatLib.Core/Support/Container/MethodContainer.cs +++ b/src/CatLib.Core/Support/Container/MethodContainer.cs @@ -80,7 +80,7 @@ public IMethodBind Bind(string method, object target, MethodInfo methodInfo) { if (methodMappings.ContainsKey(method)) { - throw new RuntimeException($"Method [{method}] is already {nameof(Bind)}"); + throw new LogicException($"Method [{method}] is already {nameof(Bind)}"); } var methodBind = new MethodBind(this, container, method, target, methodInfo); @@ -223,9 +223,9 @@ public void Flush() /// 生成一个方法没有找到异常 /// /// - private RuntimeException MakeMethodNotFoundException(string method) + private LogicException MakeMethodNotFoundException(string method) { - return new RuntimeException($"Method [{method}] is not found."); + return new LogicException($"Method [{method}] is not found."); } } } diff --git a/src/CatLib.Core/Support/Exception/LogicException.cs b/src/CatLib.Core/Support/Exception/LogicException.cs new file mode 100644 index 0000000..b81fd7d --- /dev/null +++ b/src/CatLib.Core/Support/Exception/LogicException.cs @@ -0,0 +1,47 @@ +/* + * This file is part of the CatLib package. + * + * (c) Yu Bin + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * Document: http://catlib.io/ + */ + +using System; + +namespace CatLib +{ + /// + /// 代码逻辑异常 + /// + [ExcludeFromCodeCoverage] + public class LogicException : RuntimeException + { + /// + /// 代码逻辑异常 + /// + public LogicException() + { + + } + + /// + /// 代码逻辑异常 + /// + /// 异常消息 + public LogicException(string message) : base(message) + { + } + + /// + /// 代码逻辑异常 + /// + /// 异常消息 + /// 内部异常 + public LogicException(string message, Exception innerException) : base(message, innerException) + { + } + } +} \ No newline at end of file diff --git a/src/CatLib.Core/Support/SortSet/SortSet.cs b/src/CatLib.Core/Support/SortSet/SortSet.cs index 15550fe..2576e4a 100644 --- a/src/CatLib.Core/Support/SortSet/SortSet.cs +++ b/src/CatLib.Core/Support/SortSet/SortSet.cs @@ -142,7 +142,7 @@ public TElement Current { return current.Element; } - throw new RuntimeException($"Can not get {nameof(current)} element"); + throw new LogicException($"Can not get {nameof(current)} element"); } } @@ -157,7 +157,7 @@ object IEnumerator.Current { return current.Element; } - throw new RuntimeException($"Can not get {nameof(current)} element"); + throw new LogicException($"Can not get {nameof(current)} element"); } } diff --git a/src/CatLib.Core/Support/Template/Managed.cs b/src/CatLib.Core/Support/Template/Managed.cs index b1da623..2fd9882 100644 --- a/src/CatLib.Core/Support/Template/Managed.cs +++ b/src/CatLib.Core/Support/Template/Managed.cs @@ -51,7 +51,7 @@ public void Extend(Func builder, string name = null) if (extendBuilder.ContainsKey(name)) { - throw new RuntimeException($"Extend [{name}]({GetType()}) is already exists."); + throw new LogicException($"Extend [{name}]({GetType()}) is already exists."); } extendBuilder.Add(name, builder); @@ -139,7 +139,7 @@ private Func GetExtend(string name) if (!extendBuilder.TryGetValue(name, out Func result)) { - throw new RuntimeException($"Can not find [{name}]({GetType()}) Extend."); + throw new LogicException($"Can not find [{name}]({GetType()}) Extend."); } return result; diff --git a/src/CatLib.Core/Support/Util/Extension/StreamExtension.cs b/src/CatLib.Core/Support/Util/Extension/StreamExtension.cs index 26d2cb3..25ed07a 100644 --- a/src/CatLib.Core/Support/Util/Extension/StreamExtension.cs +++ b/src/CatLib.Core/Support/Util/Extension/StreamExtension.cs @@ -68,7 +68,7 @@ public static string ToText(this Stream source, Encoding encoding = null, bool c { if (!source.CanRead) { - throw new RuntimeException($"Can not read stream, {nameof(source.CanRead)} == false"); + throw new LogicException($"Can not read stream, {nameof(source.CanRead)} == false"); } encoding = encoding ?? Util.Encoding; diff --git a/src/CatLib.Core/Support/Util/Version.cs b/src/CatLib.Core/Support/Util/Version.cs index 02ecaf0..5496177 100644 --- a/src/CatLib.Core/Support/Util/Version.cs +++ b/src/CatLib.Core/Support/Util/Version.cs @@ -223,7 +223,7 @@ private void GuardVersion(string version) { if (!VersionMatcher.IsMatch(version)) { - throw new RuntimeException($"{nameof(version)} is invalid : {version}"); + throw new LogicException($"{nameof(version)} is invalid : {version}"); } } From 98e6ba069a949780618558efa9827ef231f9bb55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=96=B5=E5=96=B5=E5=A4=A7=E4=BA=BA?= Date: Mon, 26 Nov 2018 16:12:51 +0800 Subject: [PATCH 5/9] resolved #64 --- src/CatLib.Core/Support/Container/BindData.cs | 3 ++- src/CatLib.Core/Support/Container/Bindable.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/CatLib.Core/Support/Container/BindData.cs b/src/CatLib.Core/Support/Container/BindData.cs index f9f4e53..3d2146a 100644 --- a/src/CatLib.Core/Support/Container/BindData.cs +++ b/src/CatLib.Core/Support/Container/BindData.cs @@ -127,7 +127,8 @@ public IBindData OnRelease(Action closure) Guard.NotNull(closure, nameof(closure)); if (!IsStatic) { - throw new LogicException($"Service [{Service}] is not Singleton(Static) Bind , Can not call {nameof(OnRelease)}()."); + throw new LogicException( + $"Service [{Service}] is not Singleton(Static) Bind , Can not call {nameof(OnRelease)}()."); } lock (SyncRoot) { diff --git a/src/CatLib.Core/Support/Container/Bindable.cs b/src/CatLib.Core/Support/Container/Bindable.cs index 8e207dd..b32372c 100644 --- a/src/CatLib.Core/Support/Container/Bindable.cs +++ b/src/CatLib.Core/Support/Container/Bindable.cs @@ -21,7 +21,7 @@ public abstract class Bindable : IBindable /// /// 当前绑定的名字 /// - public string Service { get; private set; } + public string Service { get; } /// /// 父级容器 From 4364522e63ba65a0ee8af46a5ed80c802dff832b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=96=B5=E5=96=B5=E5=A4=A7=E4=BA=BA?= Date: Mon, 26 Nov 2018 16:14:37 +0800 Subject: [PATCH 6/9] resolved #80 --- src/CatLib.Core/Support/Exception/CodeStandardException.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CatLib.Core/Support/Exception/CodeStandardException.cs b/src/CatLib.Core/Support/Exception/CodeStandardException.cs index 5dd8719..5a4540d 100644 --- a/src/CatLib.Core/Support/Exception/CodeStandardException.cs +++ b/src/CatLib.Core/Support/Exception/CodeStandardException.cs @@ -17,7 +17,7 @@ namespace CatLib /// 代码规范异常,引发本异常一般由于不正确的使用框架 /// [ExcludeFromCodeCoverage] - public class CodeStandardException : RuntimeException + public class CodeStandardException : LogicException { /// /// 代码规范异常 From 3322d6b8068b3e77a292588f63e41f101d200c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=96=B5=E5=96=B5=E5=A4=A7=E4=BA=BA?= Date: Mon, 26 Nov 2018 16:25:32 +0800 Subject: [PATCH 7/9] resolved #82 --- .../Support/Container/ContainerTests.cs | 28 +++++++++++++++++++ .../Support/Container/Container.cs | 18 +++++++++++- .../Support/Container/IContainer.cs | 2 +- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/CatLib.Core.Tests/Support/Container/ContainerTests.cs b/src/CatLib.Core.Tests/Support/Container/ContainerTests.cs index 84e2b82..e968183 100644 --- a/src/CatLib.Core.Tests/Support/Container/ContainerTests.cs +++ b/src/CatLib.Core.Tests/Support/Container/ContainerTests.cs @@ -2590,6 +2590,34 @@ public void TestExtendGivenMismatchedType() container.Extend((instance) => "123"); container.Make(); } + + [TestMethod] + public void TestThisSet() + { + var container = new Container(); + container["hello"] = "world"; + Assert.AreEqual("world", container.Make("hello")); + } + + [TestMethod] + public void TestMultThisSet() + { + var container = new Container(); + container["hello"] = "world"; + container["world"] = "hello"; + Assert.AreEqual("world", container.Make("hello")); + Assert.AreEqual("hello", container.Make("world")); + } + + [TestMethod] + public void TestExistsThisSet() + { + var container = new Container(); + container["hello"] = "world"; + Assert.AreEqual("world", container.Make("hello")); + container["hello"] = 123; + Assert.AreEqual(123, container.Make("hello")); + } #endregion /// diff --git a/src/CatLib.Core/Support/Container/Container.cs b/src/CatLib.Core/Support/Container/Container.cs index 7fa1228..0d20af7 100644 --- a/src/CatLib.Core/Support/Container/Container.cs +++ b/src/CatLib.Core/Support/Container/Container.cs @@ -562,7 +562,22 @@ public object Make(string service, params object[] userParams) /// /// 服务名或者别名 /// 服务实例,如果构造失败那么返回null - public object this[string service] => Make(service); + public object this[string service] + { + get => Make(service); + set + { + lock (syncRoot) + { + var bind = GetBind(service); + if (bind != null) + { + Unbind(bind); + } + Bind(service, (_, __) => value, false); + } + } + } /// /// 获取一个回调,当执行回调可以生成指定的服务 @@ -899,6 +914,7 @@ internal void Unbind(IBindable bindable) { lock (syncRoot) { + GuardFlushing(); Release(bindable.Service); if (aliasesReverse.TryGetValue(bindable.Service, out List serviceList)) { diff --git a/src/CatLib.Core/Support/Container/IContainer.cs b/src/CatLib.Core/Support/Container/IContainer.cs index 3f561bc..63c8797 100644 --- a/src/CatLib.Core/Support/Container/IContainer.cs +++ b/src/CatLib.Core/Support/Container/IContainer.cs @@ -196,7 +196,7 @@ public interface IContainer /// /// 服务名或者别名 /// 服务实例,如果构造失败那么返回null - object this[string service] { get; } + object this[string service] { get; set; } /// /// 获取一个回调,当执行回调可以生成指定的服务 From 410565746be17836440feb810ee66092348fd60e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=96=B5=E5=96=B5=E5=A4=A7=E4=BA=BA?= Date: Mon, 26 Nov 2018 17:16:53 +0800 Subject: [PATCH 8/9] resolved #83 --- .../Support/Container/BindDataTests.cs | 4 +- .../Support/Container/ContainerTests.cs | 49 +++++++++++++ src/CatLib.Core/Support/Container/BindData.cs | 71 +++++++++++++------ .../Support/Container/BindDataExtend.cs | 30 ++++++++ .../Support/Container/Container.cs | 71 ++++++++++++++----- .../Support/Container/ContainerExtend.cs | 15 ++++ .../Support/Container/IBindData.cs | 7 ++ .../Support/Container/IContainer.cs | 7 ++ 8 files changed, 214 insertions(+), 40 deletions(-) diff --git a/src/CatLib.Core.Tests/Support/Container/BindDataTests.cs b/src/CatLib.Core.Tests/Support/Container/BindDataTests.cs index 0eb5fdc..15ed7dc 100644 --- a/src/CatLib.Core.Tests/Support/Container/BindDataTests.cs +++ b/src/CatLib.Core.Tests/Support/Container/BindDataTests.cs @@ -177,13 +177,15 @@ public void CanOnRelease() public void CheckIllegalRelease() { var container = new Container(); - var bindData = container.Bind("CheckIllegalRelease", (app, param) => "hello world", false); + var bindData = container.Bind("CheckIllegalRelease", (app, param) => "hello world", true); ExceptionAssert.Throws(() => { bindData.OnRelease(null); }); + bindData.Unbind(); + bindData = container.Bind("CheckIllegalRelease", (app, param) => "hello world", false); ExceptionAssert.Throws(() => { bindData.OnRelease((obj) => diff --git a/src/CatLib.Core.Tests/Support/Container/ContainerTests.cs b/src/CatLib.Core.Tests/Support/Container/ContainerTests.cs index e968183..a1019aa 100644 --- a/src/CatLib.Core.Tests/Support/Container/ContainerTests.cs +++ b/src/CatLib.Core.Tests/Support/Container/ContainerTests.cs @@ -2618,6 +2618,55 @@ public void TestExistsThisSet() container["hello"] = 123; Assert.AreEqual(123, container.Make("hello")); } + + [TestMethod] + public void TestOnAfterResolving() + { + var container = new Container(); + var val = 0; + container.OnAfterResolving((_) => + { + Assert.AreEqual(10, val); + val = 20; + }); + container.OnAfterResolving((_,__) => + { + Assert.AreEqual(20, val); + val = 30; + }); + container.OnResolving((_, __) => + { + Assert.AreEqual(0, val); + val = 10; + }); + + container["hello"] = "hello"; + Assert.AreEqual("hello", container["hello"]); + Assert.AreEqual(30, val); + } + + [TestMethod] + public void TestOnAfterResolvingLocal() + { + var container = new Container(); + var val = 0; + container.Bind("hello", (_, __) => "world").OnAfterResolving(() => + { + Assert.AreEqual(10, val); + val = 20; + }).OnAfterResolving((_) => + { + Assert.AreEqual(20, val); + val = 30; + }).OnResolving(() => + { + Assert.AreEqual(0, val); + val = 10; + }); + + Assert.AreEqual("world", container["hello"]); + Assert.AreEqual(30, val); + } #endregion /// diff --git a/src/CatLib.Core/Support/Container/BindData.cs b/src/CatLib.Core/Support/Container/BindData.cs index 3d2146a..566855c 100644 --- a/src/CatLib.Core/Support/Container/BindData.cs +++ b/src/CatLib.Core/Support/Container/BindData.cs @@ -34,6 +34,11 @@ internal sealed class BindData : Bindable, IBindData /// private List> resolving; + /// + /// 在服务构建修饰器之后的修饰器 + /// + private List> afterResolving; + /// /// 服务构造修饰器 /// @@ -102,18 +107,18 @@ public IBindData Tag(string tag) /// 服务绑定数据 public IBindData OnResolving(Action closure) { - Guard.NotNull(closure, nameof(closure)); - lock (SyncRoot) - { - GuardIsDestroy(); - - if (resolving == null) - { - resolving = new List>(); - } + AddClosure(closure, ref resolving); + return this; + } - resolving.Add(closure); - } + /// + /// 解决服务时事件之后的回调 + /// + /// 解决事件 + /// 服务绑定数据 + public IBindData OnAfterResolving(Action closure) + { + AddClosure(closure, ref afterResolving); return this; } @@ -124,23 +129,13 @@ public IBindData OnResolving(Action closure) /// 服务绑定数据 public IBindData OnRelease(Action closure) { - Guard.NotNull(closure, nameof(closure)); if (!IsStatic) { throw new LogicException( $"Service [{Service}] is not Singleton(Static) Bind , Can not call {nameof(OnRelease)}()."); } - lock (SyncRoot) - { - GuardIsDestroy(); - - if (release == null) - { - release = new List>(); - } - release.Add(closure); - } + AddClosure(closure, ref release); return this; } @@ -162,6 +157,16 @@ internal object TriggerResolving(object instance) return Container.Trigger(this, instance, resolving); } + /// + /// 执行服务修饰器之后的回调 + /// + /// 服务实例 + /// 服务实例 + internal object TriggerAfterResolving(object instance) + { + return Container.Trigger(this, instance, afterResolving); + } + /// /// 执行服务释放处理器 /// @@ -171,5 +176,27 @@ internal object TriggerRelease(object instance) { return Container.Trigger(this, instance, release); } + + /// + /// 增加一个事件 + /// + /// 闭包 + /// 事件列表 + private void AddClosure(Action closure, ref List> list) + { + Guard.NotNull(closure, nameof(closure)); + + lock (SyncRoot) + { + GuardIsDestroy(); + + if (list == null) + { + list = new List>(); + } + + list.Add(closure); + } + } } } \ No newline at end of file diff --git a/src/CatLib.Core/Support/Container/BindDataExtend.cs b/src/CatLib.Core/Support/Container/BindDataExtend.cs index 59421a9..951fa70 100644 --- a/src/CatLib.Core/Support/Container/BindDataExtend.cs +++ b/src/CatLib.Core/Support/Container/BindDataExtend.cs @@ -48,6 +48,36 @@ public static IBindData OnResolving(this IBindData bindData, Action action) }); } + /// + /// 解决服务事件之后的回调 + /// + /// 绑定数据 + /// 解决事件 + /// 服务绑定数据 + public static IBindData OnAfterResolving(this IBindData bindData, Action action) + { + Guard.Requires(action != null); + return bindData.OnAfterResolving((_, instance) => + { + action(instance); + }); + } + + /// + /// 解决服务事件之后的回调 + /// + /// 绑定数据 + /// 解决事件 + /// 服务绑定数据 + public static IBindData OnAfterResolving(this IBindData bindData, Action action) + { + Guard.Requires(action != null); + return bindData.OnAfterResolving((_, instance) => + { + action(); + }); + } + /// /// 当静态服务被释放时 /// diff --git a/src/CatLib.Core/Support/Container/Container.cs b/src/CatLib.Core/Support/Container/Container.cs index 0d20af7..3717109 100644 --- a/src/CatLib.Core/Support/Container/Container.cs +++ b/src/CatLib.Core/Support/Container/Container.cs @@ -56,6 +56,11 @@ public class Container : IContainer /// private readonly List> resolving; + /// + /// 在服务构建修饰器之后的修饰器 + /// + private readonly List> afterResloving; + /// /// 静态服务释放时的修饰器 /// @@ -146,6 +151,7 @@ public Container(int prime = 64) instancesReverse = new Dictionary(prime * 4); binds = new Dictionary(prime * 4); resolving = new List>((int)(prime * 0.25)); + afterResloving = new List>((int)(prime * 0.25)); release = new List>((int)(prime * 0.25)); extenders = new Dictionary>>((int)(prime * 0.25)); resolved = new HashSet(); @@ -686,14 +692,13 @@ public object Instance(string service, object instance) { throw new LogicException($"Service [{service}] is not Singleton(Static) Bind."); } - instance = ((BindData)bindData).TriggerResolving(instance); } else { bindData = MakeEmptyBindData(service); } - instance = TriggerOnResolving(bindData, instance); + instance = TriggerOnResolving((BindData)bindData, instance); if (instance != null && instancesReverse.TryGetValue(instance, out string realService) @@ -787,12 +792,7 @@ public IContainer OnFindType(Func finder, int priority = int.MaxVa /// 当前容器实例 public IContainer OnRelease(Action closure) { - Guard.NotNull(closure, nameof(closure)); - lock (syncRoot) - { - GuardFlushing(); - release.Add(closure); - } + AddClosure(closure, release); return this; } @@ -803,12 +803,18 @@ public IContainer OnRelease(Action closure) /// 当前容器对象 public IContainer OnResolving(Action closure) { - Guard.NotNull(closure, nameof(closure)); - lock (syncRoot) - { - GuardFlushing(); - resolving.Add(closure); - } + AddClosure(closure, resolving); + return this; + } + + /// + /// 解决服务时事件之后的回调 + /// + /// 解决事件 + /// 服务绑定数据 + public IContainer OnAfterResolving(Action closure) + { + AddClosure(closure, afterResloving); return this; } @@ -838,6 +844,7 @@ public IContainer OnRebound(string service, Action callback) { rebound[service] = list = new List>(); } + list.Add(callback); } return this; @@ -1700,9 +1707,23 @@ private string AliasToService(string service) /// 服务绑定数据 /// 服务实例 /// 被修饰器修饰后的服务实例 - private object TriggerOnResolving(IBindData bindData, object instance) + private object TriggerOnResolving(BindData bindData, object instance) { - return Trigger(bindData, instance, resolving); + instance = bindData.TriggerResolving(instance); + instance = Trigger(bindData, instance, resolving); + return TriggerOnAfterResolving(bindData, instance); + } + + /// + /// 触发全局解决修饰器之后的修饰器回调 + /// + /// 服务绑定数据 + /// 服务实例 + /// 被修饰器修饰后的服务实例 + private object TriggerOnAfterResolving(BindData bindData, object instance) + { + instance = bindData.TriggerAfterResolving(instance); + return Trigger(bindData, instance, afterResloving); } /// @@ -1865,7 +1886,7 @@ private object Resolve(string service, params object[] userParams) instance = bindData.IsStatic ? Instance(bindData.Service, instance) - : TriggerOnResolving(bindData, bindData.TriggerResolving(instance)); + : TriggerOnResolving(bindData, instance); resolved.Add(bindData.Service); return instance; @@ -2017,5 +2038,21 @@ private Func MakeParamsMatcher(IParams[] tables) return null; }; } + + /// + /// 增加一个闭包到指定的列表 + /// + /// 闭包 + /// 指定的列表 + private void AddClosure(Action closure, List> list) + { + Guard.NotNull(closure, nameof(closure)); + + lock (syncRoot) + { + GuardFlushing(); + list.Add(closure); + } + } } } \ No newline at end of file diff --git a/src/CatLib.Core/Support/Container/ContainerExtend.cs b/src/CatLib.Core/Support/Container/ContainerExtend.cs index cbaa311..6dae4ee 100644 --- a/src/CatLib.Core/Support/Container/ContainerExtend.cs +++ b/src/CatLib.Core/Support/Container/ContainerExtend.cs @@ -772,6 +772,21 @@ public static IContainer OnResolving(this IContainer container, Action c }); } + /// + /// 当服务被解决事件之后的回调 + /// + /// 服务容器 + /// 回调函数 + /// 当前容器对象 + public static IContainer OnAfterResolving(this IContainer container, Action callback) + { + Guard.Requires(callback != null); + return container.OnAfterResolving((_, instance) => + { + callback(instance); + }); + } + /// /// 关注指定的服务,当服务触发重定义时调用指定对象的指定方法 /// 调用是以依赖注入的形式进行的 diff --git a/src/CatLib.Core/Support/Container/IBindData.cs b/src/CatLib.Core/Support/Container/IBindData.cs index 78b0cdf..71af60a 100644 --- a/src/CatLib.Core/Support/Container/IBindData.cs +++ b/src/CatLib.Core/Support/Container/IBindData.cs @@ -56,6 +56,13 @@ public interface IBindData : IBindable /// 服务绑定数据 IBindData OnResolving(Action closure); + /// + /// 解决服务时事件之后的回调 + /// + /// 解决事件 + /// 服务绑定数据 + IBindData OnAfterResolving(Action closure); + /// /// 当服务被释放时 /// diff --git a/src/CatLib.Core/Support/Container/IContainer.cs b/src/CatLib.Core/Support/Container/IContainer.cs index 63c8797..e39d2de 100644 --- a/src/CatLib.Core/Support/Container/IContainer.cs +++ b/src/CatLib.Core/Support/Container/IContainer.cs @@ -230,6 +230,13 @@ public interface IContainer /// 当前容器实例 IContainer OnResolving(Action closure); + /// + /// 解决服务时事件之后的回调 + /// + /// 解决事件 + /// 服务绑定数据 + IContainer OnAfterResolving(Action closure); + /// /// 当静态服务被释放时 /// From c36e95839b06261a1e011f6e384051431d80b84b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=96=B5=E5=96=B5=E5=A4=A7=E4=BA=BA?= Date: Mon, 26 Nov 2018 17:58:48 +0800 Subject: [PATCH 9/9] resolved #84 --- .../Support/Container/BindDataTests.cs | 64 ++++++++++ .../Support/Container/ContainerHelperTests.cs | 85 +++++++++++++ .../Support/Container/BindDataExtend.cs | 110 +++++++++++++++++ .../Support/Container/ContainerExtend.cs | 116 ++++++++++++++++++ 4 files changed, 375 insertions(+) diff --git a/src/CatLib.Core.Tests/Support/Container/BindDataTests.cs b/src/CatLib.Core.Tests/Support/Container/BindDataTests.cs index 15ed7dc..8f8f44d 100644 --- a/src/CatLib.Core.Tests/Support/Container/BindDataTests.cs +++ b/src/CatLib.Core.Tests/Support/Container/BindDataTests.cs @@ -240,6 +240,70 @@ public void CheckIllegalResolving() bindData.OnResolving(null); }); } + + [TestMethod] + public void TestTypeMatchOnResolving() + { + var container = new Container(); + var count = 0; + container.Bind("hello", (_, __) => new ContainerHelperTests.TestTypeMatchOnResolvingClass()) + .OnResolving((instance) => + { + count++; + }).OnResolving((bindData, instance) => + { + Assert.AreNotEqual(null, bindData); + count++; + }).OnAfterResolving((instance) => + { + count++; + }).OnAfterResolving((bindData, instance) => + { + Assert.AreNotEqual(null, bindData); + count++; + }).OnAfterResolving((instance) => + { + count++; + }); + + container.Make("hello"); + + Assert.AreEqual(4, count); + } + + [TestMethod] + public void TestTypeMatchOnRelease() + { + var container = new Container(); + var count = 0; + container.Singleton("hello", (_, __) => new ContainerHelperTests.TestTypeMatchOnResolvingClass()) + .OnRelease((instance) => + { + count++; + }).OnRelease((instance) => + { + count++; + }).OnRelease((bindData,instance) => + { + Assert.AreNotEqual(null, bindData); + count++; + }).OnRelease((bindData, instance) => + { + Assert.AreNotEqual(null, bindData); + count++; + }).OnRelease((bindData, instance) => + { + Assert.AreNotEqual(null, bindData); + count++; + }); + container.Singleton("world", (_, __) => "hello"); + + container.Make("hello"); + + container.Release("hello"); + + Assert.AreEqual(2, count); + } #endregion #region Unbind diff --git a/src/CatLib.Core.Tests/Support/Container/ContainerHelperTests.cs b/src/CatLib.Core.Tests/Support/Container/ContainerHelperTests.cs index 1b5ee02..5c6e358 100644 --- a/src/CatLib.Core.Tests/Support/Container/ContainerHelperTests.cs +++ b/src/CatLib.Core.Tests/Support/Container/ContainerHelperTests.cs @@ -406,6 +406,91 @@ public void TestExtendContainer() Assert.AreEqual("hello world", container.Make()); } + public interface ITypeMatchInterface + { + + } + + public class TestTypeMatchOnResolvingClass : ITypeMatchInterface + { + + } + + [TestMethod] + public void TestTypeMatchOnResolving() + { + var container = new Container(); + container.Bind("hello", (_, __) => new TestTypeMatchOnResolvingClass()); + container["world"] = "hello"; + var count = 0; + container.OnResolving((instance) => + { + count++; + }); + + container.OnResolving((bindData, instance) => + { + Assert.AreNotEqual(null, bindData); + count++; + }); + + container.OnAfterResolving((instance) => + { + count++; + }); + + container.OnAfterResolving((bindData,instance) => + { + Assert.AreNotEqual(null, bindData); + count++; + }); + + container.Make("hello"); + container.Make("world"); + + Assert.AreEqual(4, count); + } + + [TestMethod] + public void TestTypeMatchOnRelease() + { + var container = new Container(); + container.Singleton("hello", (_, __) => new TestTypeMatchOnResolvingClass()); + container.Singleton("world", (_, __) => "hello"); + var count = 0; + var stringCount = 0; + container.OnRelease((instance) => + { + count++; + }); + + container.OnRelease((bindData, instance) => + { + Assert.AreNotEqual(null, bindData); + count++; + }); + + container.OnRelease((instance) => + { + stringCount++; + }); + + container.OnRelease((bindData, instance) => + { + Assert.AreNotEqual(null, bindData); + stringCount++; + }); + + container.Make("hello"); + container.Make("world"); + + container.Release("hello"); + container.Release("world"); + + Assert.AreEqual(2, count); + Assert.AreEqual(2, stringCount); + } + /// /// 生成容器 /// diff --git a/src/CatLib.Core/Support/Container/BindDataExtend.cs b/src/CatLib.Core/Support/Container/BindDataExtend.cs index 951fa70..da4fa11 100644 --- a/src/CatLib.Core/Support/Container/BindDataExtend.cs +++ b/src/CatLib.Core/Support/Container/BindDataExtend.cs @@ -33,6 +33,44 @@ public static IBindData OnResolving(this IBindData bindData, Action acti }); } + /// + /// 解决服务时触发的回调 + /// + /// 指定的类型 + /// 绑定数据 + /// 闭包 + /// 服务绑定数据 + public static IBindData OnResolving(this IBindData bindData, Action closure) + { + Guard.Requires(closure != null); + return bindData.OnResolving((_, instance) => + { + if (instance is T) + { + closure((T)instance); + } + }); + } + + /// + /// 解决服务时触发的回调 + /// + /// 指定的类型 + /// 绑定数据 + /// 闭包 + /// 服务绑定数据 + public static IBindData OnResolving(this IBindData bindData, Action closure) + { + Guard.Requires(closure != null); + return bindData.OnResolving((bind, instance) => + { + if (instance is T) + { + closure(bind, (T)instance); + } + }); + } + /// /// 解决服务时触发的回调 /// @@ -63,6 +101,42 @@ public static IBindData OnAfterResolving(this IBindData bindData, Action }); } + /// + /// 解决服务事件之后的回调 + /// + /// 绑定数据 + /// 解决事件 + /// 服务绑定数据 + public static IBindData OnAfterResolving(this IBindData bindData, Action closure) + { + Guard.Requires(closure != null); + return bindData.OnAfterResolving((_, instance) => + { + if (instance is T) + { + closure((T)instance); + } + }); + } + + /// + /// 解决服务事件之后的回调 + /// + /// 绑定数据 + /// 解决事件 + /// 服务绑定数据 + public static IBindData OnAfterResolving(this IBindData bindData, Action closure) + { + Guard.Requires(closure != null); + return bindData.OnAfterResolving((bind, instance) => + { + if (instance is T) + { + closure(bind, (T)instance); + } + }); + } + /// /// 解决服务事件之后的回调 /// @@ -93,6 +167,42 @@ public static IBindData OnRelease(this IBindData bindData, Action action }); } + /// + /// 当静态服务被释放时 + /// + /// 绑定数据 + /// 处理事件 + /// 服务绑定数据 + public static IBindData OnRelease(this IBindData bindData, Action closure) + { + Guard.Requires(closure != null); + return bindData.OnRelease((_, instance) => + { + if (instance is T) + { + closure((T)instance); + } + }); + } + + /// + /// 当静态服务被释放时 + /// + /// 绑定数据 + /// 处理事件 + /// 服务绑定数据 + public static IBindData OnRelease(this IBindData bindData, Action closure) + { + Guard.Requires(closure != null); + return bindData.OnRelease((bind, instance) => + { + if (instance is T) + { + closure(bind, (T)instance); + } + }); + } + /// /// 当静态服务被释放时 /// diff --git a/src/CatLib.Core/Support/Container/ContainerExtend.cs b/src/CatLib.Core/Support/Container/ContainerExtend.cs index 6dae4ee..ad935b7 100644 --- a/src/CatLib.Core/Support/Container/ContainerExtend.cs +++ b/src/CatLib.Core/Support/Container/ContainerExtend.cs @@ -757,6 +757,42 @@ public static IContainer OnRelease(this IContainer container, Action cal return container.OnRelease((_, instance) => callback(instance)); } + /// + /// 当静态服务被释放时 + /// + /// 服务容器 + /// 处理释放时的回调 + /// 当前容器实例 + public static IContainer OnRelease(this IContainer container, Action closure) + { + Guard.Requires(closure != null); + return container.OnRelease((_, instance) => + { + if (instance is T) + { + closure((T)instance); + } + }); + } + + /// + /// 当静态服务被释放时 + /// + /// 服务容器 + /// 处理释放时的回调 + /// 当前容器实例 + public static IContainer OnRelease(this IContainer container, Action closure) + { + Guard.Requires(closure != null); + return container.OnRelease((bindData, instance) => + { + if (instance is T) + { + closure(bindData, (T)instance); + } + }); + } + /// /// 当服务被解决时,生成的服务会经过注册的回调函数 /// @@ -772,6 +808,46 @@ public static IContainer OnResolving(this IContainer container, Action c }); } + /// + /// 当服务被解决时,生成的服务会经过注册的回调函数 + /// 只有类型和给定的类型相匹配才会被回调 + /// + /// 指定的类型 + /// 服务容器 + /// 闭包 + /// 当前容器对象 + public static IContainer OnResolving(this IContainer container, Action closure) + { + Guard.Requires(closure != null); + return container.OnResolving((_, instance) => + { + if (instance is T) + { + closure((T)instance); + } + }); + } + + /// + /// 当服务被解决时,生成的服务会经过注册的回调函数 + /// 只有类型和给定的类型相匹配才会被回调 + /// + /// 指定的类型 + /// 服务容器 + /// 闭包 + /// 当前容器对象 + public static IContainer OnResolving(this IContainer container, Action closure) + { + Guard.Requires(closure != null); + return container.OnResolving((bindData, instance) => + { + if (instance is T) + { + closure(bindData, (T) instance); + } + }); + } + /// /// 当服务被解决事件之后的回调 /// @@ -787,6 +863,46 @@ public static IContainer OnAfterResolving(this IContainer container, Action + /// 当服务被解决事件之后的回调 + /// 只有类型和给定的类型相匹配才会被回调 + /// + /// 指定的类型 + /// 服务容器 + /// 闭包 + /// 当前容器对象 + public static IContainer OnAfterResolving(this IContainer container, Action closure) + { + Guard.Requires(closure != null); + return container.OnAfterResolving((_, instance) => + { + if (instance is T) + { + closure((T)instance); + } + }); + } + + /// + /// 当服务被解决事件之后的回调 + /// 只有类型和给定的类型相匹配才会被回调 + /// + /// 指定的类型 + /// 服务容器 + /// 闭包 + /// 当前容器对象 + public static IContainer OnAfterResolving(this IContainer container, Action closure) + { + Guard.Requires(closure != null); + return container.OnAfterResolving((bindData, instance) => + { + if (instance is T) + { + closure(bindData, (T)instance); + } + }); + } + /// /// 关注指定的服务,当服务触发重定义时调用指定对象的指定方法 /// 调用是以依赖注入的形式进行的