/// <summary>
        /// Inject properties onto an instance, filtered by a property selector.
        /// </summary>
        /// <param name="context">The component context to resolve dependencies from.</param>
        /// <param name="instance">The instance to inject onto.</param>
        /// <param name="propertySelector">The property selector.</param>
        /// <param name="parameters">The set of parameters for the resolve that can be used to satisfy injectable properties.</param>
        public static void InjectProperties(IResolveContext 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 (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            var resolveParameters = parameters as Parameter[] ?? parameters.ToArray();

            var instanceType         = instance.GetType();
            var injectableProperties = InjectableProperties.GetOrAdd(instanceType, type => GetInjectableProperties(type).ToArray());

            for (var index = 0; index < injectableProperties.Length; index++)
            {
                var property = injectableProperties[index];

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

                var setParameter  = property.SetMethod.GetParameters()[0];
                var valueProvider = (Func <object?>?)null;
                var parameter     = resolveParameters.FirstOrDefault(p => p.CanSupplyValue(setParameter, context, out valueProvider));
                if (parameter != null)
                {
                    var setter = PropertySetters.GetOrAdd(property, MakeFastPropertySetter);
                    setter(instance, valueProvider !());
                    continue;
                }

                var propertyService       = new TypedService(property.PropertyType);
                var instanceTypeParameter = new NamedParameter(InstanceTypeNamedParameter, instanceType);
                if (context.TryResolveService(propertyService, new Parameter[] { instanceTypeParameter }, out var propertyValue))
                {
                    var setter = PropertySetters.GetOrAdd(property, MakeFastPropertySetter);
                    setter(instance, propertyValue);
                }
            }
        }