Onion Architecture Identity Framework - asp.net

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?

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

Related

How to implement code first approch without adding any references to web project?

I have added my dbContext in separate class library and added referce of this project to WebAPI project.
Now i want to create a migrations. But to create it i need to add some entity framework references into webapi project too.
this will violate SOP principle of my architechture.
So how can i implement code first approch where my web api is not dependent on DB layer?
It is not necessary for your webapi project to have a direct dependency on EntityFramework.
You can specify your database class library project to be the one which will hold the migrations. E.g:
dotnet ef migrations add MigrationName --project DatabaseClassLibrary --startup-project WebApiProject
The above command will use the WebApiProject as the startup-project as that will most likely (but not always) have the DI setup for creating an instance of your DbContext for your database provider.

How can register profiles in Automapper from different assemblies?

I have an application (NET Core) with many assemblies:
WebAPI (contain view models and consume DTO)
Services (contain DTO and consume Domain entities)
On WebAPI assembly I registered automapper profiles automatically with this line:
services.AddAutoMapper();
With this line I can convert view models to DTO (and backwards)
But I need register profiles located on Services layer to convert DTO to Domain entities (and backwards)
Evidently, Automapper not found this profiles.
What's the best way to register profiles from different assemblies?
I use services.AddAutoMapper(params Assembly[] assemblies).
for example:
services.AddAutoMapper(
typeof(Startup).GetTypeInfo().Assembly,
typeof(Class_In_Other_Assembly).GetTypeInfo().Assembly
);

AspNet Identity ApplicationDbContext on existing database

I have an existing database with my application tables and i am about to build a new version for my application using MVC5. I decided to use AspNet Identity framework as part of my application.
The visual studio template i used while creating the project added a file "IdentityModel.cs" and the class
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
}
So i can access the tables Users, Roles and other AspNet Identity tables using the code like:
var context = new ApplicationDbContext();
context.Users.ToList();
Because of the name Microsoft gave to the class "ApplicationDbContext" (and not: IdentityDbContext for example), i am wondering if that class should be used as "accessor" for all the rest existing tables that not related to AspNet Identity framework or not?
without the so generic name of the class "ApplicationDbContext" i would just use my entity framework project i just added to my solution to access the other tables of my application but i am wondering what is the "best practices". To use the same AspNet Identity ApplicationDbContext accessor (and how?) or to work with two Db accessors, one of the AspNet Identity tables and one for the entity framework i created for the rest of the tables (Db First).
it looks me more logic to use the same dbContext for all the tables, AspNet identity and all the rest of the tables i have in a separate EntityFramework edmx file. How can i use both of them in one dbContext?
AspNet Identity provide something like user manager, it should solve your problem. You don't need to operate on real tables, AspNet Identity should cover table structure and should allow to do high level operations. Your user model should inherit IdentityModel class, then you are able to build your own custom model.
It sounds like part of your issue is that while IdentityFramework is using code-first entity framework you are not using code-first for the rest of your application, instead using the older edmx designer approach. I would not try to mix the two into a single context.
Moreover, because ApplicationDbContext inherits from IdentityDbContext I would leave it alone. The base class implements things like OnModelCreating and ValidateEntity. If you wanted to use your other context for IdentityFramework you'd need to either have your other context inherit from IdentityDbContext--which is bad semantics, because it is not in fact just an identity context--or you'd need to implement these methods manually.
It is easy, however, to point the identity framework context to the same database as your other entity framework items. Just replace "DefaultConnection" in your ApplicationDbContext with whatever the name of the connection string you use for your other stuff is.

Moving ASP.NET Identity IdentityConfig.cs from App_Start folder

I use ASP.NET Identity 2.0 in an ASP.NET MVC5 project that is composed of three layers; Web application (presentation layer), Unit Test (test project) and Class library (data layer). Normally IdentityConfig.cs is located in the App_Start folder of Web application but as I implement a Group-Based Permissions Management as indicated on this page I want to keep all the domain models and IdentityConfig.cs file to the Identity folder in data layer project instead of the web project (presentation layer). Because IdentityConfig.cs needs to access DbContext class that is placed in my data layer project. Is there any problem doing this? On the other hand, could you please explain a little bit what is the App_Start folder?
Here is the ASP.NET Identity folder structure in my project below:
DataLayer (class library)
Concrete EFDbContext
Entities (my entity classes except from ASP.NET Identity entities)
Identity
ApplicationGroupManager
ApplicationGroupStore
GroupStoreBase
IdentityConfig
IdentityModels
PresentationLayer (Web app)
App_Start
Controllers
AccountController
GroupsAdminController
ManageController
RolesAdminController
UsersAdminController
As long as you have asp.net identity, you will have to add reference to it in the presentation layer (web project) and the configuration will be kicked off from there.
If you moved it to the data access layer, then you put a security concern in the data access which is not right.
Normally, I just leave it in the web project and create my own user class and link it to the ApplicationUser class through its Id, but if you must seprate it, then you can put the IdentityConfig in a separate library that handles the cross cutting concerns like security, logging and exception handling as this layer will be working across all layers.
In the data access, you can have a custom user and role stores and put the configuration in the cross cutting library and link all of that in the presentation layer as this is the kickoff point for your web app.
The App_Start is justa normal folder that has the code that will be executed when the application starts, and you can put this code any where else, it is all called by the Global.asax file

How to expose entities to a web project without adding a reference to the project that contains the full EntityFramework model?

I'm facing this problem with EntityFramework 5 (VS 2012). I have the following projects in my solution:
I'm using database first and the designer
Data. Where my entities model and entities are.
Security. Where the business logic for security is.
Web. The web UI
Security has a reference to Data so it can use the model and entities to retrieve data from the database. In Security I have a method the returns a list of MenuOptions (this is an entity in the project Data) to the UI (Web project). In the Web project I then want to iterate the list of MenuOptions to build a menu. The problem is that I don't want to add a reference to Data in my Web project just to be able to have access to the entities. Then, how can I make the entities in Data visible to Web without adding a reference to the full project? (I only want the entities to be accessible to the UI).
Separate the entities in a dll (or project) put your DbContext inherited class and entities mapping configuration in another.
This way you can distribute your entities dll in different projects without sharing DB access items.

Resources