Skip to content

Commit

Permalink
Add UnbindByInstance method on binder [Resolves #59 and #60]
Browse files Browse the repository at this point in the history
  • Loading branch information
intentor committed Nov 30, 2016
1 parent c92f0df commit 575730a
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 24 deletions.
1 change: 1 addition & 0 deletions src/Assets/Adic/CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
66 changes: 45 additions & 21 deletions src/Assets/Adic/Scripts/Framework/Binding/Binder.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Adic.Injection;
using Adic.Exceptions;

namespace Adic.Binding {
Expand All @@ -14,7 +15,13 @@ public class Binder : IBinder {
/// <summary>Occurs before a binding is removed.</summary>
public event BindingRemovedHandler beforeRemoveBinding;
/// <summary>Occurs after a binding is removed.</summary>
public event BindingRemovedHandler afterRemoveBinding;
public event BindingRemovedHandler afterRemoveBinding;

/// <summary>
/// Checks whether a binding can be removed.
/// </summary>
/// <param name="binding">Binding to be evaluated.</param>
public delegate bool CanRemoveBindingHandler(BindingInfo binding);

/// <summary>Type bindings of the binder.</summary>
protected Dictionary<Type, IList<BindingInfo>> typeBindings = new Dictionary<Type, IList<BindingInfo>>();
Expand Down Expand Up @@ -260,29 +267,46 @@ public void Unbind(Type type) {
/// </summary>
/// <param name="identifier">The identifier to be unbound.</param>
public void Unbind(object identifier) {
var bindingsToRemove = new List<BindingInfo>();
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);
/// <summary>
/// Unbinds any bindings that holds the given instance, either as a value or on conditions.
/// </summary>
/// <param name="instance">Instance.</param>
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);
}
/// <summary>
/// Unbinds bindings using a given condition.
/// </summary>
/// <param name="canRemoveBinding">Condition to check for bindings removal.</param>
protected void Unbind(CanRemoveBindingHandler canRemoveBinding) {
var bindingsToRemove = new List<BindingInfo>();

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);
}
}
}
}
}

/// <summary>
/// Resolves the binding provider.
Expand Down
8 changes: 7 additions & 1 deletion src/Assets/Adic/Scripts/Framework/Binding/IBinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ public interface IBinder : IBindingCreator {
/// Unbinds any bindings to a certain <paramref name="identifier"/>.
/// </summary>
/// <param name="identifier">The identifier to be unbound.</param>
void Unbind(object identifier);
void Unbind(object identifier);

/// <summary>
/// Unbinds any bindings that holds the given instance, either as a value or on conditions.
/// </summary>
/// <param name="instance">Instance.</param>
void UnbindInstance(object instance);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
18 changes: 17 additions & 1 deletion src/Assets/Tests/Editor/BinderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<MockClassToDepend>().ToSelf();
binder.Bind<MockClassToDepend>().ToSelf().WhenIntoInstance(instance);
binder.Bind<IMockInterface>().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() {
Expand Down

0 comments on commit 575730a

Please sign in to comment.