RegisterLazy(this ContainerBuilder builder, Type typeFrom, Type typeTo, string name = null,
                     IRegistrationMutator nonLazyRegistrationMutator = null)
        {
            // There is no way to constraint it on the compilation step.
            if (!typeFrom.IsInterface)
            {
                throw new NotSupportedException("The lazy registration is supported only for interfaces.");
            }

            var registrationName = Guid.NewGuid().ToString();
            IRegistrationBuilder <object, SimpleActivatorData, SingleRegistrationStyle> registration;

            if (typeTo.IsGenericTypeDefinition)
            {
                var nonLazyRegistration = builder.RegisterGeneric(typeTo).Named(registrationName, typeFrom);
                nonLazyRegistrationMutator?.Mutate(nonLazyRegistration);

                registration = builder.RegisterGenericFactory(typeFrom, name,
                                                              (c, t, n, p) => CreateLazyProxy(c, t, registrationName, p));
            }
            else
            {
                var nonLazyRegistration = builder.RegisterType(typeTo).Named(registrationName, typeFrom);
                nonLazyRegistrationMutator?.Mutate(nonLazyRegistration);

                registration = builder.Register(
                    (c, p) => CreateLazyProxy(c.Resolve <IComponentContext>(), typeFrom, registrationName, p));
            }

            return(name == null
                ? registration.As(typeFrom)
                : registration.Named(name, typeFrom));
        }
        RegisterGenericLazy(this ContainerBuilder builder, Type typeFrom, Type typeTo, string name = null,
                            IRegistrationMutator nonLazyRegistrationMutator = null)
        {
            if (!typeFrom.IsInterface)
            {
                throw new NotSupportedException(
                          "The lazy registration is supported only for interfaces.");
            }

            if (!typeTo.IsGenericTypeDefinition)
            {
                throw new ArgumentException(
                          $"{typeFrom} is not an open generic type definition. Use the 'RegisterLazy' method instead.");
            }

            var registrationName    = Guid.NewGuid().ToString();
            var nonLazyRegistration = builder.RegisterGeneric(typeTo).Named(registrationName, typeFrom);

            nonLazyRegistrationMutator?.Mutate(nonLazyRegistration);

            var registration = builder.RegisterGeneric((c, t, p) =>
            {
                var closedTypeFrom = typeFrom.MakeGenericType(t);
                return(CreateLazyProxy(c.Resolve <IComponentContext>(), closedTypeFrom, registrationName, p));
            });

            return(name == null
                ? registration.As(typeFrom)
                : registration.Named(name, typeFrom));
        }