Skip to content

Commit

Permalink
Property injection only considers parameters on PropertiesAutowired. …
Browse files Browse the repository at this point in the history
…InjectProperties now takes parameters.
  • Loading branch information
Travis Illig committed Aug 24, 2016
1 parent 2df1db2 commit 9c605d3
Show file tree
Hide file tree
Showing 6 changed files with 480 additions and 287 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,9 @@ public IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> OnActiva
public IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> PropertiesAutowired(IPropertySelector propertySelector, bool allowCircularDependencies)
{
if (allowCircularDependencies)
RegistrationData.ActivatedHandlers.Add((s, e) => AutowiringPropertyInjector.InjectProperties(e.Context, e.Instance, propertySelector));
RegistrationData.ActivatedHandlers.Add((s, e) => AutowiringPropertyInjector.InjectProperties(e.Context, e.Instance, propertySelector, e.Parameters));
else
RegistrationData.ActivatingHandlers.Add((s, e) => AutowiringPropertyInjector.InjectProperties(e.Context, e.Instance, propertySelector));
RegistrationData.ActivatingHandlers.Add((s, e) => AutowiringPropertyInjector.InjectProperties(e.Context, e.Instance, propertySelector, e.Parameters));

return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
// OTHER DEALINGS IN THE SOFTWARE.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Autofac.Util;
Expand All @@ -34,11 +35,27 @@ internal class AutowiringPropertyInjector
{
public const string InstanceTypeNamedParameter = "Autofac.AutowiringPropertyInjector.InstanceType";

public static void InjectProperties(IComponentContext context, object instance, IPropertySelector propertySelector)
public static void InjectProperties(IComponentContext context, object instance, IPropertySelector propertySelector, IEnumerable<Parameter> parameters)
{
if (context == null) throw new ArgumentNullException(nameof(context));
if (instance == null) throw new ArgumentNullException(nameof(instance));
if (propertySelector == null) throw new ArgumentNullException(nameof(propertySelector));
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

if (instance == null)
{
throw new ArgumentNullException(nameof(instance));
}

if (propertySelector == null)
{
throw new ArgumentNullException(nameof(propertySelector));
}

if (parameters == null)
{
throw new ArgumentNullException(nameof(parameters));
}

var instanceType = instance.GetType();

Expand All @@ -49,19 +66,38 @@ public static void InjectProperties(IComponentContext context, object instance,
var propertyType = property.PropertyType;

if (propertyType.GetTypeInfo().IsValueType && !propertyType.GetTypeInfo().IsEnum)
{
continue;
}

if (propertyType.IsArray && propertyType.GetElementType().GetTypeInfo().IsValueType)
{
continue;
}

if (propertyType.IsGenericEnumerableInterfaceType() && propertyType.GetTypeInfo().GenericTypeArguments[0].GetTypeInfo().IsValueType)
{
continue;
}

if (property.GetIndexParameters().Length != 0)
{
continue;
}

if (!propertySelector.InjectProperty(property, instance))
{
continue;
}

var setParameter = property.SetMethod.GetParameters().First();
var valueProvider = (Func<object>)null;
var parameter = parameters.FirstOrDefault(p => p.CanSupplyValue(setParameter, context, out valueProvider));
if (parameter != null)
{
property.SetValue(instance, valueProvider(), null);
continue;
}

object propertyValue;
var propertyService = new TypedService(propertyType);
Expand Down
21 changes: 10 additions & 11 deletions src/Autofac/Core/Activators/Reflection/ReflectionActivator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public object ActivateInstance(IComponentContext context, IEnumerable<Parameter>

var instance = selectedBinding.Instantiate();

InjectProperties(instance, context, parameters);
InjectProperties(instance, context);

return instance;
}
Expand Down Expand Up @@ -152,29 +152,28 @@ private IEnumerable<ConstructorParameterBinding> GetConstructorBindings(
return constructorInfo.Select(ci => new ConstructorParameterBinding(ci, prioritisedParameters, context));
}

private void InjectProperties(object instance, IComponentContext context, IEnumerable<Parameter> parameters)
private void InjectProperties(object instance, IComponentContext context)
{
if (!_configuredProperties.Any() && !parameters.Any())
if (!_configuredProperties.Any())
return;

var actualProps = instance
var actualProperties = instance
.GetType()
.GetRuntimeProperties()
.Where(pi => pi.CanWrite)
.ToList();

var prioritisedProperties = parameters.Concat(_configuredProperties);
foreach (var prop in prioritisedProperties)
foreach (var configuredProperty in _configuredProperties)
{
foreach (var actual in actualProps)
foreach (var actualProperty in actualProperties)
{
var setter = actual.SetMethod;
var setter = actualProperty.SetMethod;
Func<object> vp;
if (setter != null &&
prop.CanSupplyValue(setter.GetParameters().First(), context, out vp))
configuredProperty.CanSupplyValue(setter.GetParameters().First(), context, out vp))
{
actualProps.Remove(actual);
actual.SetValue(instance, vp(), null);
actualProperties.Remove(actualProperty);
actualProperty.SetValue(instance, vp(), null);
break;
}
}
Expand Down
Loading

0 comments on commit 9c605d3

Please sign in to comment.