diff --git a/src/Assets/Adic/CHANGELOG.txt b/src/Assets/Adic/CHANGELOG.txt index f28a65d..95494d1 100644 --- a/src/Assets/Adic/CHANGELOG.txt +++ b/src/Assets/Adic/CHANGELOG.txt @@ -5,6 +5,11 @@ Copyright (c) 2014-2016 André "Intentor" Martins http://intentor.com.br/ ------------------------------------------------ +Version 2.20.2 (2016-08-11) + +Framework +- Fix singleton binding when ResolutionMode is RETURN_NULL. [Issue #54] + Version 2.20.1 (2016-08-03) Commander extension diff --git a/src/Assets/Adic/Scripts/Framework/Injection/Injector.cs b/src/Assets/Adic/Scripts/Framework/Injection/Injector.cs index 5ae824c..85e40a8 100644 --- a/src/Assets/Adic/Scripts/Framework/Injection/Injector.cs +++ b/src/Assets/Adic/Scripts/Framework/Injection/Injector.cs @@ -51,7 +51,7 @@ public Injector(IReflectionCache cache, IBinder binder, ResolutionMode resolutio /// Type to be resolved. /// The instance or NULL. public T Resolve() { - return (T)this.Resolve(typeof(T), InjectionMember.None, null, null); + return (T)this.Resolve(typeof(T), InjectionMember.None, null, null, false); } /// @@ -64,7 +64,7 @@ public T Resolve() { /// Identifier to look for. /// The instance or NULL. public T Resolve(object identifier) { - return (T)this.Resolve(typeof(T), InjectionMember.None, null, identifier); + return (T)this.Resolve(typeof(T), InjectionMember.None, null, identifier, false); } /// @@ -76,7 +76,7 @@ public T Resolve(object identifier) { /// Type to be resolved. /// The instance or NULL. public object Resolve(Type type) { - return this.Resolve(type, InjectionMember.None, null, null); + return this.Resolve(type, InjectionMember.None, null, null, false); } /// @@ -89,7 +89,7 @@ public object Resolve(Type type) { /// The instance or NULL. public object Resolve(object identifier) { //Given no type will be passed, it'll always resolve an array. - var instances = (object[])this.Resolve(null, InjectionMember.None, null, identifier); + var instances = (object[])this.Resolve(null, InjectionMember.None, null, identifier, false); if (instances != null && instances.Length > 0) { return instances[0]; @@ -108,7 +108,7 @@ public object Resolve(object identifier) { /// Identifier to look for. /// The instance or NULL. public object Resolve(Type type, object identifier) { - return this.Resolve(type, InjectionMember.None, null, identifier); + return this.Resolve(type, InjectionMember.None, null, identifier, false); } /// @@ -185,7 +185,8 @@ public object[] ResolveAll(Type type, object identifier) { /// Member for which the binding is being resolved. /// Parent object in which the resolve is occuring. /// The binding identifier to be looked for. - protected object Resolve(Type type, InjectionMember member, object parentInstance, object identifier) { + /// Always resolve the type, even when resolution mode is null. + protected object Resolve(Type type, InjectionMember member, object parentInstance, object identifier, bool alwaysResolve) { object resolution = null; if (this.beforeResolve != null) { @@ -227,7 +228,7 @@ protected object Resolve(Type type, InjectionMember member, object parentInstanc IList instances = new List(); if (bindings == null) { - if (this.resolutionMode == ResolutionMode.ALWAYS_RESOLVE) { + if (alwaysResolve || this.resolutionMode == ResolutionMode.ALWAYS_RESOLVE) { instances.Add(this.Instantiate(type as Type)); } else { return null; @@ -331,7 +332,7 @@ protected object Inject(object instance, ReflectedClass reflectedClass) { protected void InjectFields(object instance, SetterInfo[] fields) { for (int fieldIndex = 0; fieldIndex < fields.Length; fieldIndex++) { var field = fields[fieldIndex]; - var valueToSet = this.Resolve(field.type, InjectionMember.Field, instance, field.identifier); + var valueToSet = this.Resolve(field.type, InjectionMember.Field, instance, field.identifier, false); field.setter(instance, valueToSet); } } @@ -344,7 +345,8 @@ protected void InjectFields(object instance, SetterInfo[] fields) { protected void InjectProperties(object instance, SetterInfo[] properties) { for (int propertyIndex = 0; propertyIndex < properties.Length; propertyIndex++) { var property = properties[propertyIndex]; - var valueToSet = this.Resolve(property.type, InjectionMember.Property, instance, property.identifier); + var valueToSet = this.Resolve(property.type, InjectionMember.Property, instance, property.identifier, + false); property.setter(instance, valueToSet); } } @@ -485,12 +487,8 @@ protected object[] GetParametersFromInfo(object instance, ParameterInfo[] parame for (int paramIndex = 0; paramIndex < parameters.Length; paramIndex++) { var parameterInfo = parametersInfo[paramIndex]; - parameters[paramIndex] = this.Resolve( - parameterInfo.type, - InjectionMember.Constructor, - instance, - parameterInfo.identifier - ); + parameters[paramIndex] = this.Resolve(parameterInfo.type, InjectionMember.Constructor, instance, + parameterInfo.identifier, false); } return parameters; @@ -517,6 +515,7 @@ protected void OnBeforeAddBinding(IBinder source, ref BindingInfo binding) { var valueTypeIsTheSame = isSingleton && bindingIsType && + bindingFromBinder.value != null && bindingFromBinder.value.GetType().Equals(binding.value); var valueInstanceIsTheSame = isSingleton && @@ -534,8 +533,10 @@ protected void OnBeforeAddBinding(IBinder source, ref BindingInfo binding) { if (existingBinding != null) { binding.value = existingBinding.value; } else { + if (bindingIsType) { - var value = this.Resolve(binding.value as Type); + //Force resolution to prevent returning null on ResolutionMode.RETURN_NULL. + var value = this.Resolve(binding.value as Type, InjectionMember.None, null, null, true); binding.value = value; } else { this.Inject(binding.value); diff --git a/src/Assets/Tests/Editor/InjectorTests.cs b/src/Assets/Tests/Editor/InjectorTests.cs index deb11f0..1f777c0 100755 --- a/src/Assets/Tests/Editor/InjectorTests.cs +++ b/src/Assets/Tests/Editor/InjectorTests.cs @@ -316,5 +316,18 @@ public void TestResolutionModeReturnNullNotBound() { Assert.IsNull(instance); } + + [Test] + public void TestResolutionModeReturnNullSingleton() { + var container = new InjectionContainer(ResolutionMode.RETURN_NULL); + container.Bind().ToSingleton(); + + var instance = container.Resolve(); + + Assert.IsNotNull(instance); + Assert.AreEqual(typeof(MockIClassWithAttributes), instance.GetType()); + Assert.Null(((MockIClassWithAttributes)instance).field4); + Assert.Null(((MockIClassWithAttributes)instance).property4); + } } } \ No newline at end of file