What is the difference between using user.Email vs await _userManager.GetEmailAsync(user)?
I mean, once I have the user instance itself, what is the use of the _userManager's GetEmailAsync() method which takes exactly that user instance as parameter? I can access the user's email via its property.
I examined the source and I do understand that there is an abstraction layer of using IUserEmailStore but its default implementation is just returning the Email property...
I also do understand, that may exist other implementations, of IUserEmailStore but this case the question will arise: are the user.Email property and _userManager.GetEmailAsync(user) consistent to each other, or are not?
If not, that is a problem, if yes, then we are returned to the original question: what is the use case of using _userManager.GetEmailAsync(user)?
(the same question goes to UserName, PhoneNumber, etc properties)
CodePudding user response:
What is the difference between using
user.Emailvsawait UserManager.GetEmailAsync(user)?
user.Emailonly works if yourTUseractually has anEmailproperty in the first place.- Fun-fact: ASP.NET-Core-Identity does not actually require whatever
classyou're using for yourTUserto have aString Emailproperty.- i.e. what you're presupposing (that users have e-mail addresses) is not actually guaranteed in, nor required by, ASP.NET-Core-Identity.
- ASP.NET-Core-Identity's only constraint on
TUserisTUser : class, so you could even useStringorIDictionaryfor yourTUserif you're brave enough.- While ASP.NET-Core-Identity does have a
String Email { get; }property defined only onclass Microsoft.AspNetCore.Identity.IdentityUser<TKey>, but you are not obligated to use this class at all: it's just a prewritten implemention that covers the most common use-cases and (probably) saves most people time by having them subclass it.
- While ASP.NET-Core-Identity does have a
- Fun-fact: ASP.NET-Core-Identity does not actually require whatever
But there are also other scenarios to consider:
- ...such as domain-model design where users have multiple e-mail addresses per user, in which case having a single scalar
String Email { get; }property simply won't work... though neither wouldGetEmailAsynceither, but that's another part of ASP.NET-Core-Identity's design that you missed: you can implementIUserStore<TUser>and not implementIUserEmailStore<TUser>, so there wouldn't be either anEmailproperty nor aGetEmailAsyncmethod. (Just make sure you don't subclassclass UserStoreBase) and instead build your store implementation from scratch.- In this hypothetical case, where no types implement
IUserEmailStore<TUser>, there wouldn't be any methods anywhere in your codebase that would have to throwNotImplementedExceptionorNotSupportedException. And that's a good thing: a common mantra when designing a domain-model is to "make invalid things impossible" (that's my corruption of the original maxim "make invalid state unrepresentable").
- In this hypothetical case, where no types implement
- ...such as domain-model design where users have multiple e-mail addresses per user, in which case having a single scalar
Another scenario is some (atypical, I'll admit) system where Users do have an email address, but it's not stored or represented by the in-memory
Userobject, in which case you would have to use a custom implementation ofGetEmailAsyncto get a user's email address every time.- I imagine this might be a possibility when using a back-end user-store with extremely fine-grained security (e.g. some paranoid Active Directory setup where the current
Thread's NT security token is used to attest permission to request e-mail addresses from the directory... but that idea is just speculation and I hope no-one ever actually has to support that, at least not without good blood-pressure medication on-hand).
- I imagine this might be a possibility when using a back-end user-store with extremely fine-grained security (e.g. some paranoid Active Directory setup where the current
In conclusion: Not every system has user e-mail addresses, and ASP.NET Core Identity doesn't require them to expose them - and the (admittingly very complicated) design of ASP.NET Core Identity reflects that.
