diff --git a/src/Assets/Adic/CHANGELOG.txt b/src/Assets/Adic/CHANGELOG.txt index 9c6398a..e6b076e 100644 --- a/src/Assets/Adic/CHANGELOG.txt +++ b/src/Assets/Adic/CHANGELOG.txt @@ -8,6 +8,7 @@ http://intentor.com.br/ Version 2.20.3 (2016-10-??) Framework +- Added UnbindByInstance method on binder. [Issues #59 and #60] - Fix singleton binding adding type instead of value when binging different types. [Issue #45] Unity Binding Extension diff --git a/src/Assets/Adic/Scripts/Framework/Binding/Binder.cs b/src/Assets/Adic/Scripts/Framework/Binding/Binder.cs index 0ca7a14..6ee6530 100755 --- a/src/Assets/Adic/Scripts/Framework/Binding/Binder.cs +++ b/src/Assets/Adic/Scripts/Framework/Binding/Binder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Adic.Injection; using Adic.Exceptions; namespace Adic.Binding { @@ -14,7 +15,13 @@ public class Binder : IBinder { /// Occurs before a binding is removed. public event BindingRemovedHandler beforeRemoveBinding; /// Occurs after a binding is removed. - public event BindingRemovedHandler afterRemoveBinding; + public event BindingRemovedHandler afterRemoveBinding; + + /// + /// Checks whether a binding can be removed. + /// + /// Binding to be evaluated. + public delegate bool CanRemoveBindingHandler(BindingInfo binding); /// Type bindings of the binder. protected Dictionary> typeBindings = new Dictionary>(); @@ -260,29 +267,46 @@ public void Unbind(Type type) { /// /// The identifier to be unbound. public void Unbind(object identifier) { - var bindingsToRemove = new List(); + this.Unbind(binding => binding.identifier != null && binding.identifier.Equals(identifier)); + } - foreach (var entry in this.typeBindings) { - for (var bindingIndex = 0; bindingIndex < entry.Value.Count; bindingIndex++) { - var binding = entry.Value[bindingIndex]; - bindingsToRemove.Clear(); - - if (binding.identifier != null && binding.identifier.Equals(identifier)) { - bindingsToRemove.Add(binding); + /// + /// Unbinds any bindings that holds the given instance, either as a value or on conditions. + /// + /// Instance. + public void UnbindInstance(object instance) { + this.Unbind(binding => binding.value == instance + || (binding.condition != null && binding.condition(new InjectionContext() { parentInstance = instance }))); + } - if (this.beforeRemoveBinding != null) { - this.beforeRemoveBinding(this, binding.type, bindingsToRemove); - } + /// + /// Unbinds bindings using a given condition. + /// + /// Condition to check for bindings removal. + protected void Unbind(CanRemoveBindingHandler canRemoveBinding) { + var bindingsToRemove = new List(); - entry.Value.RemoveAt(bindingIndex--); - - if (this.afterRemoveBinding != null) { - this.afterRemoveBinding(this, binding.type, bindingsToRemove); - } - } - } - } - } + foreach (var entry in this.typeBindings) { + for (var bindingIndex = 0; bindingIndex < entry.Value.Count; bindingIndex++) { + var binding = entry.Value[bindingIndex]; + bindingsToRemove.Clear(); + + if (canRemoveBinding(binding)) { + bindingsToRemove.Add(binding); + + if (this.beforeRemoveBinding != null) { + this.beforeRemoveBinding(this, binding.type, bindingsToRemove); + } + + entry.Value.RemoveAt(bindingIndex--); + + if (this.afterRemoveBinding != null) { + this.afterRemoveBinding(this, binding.type, bindingsToRemove); + } + } + } + } + } /// /// Resolves the binding provider. diff --git a/src/Assets/Adic/Scripts/Framework/Binding/IBinder.cs b/src/Assets/Adic/Scripts/Framework/Binding/IBinder.cs index 2f544f3..e6e28d7 100755 --- a/src/Assets/Adic/Scripts/Framework/Binding/IBinder.cs +++ b/src/Assets/Adic/Scripts/Framework/Binding/IBinder.cs @@ -99,6 +99,12 @@ public interface IBinder : IBindingCreator { /// Unbinds any bindings to a certain . /// /// The identifier to be unbound. - void Unbind(object identifier); + void Unbind(object identifier); + + /// + /// Unbinds any bindings that holds the given instance, either as a value or on conditions. + /// + /// Instance. + void UnbindInstance(object instance); } } \ No newline at end of file diff --git a/src/Assets/Adic/Scripts/Framework/Container/InjectionContainer.cs b/src/Assets/Adic/Scripts/Framework/Container/InjectionContainer.cs index 946033d..9b6ffb6 100644 --- a/src/Assets/Adic/Scripts/Framework/Container/InjectionContainer.cs +++ b/src/Assets/Adic/Scripts/Framework/Container/InjectionContainer.cs @@ -299,6 +299,10 @@ public void Unbind(Type type) { public void Unbind(object identifier) { this.binder.Unbind(identifier); - } + } + + public void UnbindInstance(object instance) { + this.binder.UnbindInstance(instance); + } } } \ No newline at end of file diff --git a/src/Assets/Tests/Editor/BinderTests.cs b/src/Assets/Tests/Editor/BinderTests.cs index e8ca3b2..bd39124 100755 --- a/src/Assets/Tests/Editor/BinderTests.cs +++ b/src/Assets/Tests/Editor/BinderTests.cs @@ -153,7 +153,23 @@ public void TestUnbindByIdentifier() { Assert.AreEqual(typeof(MockClassToDepend), bindings[0].type); Assert.AreEqual(typeof(IMockInterface), bindings[1].type); Assert.AreEqual("Mock2", bindings[1].identifier); - } + } + + [Test] + public void TestUnbindByInstance() { + var binder = new Binder(); + + var instance = new MockIClassWithAttributes(); + + binder.Bind().ToSelf(); + binder.Bind().ToSelf().WhenIntoInstance(instance); + binder.Bind().To(instance).As("Mock1"); + binder.UnbindInstance(instance); + + var bindings = binder.GetBindings(); + Assert.AreEqual(1, bindings.Count); + Assert.AreEqual(typeof(MockClassToDepend), bindings[0].type); + } [Test] public void TestUnbindSingleton() {