Skip to content
This repository has been archived by the owner on Dec 20, 2018. It is now read-only.

Is it possible to use ASPNET Core Identity and still have completely persistence agnostic controllers? #1236

Closed
BenjaminCharlton opened this issue May 20, 2017 · 10 comments

Comments

@BenjaminCharlton
Copy link

BenjaminCharlton commented May 20, 2017

Hello again!

I have been struggling with this problem for weeks now. Maybe somebody here can tell me the proper way to do it (or confirm that it's impossible so I can give up!).

I would like to use ASP .NET Identity and Entity Framework but I would like my controllers to be completely ignorant of persistence frameworks.

As the IdentityUser class (and IdentityRole etc.) reside inside Microsoft.AspNetCore.Identity.EntityFrameworkCore, I can't reference those classes, or any classes derived from them in my controllers because then they would be tied to Entity Framework, but I still want to use them via DI. When I realized this, I thought I had three options:

  1. Create an IUser interface in my Core assembly, and pass this interface in my controllers' constructors, like this:
    public AccountController(
            UserManager<IUser> userManager,
            SignInManager<IUser> signInManager)

Having a concrete implementation of ApplicationUser (which implements my IUser interface and inherits from your IdentityUser class) in a separate Persistence project I was hoping that I could get an instance of ApplicationUser with Dependency Injection without referring it at all in my controllers.

Alas, I was wrong. Mapping IUser to a concrete implementation of IdentityUser in my Startup.cs file is not enough; you also have to map UserManager<IUser> to UserManager<ApplicationUser> (and likewise with SignInManager) and that produces a compilation error. Back to the drawing board.

  1. Create a generic solution passing the type TUser (and TUserKey to be thorough) to every controller. This will compile, and allows the ignorance of the precise concrete implementation to be maintained right up to the top level in the StartUp.cs file. It was there that I was going to hook it all up. That idea produced very verbose, ugly domain classes such as:

    Exam<TUser, TUserKey> where TUser : IUser, TUserKey : IEquatable<TUserKey>

Not to mention that creating controllers from generic classes is a problem all on its own, with complex implementations of custom controller factories. I abandoned this idea for those reasons.

  1. Finally, the only thing left I can think of is maybe to copy and paste the code of the IdentityUser, IdentityRole etc. classes from the Microsoft.AspNetCore.Identity.EntityFrameworkCore library and place them in my domain models project. So far as I can see there is not really anything EF-specific in those classes so my controllers and my core would still be persistence ignorant. But still I am reluctant to do this because it seems hacky and I worry that, like my previous attempts, this too will bring complications that I haven't yet foreseen.

While struggling through all this I couldn't help but wonder why it was so difficult. After all, separation of concerns is a pretty hot topic. IdentityUser, IdentityRole etc. are inside the EntityFrameworkCore namespace despite there being little or no EF-specific code in them.

Anyway, can anybody put me out of my misery please? Is it actually possible to have 100% persistent ignorant controllers that still hook-up seamlessly to Identity Entity Framework using DI in the startup class?

If so, how please? If not, why not, please?

@HaoK
Copy link
Member

HaoK commented May 21, 2017

You should be able to do this in 2.0 via this PR #1188, prior to this , to use the any of the EF Core stores you had to derive from the pocos that lived in the EF Core package.

@HaoK
Copy link
Member

HaoK commented May 21, 2017

Dupe of #883

@HaoK HaoK closed this as completed May 21, 2017
@HaoK HaoK added the duplicate label May 21, 2017
@BenjaminCharlton
Copy link
Author

Hi @HaoK ! Thanks for your response. I look at your page #1188 and I think it would really help me out to have it that way. Great job!

I am trying to use your fix in my project but I can't find the Microsoft.Extensions namespace that you mentioned. This is a screenshot of the namespaces I see on your page. Can you guide me what I need to do to use your improvements in my project please? I would really appreciate it.

Many thanks

Benjamin

capture

@HaoK
Copy link
Member

HaoK commented May 23, 2017

It'll be in preview 2, the changes haven't been pushed publicly yet, but they will this week

@BenjaminCharlton
Copy link
Author

Thanks @HaoK! I shall look forward to that.
Best regards
Benjamin

@BenjaminCharlton
Copy link
Author

Hi again @HaoK,

I have migrated my solution to ASPNET Core 2.0 and installed your recently updated pre-release of ASPNET Core Identity.

I can't find the IdentityUser in the Microsoft.Extensions.Identity.Stores namespace, and I can't find a Nuget package for Microsoft.Extensions.Identity.Stores even if I search pre-release packages.

Please could you point me in the right direction?

Many thanks!
Benjamin

@HaoK
Copy link
Member

HaoK commented Jun 3, 2017

It will be in preview 2 which hasn't been released yet, but they are in the dev branch, so if you wanted to use the nightly builds you could, see https://github.com/aspnet/Home specifically the latest dev build section

@BenjaminCharlton
Copy link
Author

Hello again HaoK! I was happy to see that IdentityUser had been moved out of EntityFramework and into Microsoft.AspNetCore.Identity in version 2.0.0 Preview2-Final. That was very helpful.

But I just upgraded from the preview version to the final release of ASPNETCore 2.1 and it's not there anymore. Where does IdentityUser live now please?

In my AuthorizationController.cs class I'm now getting the compilation error below:

Error CS7069 Reference to type 'IdentityUser<,,,,>' claims it is defined in 'Microsoft.Extensions.Identity.Stores', but it could not be found ....\Controllers\AuthorizationController.cs

@HaoK
Copy link
Member

HaoK commented Aug 21, 2018

Its in a new stores assembly as of 2.0, https://github.com/aspnet/Identity/blob/master/src/Stores/Microsoft.Extensions.Identity.Stores.csproj

Make sure you have a reference to this package

@BenjaminCharlton
Copy link
Author

Thank you very much! It's lucky you reply as fast as you release new versions! :-)

After updating all the references to Nuget packages in each of my projects I had to replace references to IdentityUser<TKey, TLogin, TRole, TClaim> (now obsolete, it seems) with references to the simpler IdentityUser<TKey> class.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants