public static Type[] GetInterfaces(TypeInfo implementationType, AutoRegisterAttribute attribute)
        {
            var allInterfaces = implementationType.GetInterfaces();

            if (attribute.ServiceTypes != default && attribute.ServiceTypes.Length > 0)
            {
                ValidateInterfaces(implementationType, attribute);
                return(attribute.ServiceTypes);
            }

            return(allInterfaces.Count() == 0
                ? new[] { implementationType }
                : allInterfaces
                   );
        }
        public static void ValidateInterfaces(TypeInfo implementationType, AutoRegisterAttribute attribute)
        {
            var invalidInterfaces = attribute.ServiceTypes.Where(x => !x.IsAssignableFrom(implementationType));

            if (invalidInterfaces.Count() > 0)
            {
                throw new InvalidOperationException(
                          string.Concat(
                              Environment.NewLine,
                              $"[{implementationType.FullName}] does not implement the following types:",
                              string.Concat(
                                  invalidInterfaces.Select(x => string.Concat(Environment.NewLine, $" - {x.FullName}"))
                                  ),
                              Environment.NewLine
                              ));
            }
        }
        public static void RegisterType(this IServiceCollection services, TypeInfo implementationType, AutoRegisterAttribute attribute)
        {
            var interfaces = GetInterfaces(implementationType, attribute);

            foreach (var serviceType in interfaces)
            {
                if (!attribute.AllowDuplicate)
                {
                    // check for duplicates
                    var usageAttribute = serviceType.GetCustomAttribute <AutoRegisterUsageAttribute>();
                    var allowMultiple  = !(usageAttribute?.AllowMultiple).IsDefault();
                    if (!allowMultiple && services.Any(x => x.ServiceType == serviceType))
                    {
                        throw new InvalidOperationException($"Multiple registrations of type [{serviceType.FullName}] not allowed.");
                    }
                }

                services.Add(new ServiceDescriptor(
                                 serviceType,
                                 implementationType,
                                 attribute.ServiceLifetime
                                 ));
            }
        }