Search code examples
f#asp.net-core-identity

Custom Identity Usermanager from C# to F#


We currently have the following code

public class ApplicationUserManager : UserManager<ApplicationUser>
{
    public ApplicationUserManager(IUserStore<ApplicationUser> store, IOptions<IdentityOptions> optionsAccessor, IPasswordHasher<ApplicationUser> passwordHasher, IEnumerable<IUserValidator<ApplicationUser>> userValidators, IEnumerable<IPasswordValidator<ApplicationUser>> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<ApplicationUser>> logger) : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger)
    {
    }

    public override async Task<IdentityResult> ResetPasswordAsync(ApplicationUser user, string token, string newPassword)
    {
        var result = await base.ResetPasswordAsync(user, token, newPassword);
        if (result.Succeeded)
        {
            user.ChangePasswordDate = DateTime.Now.AddYears(1);
            user.ChangePassword = false;
            await base.UpdateAsync(user);
        }
        return result;
    }
}

How would i convert this to f#?

Any help would be appreciated

Greetings,

Glenn


Solution

  • If you're using F# 6, you can use the new task builder, like this:

    open Microsoft.AspNetCore.Identity
    
    type ApplicationUserManager(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger) =
        inherit UserManager<ApplicationUser>(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger)
    
        member private _.BaseResetPasswordAsync(user, token, newPassword) =
            base.ResetPasswordAsync(user, token, newPassword)
    
        override this.ResetPasswordAsync(user, token, newPassword) =
            task {
                let! result = this.BaseResetPasswordAsync(user, token, newPassword)
                if result.Succeeded then
                    user.ChangePasswordDate <- DateTime.Now.AddYears(1)
                    user.ChangePassword <- false
                    let! _result = this.UpdateAsync(user)
                    ignore _result
                return result;
            }
    

    The private Base method is required because you can't refer directly to base within a computation expression.

    Note that you're ignoring the result of UpdateAsync in your C# code. I've done the same thing here, but I don't know if it's wise.