public static IServiceCollection AddEfIdentitySecurity(this IServiceCollection services, Action <EfIdentityDbBuilder> builder)
        {
            services.AddSingleton <Action <EfIdentityDbBuilder> >(builder);

            var config = new EfIdentityDbBuilder();

            builder?.Invoke(config);

            if (config.InitialClaims.Any())
            {
                foreach (var initialClaim in config.InitialClaims)
                {
                    foreach (var claim in initialClaim)
                    {
                        Permission.Registered.Add(claim);
                    }
                }
            }

            services.AddDbContext <EfIdentityDbContext>(options =>
                                                        options.UseSqlServer(config.ConnectionString));

            services.AddIdentity <EfIdentityUser, IdentityRole>()
            .AddEntityFrameworkStores <EfIdentityDbContext>()
            .AddDefaultTokenProviders();

            if (config.EnableFirstLastNameClaim)
            {
                services.AddScoped <IUserClaimsPrincipalFactory <EfIdentityUser>, EfIdentityAppClaimsPrincipalFactory>();
            }

            if (config.IdentityOptions != null)
            {
                services.Configure(ConfgureEfIdentityOptions(config.IdentityOptions));
            }

            if (config.CookieAuthenticationOptions != null)
            {
                services.Configure(ConfigureCookieOptions(config.CookieAuthenticationOptions));
            }
            else
            {
                // Set some defaults that I like
                services.ConfigureApplicationCookie(options =>
                {
                    options.Cookie.HttpOnly   = true;
                    options.Cookie.Expiration = TimeSpan.FromDays(100);
                    options.LoginPath         = "/Manager/Login";
                    options.LogoutPath        = "/Manager/Logout";
                });
            }


            return(services.AddSingleton <ISecurity, EfIdentitySecurity>());
        }
        // Default Contructor
        public EfIdentitySecurity(Action <EfIdentityDbBuilder> options, SignInManager <EfIdentityUser> signInManager, UserManager <EfIdentityUser> userManager, ILogger logger)
        {
            _signInManager = signInManager;
            _userManager   = userManager;

            var config = new EfIdentityDbBuilder();

            options?.Invoke(config);

            foreach (var initialClaim in config.InitialClaims)
            {
                foreach (var claim in initialClaim)
                {
                    if (!Permission.Registered.Any(x => x.Equals(claim)))
                    {
                        Permission.Registered.Add(claim);
                    }
                }
            }


            if (!config.Users.Any())
            {
                return;
            }

            if (!config.Users.Any(u => u.IsDefault) || config.Users.Count(u => u.IsDefault) > 1)
            {
                logger.LogError("You must have one Default User!");

                return;
            }

            foreach (var appUser in config.Users)
            {
                List <Claim> claims = new List <Claim>();

                // Setup default user with all claims
                if (appUser.IsDefault)
                {
                    claims.AddRange(Permission.Registered.Select(claim => new Claim(claim, claim)));

                    claims.Clear();
                }


                if (appUser.Claims.Any())
                {
                    claims.AddRange(appUser.Claims.Select(claim => new Claim(claim, claim)));
                }

                var user = _userManager.FindByNameAsync(appUser.UserName).Result;

                if (user != null)
                {
                    continue;
                }

                var created = _userManager.CreateAsync(appUser, appUser.Password).Result.Succeeded;

                if (created)
                {
                    var unused = _userManager.AddClaimsAsync(appUser, claims).Result.Succeeded;
                }
            }
        }