I have .net core api project with following folders:
Models contains the database table classes and dbcontext
Services contain logic to send email, and business logic (example calculate student grade based on marks)
Controller contains the controllers with respective actions (api endpoints). The dbcontext is injected into the controller and the endpoints contain the LINQ queries (example: _ctx.Students.Where.....)
I want to organize this into layered architecture.
UI layer will contain the api project (controllers) and reference the business layer dll.
Business layer will contain the send email logic, and business logic (grading based on marks). I think this must reference the data layer to be able to fetch data.
Data layer will contain the table classes and db context.
Where do I place my entity framework queries which were previously in the controller action method?
I usually recommend people to use the repository pattern to structure Asp.net application in a monolithic fashion. At a high level, there are usually three-layer
Repository/Data Layer
Service/Business layer
Controller/API (Web Project)
In Repository Layer, we define all our models and database call(Your Entity framework will be here).
In the Service Layer, We perform all the business logic.
And in the web project, we define all the API endpoints and other client-side interaction services.
The followings are some of the articles related to the Repository pattern:
https://www.linkedin.com/pulse/repository-pattern-c-pawan-verma/
https://medium.com/net-core/repository-pattern-implementation-in-asp-net-core-21e01c6664d7
https://codewithmukesh.com/blog/repository-pattern-in-aspnet-core/
Some articles, here use the same project to define all the layers but you can simply separate all layers into a separate project (class library).
I usually layer my application like this:
APIs - EndPoints
Application Layer - All glueing code, mapping, orchestra code, utilities, and other application-level code comes here
Domain Layer - Purely contains domains, sub-domains, validations, interfaces for repositories and unit of work, and commands.
Data Layer - This layer contains the implementation of all the repositories and unit of work interfaces. And this is the layer where I keep all my queries and database-specific code.
Related
I have an existing database which I am using in a CRM project developed in asp.net MVC project. Now our company has decided to develop HRM system also using the same database. The business requirement is to use Clean Architecture with .net core 3.1 as a backend for HRM. The project is structured in a way that it has four layers.
Presentation Layer: Contains Controllers and Web API endpoints.
Application Layer: Contains Application wise logic and types.
Business Layer: Contains Enterprise wise logic and types.
Infrastructure Layer: Contains all the cross-cutting concerns.
Presentation Layer and Infrastructure Layer are dependent on Application Layer and Application Layer is dependent on Business Layer. The business layer is independent of every other layer.
I have to scaffold the DB Context and Entities from the existing database so that Entities will go to the business layer and DB Context will go to the Infrastructure layer (Note: Infrastructure is not dependent on Business). How can I do that? Is there anyone who has done this earlier? Any help would be greatly appreciated.
I am creating an application that has those three different projects:
ApiService (Web API 2)
BusinessLogic (Class Library)
DataAccess (Class Library)
ApiService has a reference to BusinessLogic
BusinessLogic has a reference to DataAccess
DataAccess uses Entity Framework with code first approach so it contains the models for the database tables.
My question is, what is the best approach or best practice regarding the models for Business and Service Projects?
I have read that Service project should not be using the models of the DataAccess project, so where should I create that models, in Service or in Business?
Thanks in advance.
Separate BL(Business logic)/Presentation layer models from DAL(Data access layer) models always.
Add one more layer between them which will do the mapping, use Automapper or somethogn custom. So when you are passing data to DAL models will be mapped to entity models, and when BL is getting the data from DALsame thing, map entity models to BL models,
Why?
The way how you are persisting your data in your database may be rather different from how you are going to present it to the user. The data may have to be obtained from several entities, joined by relationships, constructed at run time again by joining from other tables, etc. How you are going to present it to a user may be simplified and different than it is persisted, so you can hide that complexity which is needed for the database.
I don't know if this is best practice, but I have made many projects that contain a lot of shared logic and functionality between windows services, Web APIs, etc. They have all followed something similar to this:
Wrapper - Contains interaces, models, and code to make calling the WebAPI from another .NET project easier. Has no references to the other projects at all
Core - Contains all the meaty business logic. Service layer, data access layer, helper classes, etc. References Wrapper and anything else needed to function
WebAPI - Contains only code necessary for creating a WebAPI around the service layer functions in Core References Wrapper for models/interfaces, and Core for business logic
Other projects that use Core would be similar to the WebAPI one. Examples would be a console app for scheduled tasks, Windows service for continual data processing, etc.
This results in what I've seen some people refer to as a "mega solution" or similar, but so long as you're keeping your code to one domain you're not creating a mess.
Setup
.NET, C#, WebAPI, Entity Framework using code-first migration
Summary
I am designing a .NET solution using the repository pattern. The repository sits at the bottom of my stack and currently contains my domain models. I have layers on top of the repository (e.g. BLL) and finally I have an API layer on the top of the stack which contains my RESTful API endpoints.
Here is a simplified pseudo-diagram of the current solution stack:
-API
-BLL
-REPOSITORY
Problem
In the API layer, I would like to use .NET's ModelState validation inside each of the controller's endpoints. Problem is, this requires that the API layer have a reference to (ergo knowledge of) the Repository layer. Wouldn't this be a leaky abstraction?
It seems like the use of Data Transfer Objects would be the solution, but this almost seems silly since they would be essentially identical to the Domain Models in the Repository. That doesn't allow for much abstraction.
An alternative?
I am kicking around the idea of adding a separate project to contain the Domain Models, and then allow the API, BLL, and Repository to all reference that project. Any reason this shouldn't be done?
The only downside I see here is that now three of the projects in my solution will need access to the database:
API (because I have set up OWIN authentication in the API)
Repository
DomainModels (because I am using code-first migration)
Any help is appreciated.
The repository sits at the bottom of my stack and currently contains my domain models
That's your problem, the repository uses domain entities, but it doesn't contain them. The repo is part of the persistence, your domain model should be part of the Domain layer. The repo interface is part of the Domain too.
ALso, you domain model should be different (as a concept) than you persistence model i.e the pocos you're using with EF to do CRUD stuff. The domain objects are modelled according to the business view, the persistence pocos are designed with db usage (store/easily queryable) in mind.
The domain layer should be at the core, persistence and application services should use it i.e depend on it. You can take a look at the onion architecture or business components/ vertical slices (which is a more advanced approach IMO)
I have a three layer architecture program. The questions are:
1. Data access is the layer of EF?
2. If i want to use an entity generated by EF from Presentation Layer, then i reference the Data Access, but this violates the principles of 3 layered architecture.
Microsoft Spain released a pretty good documentation, guide and sample application for N-layered applications on codeplex, you can look it up here:
http://microsoftnlayerapp.codeplex.com/
You will find many directions and helpful implementation patterns there.
hth.
Yes EF would be your Data Access Layer.
With EF you can use T4 templates with POCO support, you can then extract these POCO into a seperate dll and this will be reference from all of your layers.
What type of application are you building? If you are building an ASP.NET MVC 3 application, you can have your View be the presentation layer, your Model is your data access (which can use EF) and the controller and / or Action Filters can contain your business logic and in this scenario you will be using your EF Model in the presentation layer but still satisfy the separation of concerns principle.
EF does two things: -
1) Generates an domain model for you (optional, but commonly used)
2) Gives you the ability to query / modify your database via that domain model.
This can give the appearance of blurring the lines between domain model and data access but the two are indeed separate.
As long as you're not doing stuff like creating object contexts and writing queries directly in your presentation tierthen IMHO you are not breaking abstraction - the only thing you are "breakin"g is the fact that you will need to reference System.Data.Objects (or whatever the EF dll is) in your presentation project(s) (which is just a physical artifact) unless you go down the route suggested by Jethro to generate your domain model into a separate project.
For the three tier architecture. I would consider doing Abstraction using Domain Model and Data model pattern rather then doing direct EF from Presentation Layer.
So the idea is that you have your Data Model which has EF POCO classes with Repositories which knows how to access these Classes for various CRUDs.
Your Domain Model would have models related to your Client (so you can put various ViewModels or Validation related code), It can be a WPF or MVC web app.
Now between these two there is a business which talks to both Domain and Data models.
Your Presentation Layer does know nothing about the EF/Data Layer/Repository. When you want to introduce new Data Framework or database, you just need to write new repository classes and data models classes (which prob. be with some sort of code gen).
This also allows your code to be Unit testable as well.
Just a quick question about my Domain Layer/ Domain Service... Should I allow this layer to have read only access to the database? i.e. hook up a IReadOnlySession and only allow the Repository Layer to have access to CRUD i.e. Persistence? Or should the Repository Layer do both the ReadOnly and CRUD with the service layer making a call to the Repository layer?
One thing I find rather strange is why most of the time the Service Layer is only making a direct call to the Repo, hence the question - move out ReadOnly to the Domain Service Layer.
EDIT:
I have decided to have 3 layers in my app (for anyone who is interested in what I have done), the first layer is the WebUI (I will have 3 in total, business requiement), below this is the Domain Service i.e. All business rules, validation, checking if user can do action x, user is valid user, calling the repo for the data. The final layer is the Repository Layer i.e. the layer that talks to the database iteself, I am using LinqToSql, all my CRUD and ReadOnly logic resides here. As a side note I created another project called Model, this is the actual LinqToSql model entities i.e. Product, Item, Shop, Customer etc. This very project is referenced by the UI, Domain Service and Repo, saving me from writing DTO, and from unecessary complexity hopefully.
In your application, only one 'layer' should talk to the database.
In the Repository pattern, it's the Repository.
It doesn't matter if it's CRUD or ReadOnly, it should go through the repository to the database.
I see the discussion as what are the responsibilities of these layers. The repository is clearly to provide an abstraction over the db. Done correctly and the users of the repository cannot tell if you are using SQL server, mysql or files for persistence. This layer must have all the necessary crud operations.
The service layer is another abstraction. It may depend upon the repository for persistence. There is usually a bit more business logic. Maybe cross repository concerns or another stream of data (gps for instance).
Some apps don't need a service layer. Don't add it until you need it. If you do have the need for the service layer, letting it be a thin rapper around the repo exposing read/write allows your models to only have one direct dependency.