/// <summary>
        ///     Registers given type according to it's lifetime. Type can be generic or not.
        /// </summary>
        /// <typeparam name="TLifetime">Lifetime of dependency</typeparam>
        /// <param name="builder">Autofac's <see cref="ContainerBuilder" /></param>
        /// <param name="typeToRegister">Type to register Autofac Container</param>
        internal void RegisterApplyingLifetime <TLifetime>(ContainerBuilder builder, Type typeToRegister) where TLifetime : ILifetime
        {
            List <Type> defaultInterfaces = typeToRegister.GetDefaultInterfaces().ToList();

            if (typeToRegister.GetTypeInfo().IsGenericTypeDefinition)
            {
                List <Type> defaultGenerics = defaultInterfaces.Where(t => t.GetTypeInfo().IsGenericType).ToList();
                AddStartableIfPossible(typeToRegister, defaultGenerics);
                OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder, typeToRegister, defaultGenerics.ToArray(), FindLifetime(typeof(TLifetime))));
                builder.RegisterGeneric(typeToRegister)
                .As(defaultGenerics.ToArray())
                .AsSelf()
                .WithPropertyInjection()
                .ApplyLifeStyle(typeof(TLifetime));
            }
            else
            {
                List <Type> defaults = defaultInterfaces.Where(t => !t.GetTypeInfo().IsGenericType).ToList();
                AddStartableIfPossible(typeToRegister, defaults);
                OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder, typeToRegister, defaults.ToArray(), FindLifetime(typeof(TLifetime))));
                builder.RegisterType(typeToRegister)
                .As(defaults.ToArray())
                .AsSelf()
                .WithPropertyInjection()
                .ApplyLifeStyle(typeof(TLifetime));
            }
        }
        /// <summary>
        ///     Registers the type.
        /// </summary>
        /// <param name="serviceType">Type of the service.</param>
        /// <param name="lifetime">The lifetime.</param>
        /// <param name="keepDefault">if set to <c>true</c> [keep default].</param>
        public void RegisterType(
            Type serviceType,
            Lifetime lifetime = Lifetime.Transient,
            bool keepDefault  = false)
        {
            OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder,
                                                                   serviceType,
                                                                   new Type[] { serviceType },
                                                                   lifetime));

            IRegistrationBuilder <object, ConcreteReflectionActivatorData, SingleRegistrationStyle> registration = _containerBuilder
                                                                                                                   .RegisterType(serviceType)
                                                                                                                   .WithPropertyInjection()
                                                                                                                   .AsSelf()
                                                                                                                   .OnActivating(args =>
            {
                object instance = _decoratorService.Decorate(args.Instance, new ResolverContext(new Resolver(args.Context)));
                args.ReplaceInstance(instance);
            });

            registration.ApplyLifeStyle(lifetime);

            if (keepDefault)
            {
                registration.PreserveExistingDefaults();
            }
        }
        /// <summary>
        ///     Registers the specified factory.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <param name="factory">The factory.</param>
        /// <param name="lifetime">The lifetime.</param>
        /// <param name="keepDefault">if set to <c>true</c> [keep default].</param>
        public void Register <TService>(
            Func <IResolverContext, TService> factory,
            Lifetime lifetime = Lifetime.Transient,
            bool keepDefault  = false)
            where TService : class
        {
            OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder,
                                                                   typeof(TService),
                                                                   new Type[] { typeof(TService) },
                                                                   lifetime));

            IRegistrationBuilder <TService, SimpleActivatorData, SingleRegistrationStyle> registration = _containerBuilder
                                                                                                         .Register(cc => factory(new ResolverContext(new Resolver(cc))))
                                                                                                         .WithPropertyInjection()
                                                                                                         .OnActivating(args =>
            {
                TService instance = _decoratorService.Decorate(args.Instance, new ResolverContext(new Resolver(args.Context)));
                args.ReplaceInstance(instance);
            });

            registration.ApplyLifeStyle(lifetime);

            if (keepDefault)
            {
                registration.PreserveExistingDefaults();
            }
        }
        /// <summary>
        ///     Registers if absent.
        /// </summary>
        /// <param name="serviceType">Type of the service.</param>
        /// <param name="implementationType">Type of the implementation.</param>
        /// <param name="lifetime">The lifetime.</param>
        public void RegisterIfAbsent(Type serviceType, Type implementationType, Lifetime lifetime = Lifetime.Transient)
        {
            OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder,
                                                                   implementationType,
                                                                   new Type[] { serviceType },
                                                                   lifetime));

            IRegistrationBuilder <object, ConcreteReflectionActivatorData, SingleRegistrationStyle> registration = _containerBuilder
                                                                                                                   .RegisterType(implementationType)
                                                                                                                   .WithPropertyInjection()
                                                                                                                   .AsSelf()
                                                                                                                   .IfNotRegistered(serviceType);

            _containerBuilder.Register(c => c.Resolve(implementationType))
            .As(serviceType)
            .WithPropertyInjection()
            .OnActivating(args =>
            {
                object instance = _decoratorService.Decorate(args.Instance, new ResolverContext(new Resolver(args.Context)));
                args.ReplaceInstance(instance);
            })
            .IfNotRegistered(serviceType);

            registration.ApplyLifeStyle(lifetime);
        }
        /// <summary>
        ///     Registers the specified lifetime.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <typeparam name="TImplementation">The type of the implementation.</typeparam>
        /// <param name="lifetime">The lifetime.</param>
        /// <param name="keepDefault">if set to <c>true</c> [keep default].</param>
        public void Register <TService, TImplementation>(
            Lifetime lifetime = Lifetime.Transient,
            bool keepDefault  = false)
            where TImplementation : class, TService
            where TService : class
        {
            OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder,
                                                                   typeof(TImplementation),
                                                                   new Type[] { typeof(TService) },
                                                                   lifetime));

            IRegistrationBuilder <TImplementation, ConcreteReflectionActivatorData, SingleRegistrationStyle> registration = _containerBuilder
                                                                                                                            .RegisterType <TImplementation>()
                                                                                                                            .WithPropertyInjection()
                                                                                                                            .AsSelf();

            IRegistrationBuilder <TService, SimpleActivatorData, SingleRegistrationStyle> serviceRegistration = _containerBuilder
                                                                                                                .Register <TService>(c => c.Resolve <TImplementation>())
                                                                                                                .As <TService>()
                                                                                                                .WithPropertyInjection()
                                                                                                                .OnActivating(args =>
            {
                TService instance = _decoratorService.Decorate(args.Instance, new ResolverContext(new Resolver(args.Context)));
                args.ReplaceInstance(instance);
            });

            registration.ApplyLifeStyle(lifetime);

            if (keepDefault)
            {
                serviceRegistration.PreserveExistingDefaults();
            }
        }
        /// <summary>
        ///     Registers the specified instance.
        /// </summary>
        /// <typeparam name="TService1">The type of the service1.</typeparam>
        /// <typeparam name="TService2">The type of the service2.</typeparam>
        /// <typeparam name="TService3"></typeparam>
        /// <param name="instance">The instance.</param>
        /// <param name="lifetime">The lifetime.</param>
        /// <param name="keepDefault">if set to <c>true</c> [keep default].</param>
        public void Register <TService1, TService2, TService3>(
            object instance,
            Lifetime lifetime = Lifetime.Transient,
            bool keepDefault  = false)
            where TService1 : class
            where TService2 : class
            where TService3 : class
        {
            OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder,
                                                                   instance.GetType(),
                                                                   new Type[] { typeof(TService1), typeof(TService2), typeof(TService3) },
                                                                   lifetime));

            IRegistrationBuilder <object, SimpleActivatorData, SingleRegistrationStyle> registration = _containerBuilder
                                                                                                       .RegisterInstance(instance)
                                                                                                       .As <TService1, TService2, TService3>()
                                                                                                       .AsSelf()
                                                                                                       .WithPropertyInjection();

            registration.ApplyLifeStyle(lifetime);

            if (keepDefault)
            {
                registration.PreserveExistingDefaults();
            }
        }
        /// <summary>
        ///     Registers the specified lifetime.
        /// </summary>
        /// <typeparam name="TService1">The type of the service1.</typeparam>
        /// <typeparam name="TService2">The type of the service2.</typeparam>
        /// <typeparam name="TService3"></typeparam>
        /// <typeparam name="TImplementation">The type of the implementation.</typeparam>
        /// <param name="lifetime">The lifetime.</param>
        /// <param name="keepDefault">if set to <c>true</c> [keep default].</param>
        public void Register <TService1, TService2, TService3, TImplementation>(
            Lifetime lifetime = Lifetime.Transient,
            bool keepDefault  = false)
            where TService1 : class
            where TService2 : class
            where TService3 : class
            where TImplementation : class, TService1, TService2, TService3
        {
            OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder,
                                                                   typeof(TImplementation),
                                                                   new Type[] { typeof(TService1), typeof(TService2), typeof(TService3) },
                                                                   lifetime));

            IRegistrationBuilder <TImplementation, ConcreteReflectionActivatorData, SingleRegistrationStyle> registration = _containerBuilder
                                                                                                                            .RegisterType <TImplementation>()
                                                                                                                            .As <TService1, TService2, TService3>()
                                                                                                                            .WithPropertyInjection()
                                                                                                                            .AsSelf();

            registration.ApplyLifeStyle(lifetime);

            if (keepDefault)
            {
                registration.PreserveExistingDefaults();
            }
        }
        /// <summary>
        ///     Registers the generic.
        /// </summary>
        /// <param name="serviceType">Type of the service.</param>
        /// <param name="implementationType">Type of the implementation.</param>
        /// <param name="lifetime">The lifetime.</param>
        /// <param name="keepDefault">if set to <c>true</c> [keep default].</param>
        public void RegisterGeneric(
            Type serviceType,
            Type implementationType,
            Lifetime lifetime = Lifetime.Transient,
            bool keepDefault  = false)
        {
            OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder,
                                                                   implementationType,
                                                                   new Type[] { serviceType },
                                                                   lifetime));

            IRegistrationBuilder <object, ReflectionActivatorData, DynamicRegistrationStyle> registration = _containerBuilder
                                                                                                            .RegisterGeneric(implementationType)
                                                                                                            .As(serviceType)
                                                                                                            .AsSelf()
                                                                                                            .WithPropertyInjection();

            registration.ApplyLifeStyle(lifetime);
        }