I'm creating application with layered architecture. I have separate
+ 'DataModel' project with only model classes
+ 'BusinessLogic' project that containing my business
+ 'Core' project for run Business from ui
+ 'ViewModel' project
+ 'Web' project with asp.net core application.
My goal was to separate these projects so that Web project knows nothing about DataModel so the Web project should just reference Core and ViewModel. Everything was great until I configured Asp.Net Identity - in order to configure authorization I had to reference DataModel project which I had wanted to avoid. Is it possible to achieve my goal, and (if so) how to do it.
Note:
I'm using this how to separate model library when using asp.net identity for writing my question and i don't find accepted answer as my answer!
When you create a website that uses Identity directly, you must provide it with various Identity "stores": UserStore<TUser>, RoleStore<TRole>, etc. The default and easiest approach is to use Entity Framework Core as the backing for the store(s), and Identity comes with built-in stores to work with EF Core. However, using that requires access to the context, which means you then will need a dependency on your data layer. There is no way around that when using AddEntityFrameworkStores<TContext>.
If you want to keep your data layer abstracted, then you will need to either 1) use a centralized identity provider, such as IdentityServer or 2) create custom stores.
IdentityServer, for example, supports using both EF and Identity as a backing. That does mean it will need a dependency on your data layer, but IdentityServer would be exist in a separate project. Your actual website would handle auth via IdentityServer endpoints, and therefore would have no dependency on your data layer. In fact, it doesn't even know or care that you're using Identity at all at that point.
Creating custom stores will be a bit more difficult, obviously, and unless you provide an true abstraction layer, you'll still ultimately end up with a dependency on your data layer. That might be something like a microservice(s), where the store will actually make HTTP requests to the service to get the objects it needs, instead of making database queries directly. The microservices, then, will hold the data dependency.
One thing you might not be considering in this is that the dependency is there even without a direct reference. For example, if your Core project uses stuff from your DataModel project, and then your Web project uses stuff from your Core project, your web project has an implicit dependency on your DataModel project. If you look at the bin folder after building, for example, you're see a DLL for your DataModel project and even one for EF Core there, despite not explictly using either one in your Web project. In this case, using separate projects helps only to division the logic in perhaps a more succinct and understandable way, but it does not serve to actually abstract any dependencies.
Related
I am following the Microsoft Architecture Guide for creating an ASP.NET Core Web Application.
The guide implements the clean architecture pattern which is pretty straight forward.
If you look at the sample project which is using the clean architecture pattern you will see that there is an Infrastructure/Identity folder that contains the ApplicationUser.cs class.
My issue:
I am using Entity Framework and one of my Business Entities in the ApplicationCore class library needs to contain a list of ApplicationUser. The ApplicationCore library shouldn't be referencing any other projects. It contains all of the Interfaces and Business Entities. How can I keep the ApplicationUser class in my Infrastructure/Identity project and still use it in one of my business entities in the ApplicationCore project without breaking the rules.
I know one solution is to not store the ApplicationUser entity in my Infrastructure project. However, I feel like it should be there since it will always rely on Identity as it implements IdentityUser.
User is an entity and it should be in Core layer.
But you shouldn't use ApplicationUser : IdentityUser in the Core layer because it's tied up to the ASP.NET Identity. The Core layer should not know what technologies are going to implement the domain.
What if tomorrow you want to use another library for user management? That's not the Core layer's concern.
What you can do is to use an interface or base User class in the Core layer and let the Infrastructure layer be worried about the library choice decision.
In Clean Architecture:
Application Core Types
• Entities (business model classes that are persisted) and Aggregates
• Interfaces
• Services
• DTOs
• Specifications
• Exceptions
Infrastructure Types
• EF Core types (DbContext, Migrations)
• Data access implementation types (Repositories)
• Infrastructure-specific services (FileLogger, SmtpNotifier, etc.)
So the ApplicationUser.cs is an entity, it shouls be in Application Core
This is my own problem as well and it seems opinion based somehow. I end up that if you are depending on any package that has a DbContext specified inside it, so you will reference this package in your Core project.
For example, I am using AspCore.Identity and IdentityServer4 and I have many DbContexts for that but let's say two for now:
ConfigurationDbContext and IdentityDbContext and those two contexts control two entities (just for making things easier) Client (The OAuth2 Client) and IdentityUser So now and I already have all of that as Infrastructure but now I want to have my own Core Entities ApplicationUser and ApplcationClient so how can I put those in my Core without letting them inherited their parents so I can query against them, save them or retrieve them from any source.
I don't know exactly the perfect answer for that but I end up putting those entities in the Core and reference the NuGet packages in my core which obviously not follow the clean architecture roles but I couldn't find a better solution than that.
I want to create application with layered architecture. I have separate
Model project with only model classes
Data project responsible for CodeFirst configuration, migrations, etc.,
Service project responsible for business logic, and preserving the data in the database using EF
Dto project with classes used between Web app and service
Web project with asp.net mvc application.
My goal was to separate these projects so that Web project knows nothing about Model and Data - it just consumes Service using Dto classes, so the Web project should just reference Service and Dto. Everything was great until I configured Asp.Net Identity - in order to configure authorization I had to reference Data and Model project which I had wanted to avoid. Is it possible to achieve my goal, and (if so) how to do it.
My second question is: is my desing ok from the separation of concerns point of view?
I might separate all the ASP.NET Identity things into its own project housing both the EF data access and identity models. Think of it as separating the concerns more topically or by the subject matter, rather than by function.
So your web app would then reference Service, Dto, and Identity- and everybody seems to have their own corner of the world.
The goal, imo, is not necessarily to divvy up code by similar functionality, but to eliminate dependencies where none are needed, and to hide (or rather protect) domain knowledge into isolated and authoritative blocks.
Yes, your design is basically solid and generally works well.
Solution Structure:
MyProject - WEBAPI
MyProject.CORE - Class Library
MyProject.Models - Class Library
MyProject.DAL - Class Library
Project References:
MyProject refers to CORE , MODELS
MyProject.CORE refers to DAL,MODELS
MyProject.DAL refers to MODELS
Project Description:
I am trying to create an application with ASP.NET MVC WEB API . so that I can call my API in future mobile applications. My idea behind this layered architecture is WEB API project will hold the front end views of my desktop application and call's the API controller methods on button click events . The event handler methods in API controller will call the Methods in the CORE project where I will implement the business logic.Then the call will be going to DAL where I will call the DB Stored Procs to insert data. As MODELS project is referred to the rest 3 , I will be able to transfer Objects across them.
Here are my questions below.
1) Can I use the same web API project above to create views of my desktop application and call the API controller methods on events like button click?
2) I don't want to expose the implementation of my business logic in CORE application to any other referencing projects. But still i need to follow a layered architecture.
How can i achieve that. Please explain with an example.
3) Is there any best architecture that i can follow with the above requirements.
4) Is this a valid architecture for WEB API and will this work?
Please take the Model example as UserModel {Name, Password, Email}
I assume you meant 'solution', not 'project'. Yes, you can keep mixed types of projects inside one solution, that is Web API for IIS hosting and WPF app that references your core.
This is where interfaces and dependency injection come into play. Create separate interface project to reference and use some dependency binding module like ninject or Microsoft Locator
When following any architecture pattern, remember that patterns were created for developers, not the other way round. What am trying to say, that when you follow any architecture, you - and only you - know what you are trying to achieve. Don't stick to any pattern if you don't know what are you doing and feel free to bend any pattern to your needs. For now keep it simple.
Yes.
I've been working on a Web API solution that's separated on various projects, one of each is the API itself which contains the controllers and Views but all the Business Logic is done in all the other projects (being one of them responsible for all database iteration).
Now I want to apply Authentication using Identity which I wasn't familiar with but was able to understand a lot better thanks to this series of articles and so was able to get it to work on a test solution.
My question here is, how should I organize the different parts of the Identity implementation? Should I...
Make everything directly on the API project?
Create a separate project for all the Identity Implementation except for the controllers?
Use it some other way that you will suggest?
*If you suggest using different project, will I be able to pass the owin context between the projects? how?
We've got a solution with multiple MVC web projects and now adding a client-facing WebApi project.
The API will be a much more scaled-down version of what is available through any of the web projects (though it will likely expand much more over time), so we've come to a decision-making point for how to handle the Models.
What are the best practices for handling Models across different projects?
It's my understanding that a Model in a WebApi project will, for example, use certain property attributes which are meaningless to an MVC web application. And also as an example, the Display attribute is meaningless to the WebApi, but very useful in a View.
This leads me to believe I should be creating a separate set of Models for the WebApi, but also wondering if I'm missing something.
I understand that this could be a question that may lead to a range of opinions, so I'm mostly looking for what are considered industry best practices.
In my solution where i have Web API and MVC web app, I have the below structure
Models : My Entity/Business objects. These are created by Entity framework from my database. These are almost same as my db structure. My Repositary methods (for data access) returns either a single instance /collection of instances of this classes. My data access project is a separate class library which has been referred in other places like my web api project etc..
Web API ViewModels : The Viewmodels (POCO class) specific to the Web API interfaces/action methods.
MVC Web app ViewModels : The Viewmodels (POCO class) specific to my razor views. I had even inherited few of these from the Web API Viewmodels and added additional properties as needed.
I use a separate project for the DTOs, so that the projects that need to consume them do not get into issues with circular references.
I would have the WebApi project map your models into the DTOs. If your MVC project is consuming the WebAPI output, it just needs a reference to the DTO project. This keeps you from having to refer to the WebAPI project directly.