/// <summary>
        /// Register a service using the provided <paramref name="factory"/> and specify a base type of the returned object instance
        /// which the <paramref name="factory"/> created or one of the interfaces it implements as the retrieval key.
        /// </summary>
        /// <typeparam name="TContract">The base type from which the returned object instance derives, or one of the interface it implements.</typeparam>
        /// <typeparam name="TConcrete">The concrete type of the returned object instance.</typeparam>
        /// <param name="registrar">The registrar.</param>
        /// <param name="factory">The factory used to create a object instance.</param>
        /// <returns>
        /// The method configurator
        /// </returns>
        public static ICommonConfigurationApi Register <TContract, TConcrete>(this IObjectRegistrar registrar, Func <IResolutionContext, TConcrete> factory)
            where TConcrete : TContract
        {
            Requires.NotNull(registrar, "registrar");
            Requires.NotNull(factory, "factory");
            Requires.IsPublicAccessibleType(typeof(TContract), "TContract");
            Requires.IsPublicAccessibleType(typeof(TConcrete), "TConcrete");

            var configurator = new FuncConfigurationApi <TContract>();
            Func <IResolutionContext, TContract> newFunc = (context) => factory.Invoke(context);

            configurator.CreateRegistrationProvider(registrar.Kernel, newFunc, typeof(TConcrete));
            var provider = configurator.GetRegistrationProvider();

            registrar.Register(provider);
            return(configurator);
        }
        static ITypeConfigurationApi RegisterWithType(this IObjectRegistrar registrar, Type contractType, Type concreteType)
        {
            Requires.NotNull(contractType, "contractType");
            Requires.NotNull(concreteType, "concreteType");
            Requires.IsPublicAccessibleType(contractType, "contractType");
            Requires.IsPublicAccessibleType(concreteType, "concreteType");

            Requires.IsNotOpenGenericType(concreteType, "concreteType");
            Requires.IsConcreteType(concreteType, "concreteType");
            Requires.IsAutowirableType(contractType, "contractType");
            Requires.IsAssignableFrom(contractType, concreteType);

            var configurator = new ReflectionOrEmitConfigurationApi();

            configurator.CreateRegistrationProvider(registrar.Kernel, contractType, concreteType);
            var provider = configurator.GetRegistrationProvider();

            registrar.Register(provider);
            return(configurator);
        }