Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the purpose of UserManager methods like GetPhoneNumberAsync(IdentityUser user), when the desired properties can be pulled from user object?

I'm trying to understand some of the logic behind the ASP.Net Core Identity UI views.

For example, Account\Manage\Index.cshtml.cs includes the following code:

    private async Task LoadAsync(IdentityUser user)
    {
        var userName = await _userManager.GetUserNameAsync(user);
        var phoneNumber = await _userManager.GetPhoneNumberAsync(user);

        Username = userName;

        Input = new InputModel
        {
            PhoneNumber = phoneNumber
        };
    }

Why is the call to _userManager.GetPhoneNumberAsync(user) made, when we can just pull the PhoneNumber property directly off of the user object?

like image 579
Pancake Avatar asked Mar 03 '23 23:03

Pancake


1 Answers

The fact that the default identity setup consists of a entity that is mapped to a database by Entity Framework is an implementation detail that the user manager does not care about. The user manager is actually implemented in a way that it acts mostly as a facade to various individual components that provide functionality like password validation, hashing, etc.

One of those components is the IUserStore<> which is responsible of actually persisting the identity object in some way.

The default implementation is the UserStore<> in the Microsoft.AspNetCore.Identity.EntityFrameworkCore. Note that the namespace includes EntityFrameworkCore so this is the only thing that is actually specific to how the user object is persisted: Using EF Core.

The general IUserStore<> is only responsible for actually storing and storing the user object. However, it is possible for a store implementation to enable additional features, like phone number supports, by various feature flag interfaces. For example IUserClaimStore<>, IUserEmailStore<>, IUserPhoneNumberStore<>, or IUserTwoFactorStore<>. These are then what all the high-level methods on the user manager will go through to determine (a) support for that functionality, and (b) how to get those values.

So this design of the user manager seems complicated if you only think about users as entities that are persisted by your ORM but it actually allows to swap out the whole architecture behind the user manager without affecting it on the front. That is why the default Identity UI uses those methods, to not have to rely on the implementation detail that the user is an entity, and instead go through the user manager to retrieve the values it needs.

Does this matter to your application? Probably not. If you decide to use the default user store with the IdentityUser, then you can just access the properties directly. It’s unlikely for applications to completely switch that all out later, and you will probably have to do other changes then as well. So for your application code, you can just access the entity’s properties directly.

like image 74
poke Avatar answered Mar 05 '23 14:03

poke