/// <summary>
 /// Adds a <see cref="Configuration.Configure{TOption}"/> callback to the configuration, which will set the option value returned by
 /// the <paramref name="optionValueFactory"/> in the <see cref="ITargetContainer"/> to which the <paramref name="config"/> is applied.
 /// </summary>
 /// <typeparam name="TOption">The type of option to be set</typeparam>
 /// <param name="config">The combined config to which the configuration callback will be added.</param>
 /// <param name="optionValueFactory">A callback which returns value of the option that is to be set when <paramref name="config"/> is applied to an <see cref="ITargetContainer"/>
 /// via its implementation of <see cref="ITargetContainerConfig.Configure(IRootTargetContainer)"/>.  The callback will be passed the target container being configured at that time.</param>
 /// <returns>The <paramref name="config"/> object, for method chaining.</returns>
 public static CombinedTargetContainerConfig ConfigureOption <TOption>(this CombinedTargetContainerConfig config, Func <ITargetContainer, TOption> optionValueFactory)
     where TOption : class
 {
     return(ConfigureOptionInternal(
                config ?? throw new ArgumentNullException(nameof(config)),
                optionValueFactory ?? throw new ArgumentNullException(nameof(optionValueFactory))));
 }
 /// <summary>
 /// Adds a <see cref="Configuration.Configure{TOption}"/> callback to the configuration, which will set the passed <paramref name="optionValue"/>
 /// option for the service type <paramref name="serviceType"/> in the <see cref="ITargetContainer"/> to which the <paramref name="config"/> is later applied.
 /// </summary>
 /// <typeparam name="TOption">The type of option to be set.</typeparam>
 /// <param name="config">The combined config to which the configuration callback will be added.</param>
 /// <param name="serviceType">The service type for which the option is to be set.  Use of this is option-dependent - i.e. some options are read
 /// in a service-specific way and some aren't.  Passing <c>null</c> is equivalent to calling <see cref="ConfigureOption{TOption}(CombinedTargetContainerConfig, TOption)"/>.</param>
 /// <param name="optionValue">The value of the option that is to be set when <paramref name="config"/> is applied to an <see cref="ITargetContainer"/>
 /// via its implementation of <see cref="ITargetContainerConfig.Configure(IRootTargetContainer)"/></param>
 /// <returns>The <paramref name="config"/> object, for method chaining.</returns>
 public static CombinedTargetContainerConfig ConfigureOption <TOption>(this CombinedTargetContainerConfig config, Type serviceType, TOption optionValue)
     where TOption : class
 {
     return(ConfigureOptionInternal(
                config ?? throw new ArgumentNullException(nameof(config)),
                optionValue ?? throw new ArgumentNullException(nameof(optionValue)),
                serviceType));
 }
 internal static CombinedTargetContainerConfig ConfigureOptionInternal <TOption>(CombinedTargetContainerConfig config, Func <ITargetContainer, Type, TOption> optionValueFactory, Type serviceType = null)
     where TOption : class
 {
     config.Add(new Configuration.Configure <TOption>(optionValueFactory, serviceType));
     return(config);
 }