Onion Architecture Identity Framework
Asked Answered
C

1

7

I am following Onion Architecture. And in that I am using ASP.NET Identity Framework.

Here is my Project Structure:

1-Core
     - Domain Classes //It contains my T4 template classes
          -- AppUser  //It is Identity User.  
     - Repository Interfaces
     - Service Interfaces
2-Infrastructure
     - Data //It contains my edmx file, I am using Db First approach.
     - Dependency Injection
     - Repository Interfaces Implementation
     - Service Interfaces Implementation
3-WebApi
     - Web Api Project
4-WebClient
     - My AngularJs App
5-Test
     - Test Project

I have copied the scripts of the ASP.NET Identity tables and executed on my SQL Server. Which created Identity Tables for me.

In my Infrastructure.Data project, I created an Edmx File and inserted Identity tables in it. Then I moved my T4 template to Core.Domain, here I created Partial Class for my AppUser and other Identity tables.

// This make my Core.Domain project dependent on `Microsoft.AspNet.Identity`
// Which is a violation. 
public partial class AppUser : IdentityUser 
{
    //My Custom Properties
}

Now I have confusion about my AppUser Class which is in Core. According to the Onion Architecture standards, This whole layer should not a be dependent on any external library. But here I am using 'Microsoft.AspNet.Identity' in order to make my user as Identity User. Is there any solution for that?

Catabolite answered 9/6, 2015 at 10:12 Comment(5)
AppUser doesn't belong in Core.Meekins
@ErikFunkenbusch Then where does it belong? Can you elaborate a little bit?Catabolite
If it has dependencies on anything besides a core framework library, then it doesn't belong in core. ASP.NET and Identity and EF are not core framework libraries.Meekins
@ErikFunkenbusch I know, That's why I put the question on SO. I am looking for the solution.Catabolite
I suggest you define an IApplicationUser object in core that has no dependencies, and then implement this in your presentation layersMeekins
H
2

The problem with AppUser deriving from IdentityUser is now your core project is dependant on a framework which it designed for Asp.Net, there your core project can become biased. You are correct that the core (i.e. central) project should be platform independent.

If you want to use IdentityUser you could define a User entity within your WebClient/WebApi projects which inherit from IdentityUser and keep them within these presentation layers, away from the core.

To convey your presentation user entity to the core you can manually map the properties to your core AppUser or use a mapping tool like AutoMapper

Edit

Included Diagram:

1-Core
    - Domain Classes 
        -- AppUser    
    - Repository Interfaces
    - Service Interfaces
2-Infrastructure
    - Data //It contains my edmx file, I am using Db First approach.
    - Dependency Injection
    - Repository Interfaces Implementation
    - Service Interfaces Implementation
3-WebApi
    - Web Api Project
        - Models
            ApiUser : *(Inherits Api Identity framework)*
4-WebClient
    - My AngularJs App
        - Models
            WebUser : *(Inherits IdentityUser)*
5-Test
    - Test Project
Harwin answered 9/6, 2015 at 11:22 Comment(7)
But then I have to maintain two different classes of model whenever I change something in the user table.Catabolite
Depends on the change... What if the change to the user table is only relevant to user object within the WebClient project? If you are trying to have a single class to represent multiple application platforms this could be difficult. You could end up with a model which contains multiple responsibilities (see SRP pattern). Also, ask yourself how often you are going to change the user aspect of your application: if it is very often maybe you should consider further abstractions to reduce this. For example having a Person entity which the User can extend from.Harwin
It means I have to maintain two different Context as well? One DbContext and one IdentityContext.Catabolite
I am talking about Infrastructure.Data.Catabolite
You could put your persistance logic either in the Infrustructure project under Data or introduce a new project, called "Persistance" or similar. You should keep all EF references and logic within these scopes. You then use your contexts here, hidden away from the core. Your core should not know what EF contexts are, it is not the cores concern.Harwin
@AndyClark Can you please enlighten me with WebUser : (Inherits IdentityUser). I understand ApiUser implementing Identity but In AngularJs how can WebUser inherit from IdentityUser?Catabolite
If your web project only contains angularjs/html you probably wont need it there. I only included it in both to demonstrate where you could use it muliple times for different reasons. If your API will handle the AppUser interaction through an "ApiUser" object then you can safely assume WebUser is not required.Harwin

© 2022 - 2024 — McMap. All rights reserved.