public static PasswordlessLoginBuilder AddCustomEmailTemplates(this PasswordlessLoginBuilder builder, string templateOverrideFolder, CultureInfo[] supportedCultures = null)
        {
            if (!Directory.Exists(templateOverrideFolder ?? throw new ArgumentNullException(nameof(templateOverrideFolder))))
            {
                throw new Exception($"Custom email template folder '{templateOverrideFolder}' does not exist.");
            }

            IFileProvider templateFileProvider = new CompositeFileProvider(
                new PhysicalFileProvider(templateOverrideFolder),
                TemplateFileProvider
                );


            return(builder.AddEmailTemplates(templateFileProvider, supportedCultures, true));
        }
        public static PasswordlessLoginBuilder AddPasswordlessLogin(this PasswordlessLoginBuilder builder)
        {
            var services = builder.Services;

            services.AddSingleton(builder.Options);

            services.TryAddTransient <IEventNotificationService, DefaultEventNotificationService>();
            services.TryAddTransient <IOneTimeCodeStore, DbOneTimeCodeStore>();
            services.TryAddTransient <IOneTimeCodeService, OneTimeCodeService>();
            services.TryAddTransient <IUserStore, DbUserStore>();
            services.TryAddTransient <ITrustedBrowserStore, DbTrustedBrowserStore>();
            services.TryAddTransient <IMessageService, MessageService>();
            services.TryAddTransient <ISignInService, PasswordlessSignInService>();
            services.TryAddTransient <IApplicationService, NonexistantApplicationService>();

            services.TryAddSingleton <IPasswordHashService>(
                new AspNetIdentityPasswordHashService(PasswordlessLoginConstants.Security.DefaultPbkdf2Iterations));
            services.TryAddTransient <IPasswordHashStore, DbPasswordHashStore>();
            services.TryAddTransient <IPasswordService, DefaultPasswordService>();
            services.TryAddTransient <IApplicationLocalizer, DefaultLocalizer>();

            services.TryAddTransient <AuthenticateOrchestrator>();
            services.TryAddTransient <UserOrchestrator>();

            services.TryAddSingleton <IHttpContextAccessor, HttpContextAccessor>();

            // IUrlHelper
            services.TryAddSingleton <IActionContextAccessor, ActionContextAccessor>();
            services.TryAddScoped <IUrlHelper>(x =>
            {
                var actionContext = x.GetRequiredService <IActionContextAccessor>().ActionContext;
                var factory       = x.GetRequiredService <IUrlHelperFactory>();
                return(factory.GetUrlHelper(actionContext));
            });

            services.TryAddScoped <IUrlService, PasswordlessUrlService>();

            builder.AddEmailTemplates(TemplateFileProvider);
            builder.Services.TryAddTransient <IEmailTemplateService, EmailTemplateService>();

            return(builder);
        }