public IEnumerable<SelectedProperty> SelectProperties(IBuilderContext context, IPolicyList resolverPolicyDestination) { var target = context.BuildKey.Type; var typeTracker = context.Policies.Get<TypeTrackerPolicy>(context.BuildKey).TypeTracker; // Unity includes a policy used when explicitly configuring injection. Here we borrow // it to specify the properties we want to fill. Normally the user specifies specific // properties and the policies for filling them, here we do it automatically. var policy = new SpecifiedPropertiesSelectorPolicy(); foreach (var property in target.GetProperties()) { // Ignore indexed properties if(property.GetIndexParameters().Length > 0) continue; // Ignore read only properties if(!property.CanWrite) continue; // Ignore properties we can't fill anyway if(!typeTracker.HasDependency(property.PropertyType)) continue; // Ignore properties that would create obvious circular dependencies. It is still // possible to create one if you have multiple classes referring to each other though. if (property.PropertyType == property.DeclaringType || property.DeclaringType.IsAssignableFrom(property.PropertyType)) continue; policy.AddPropertyAndValue(property, new TypeToBeResolved( property.PropertyType, GetResolver(property))); } return policy.SelectProperties(context, resolverPolicyDestination); }
private static SpecifiedPropertiesSelectorPolicy GetSelectorPolicy(IPolicyList policies, Type typeToInject, string name) { NamedTypeBuildKey key = new NamedTypeBuildKey(typeToInject, name); IPropertySelectorPolicy selector = policies.GetNoDefault<IPropertySelectorPolicy>(key, false); if (selector == null || !(selector is SpecifiedPropertiesSelectorPolicy)) { selector = new SpecifiedPropertiesSelectorPolicy(); policies.Set<IPropertySelectorPolicy>(selector, key); } return (SpecifiedPropertiesSelectorPolicy)selector; }