UI -> WebAPI Controller -> Services Pattern - c#

I've been learning about writing WebApi design patterns.
I am trying to create a simple CRUD web app with ReactJS UI and C# .NET CORE webapi with sql backend.
Articles show that specific Repositories are a direct reflection of the tables inside the DAL. And the services layer handles the domain objects and draws entities from the repositories layer. Those same articles also show the controller being designed for changing entities from just one data table in the DAL. So basically, an Employees table inside the DAL would have an Employees Service and an Employees Controller. Is this the correct interpretation?
In my example:
I am confused about which path is the proper way to do it.
I have a form that needs to get, post, put records from two different tables (Employees and Devices) in the DAL.
So do I build a single controller that can handle this form's requests (with JSON obj) or do I build two controllers and code the UI to speak to two separate controllers (one for each table)?
In this example, I skipped the repository layer because there's not much logic to need both a repository and service layer.
Please see the two alternative diagrams:
Multiple Controllers
Single Controller

Related

Where should API Request Model to Database model conversion happen when controllers and logic are in separate projects

I have a small ASP.NET API that exists in two separate projects. The API project holds my controller classes and request/response models. The Logic project holds business logic and database models.
If a user submits a request, lets say a BookRequest, to my endpoint, where is the best location to handle conversion to my Book database model? Originally I had planned to have the Book model take a BookRequest as a constructor, however that would create a cyclical dependency, as Logic would need to reference API. I could move the RequestModels into the Logic project, however I feel those should live in the API project as they are specific to the controllers. The alternative would then be to have the API convert to the database model and pass that to the logic.
Is there a better method for handling this case while keeping the projects seperate?
To avoid the cyclical dependency you described you may want to consider breaking things out into a third project, with its own models. The problem comes in because your 'Logic' project maintains both your business logic and database models.
A simple example would be:
API with API-Models <--> Business Logic with DTOs <--> DAL with DB Models / Entities
In this example the Business Logic layer would handle the translation of API Models to DTOs (Data Transfer Objects), and DTOs to values returned from the DAL (Data Access Layer).
Consider researching common architecture patterns to find one that may fit your needs. A common pattern I often use is the Clean Architecture.
Here is a link to Microsoft Architecture Patterns documentation:
https://learn.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/common-web-application-architectures

solution architecture for an OData / Web API based .Net project

so far in my office i have developed a number of small and medium sized .Net web based applications where i used to architect them something like this -
Web layer (.Net Web APIs)
Controllers, filters
Services (contains business logic)
IServices
Repository (gets data from database using entity framework / ADO.Net)
IRepository
ViewModel
Model
I used to have different projects for each of those listed above in my solution.
But now we are moving towards OData Web APIs and trying to get away with entity framework. So i am a bit confused about how my solution architecture should look like.
Question 1 - Where should my DBContext file be located?
Question 2 - How am i going to query using OData from Controller -> Service -> Repository
Question 3 - Can i still follow the architectural model given above and have OData instead of entity framework getting data from database?
Question 4 - I will still need a separate business logic layer (Service layer) between data source and controllers so i can keep my controllers as thin as possible
Please excuse if i am asking any wrong/silly question since this is my first effort trying to figure out how i can use OData to perform my tasks.
Following are the details of what we do in our project, if that can help you to an extent. We have Web API services, which have API controllers, which are used for Json serialize the end result. Following are the important layers and their respective roles:
Web API Controller
Receives the Rest request, Serialize / De-Serialize from / To C# objects
BL (Business Layer)
Business processing and External Service Integration (like Web services)
Helper Layer
In memory processing to convert simple Data entities / Poco's to complex UI / Return entities, which are finally converted to Json. This layer has lot of Linq to objects code to do the task well. It has fair amount of logic.
Repository Layer
Fetching the simple data entities, mostly as IEnumerable<T>, using our custom Micro ORM. Sometimes for specific cases we even fetch DataTable / Dataset directly and use them for further processing
ADO Helper (Custom Micro-ORM)
Use Reflection to fill a POCO at runtime, using DataReader or DataAdapter, this part can be replaced with any other dtaa fetch mechanism
Common Entities: (They can be accessed across layers defined above, though we restrict to ensure consistency)
Data - Simple POCO classes, which fills db data
UI - Final result entity
Input - For input from REST call
Constants - For hard coding and constant values across the project
All the C# layers below Web API can be created as dll, since the relation is unidirectional, from BL - Helper - Repository - ADO Helper. Any additional layer for a specific purpose can always be inserted or adjusted. It is important to separate the specific role of each entity.

MVC architeture with EF Code First

I'm trying to understand how to separate the model class / MVC to interact with the database design in EF CodeFirst.
For example, considerate this simple architecture:
MyApp:
1. WEB
2. DATABASE
3. ModelEntity
The questions is:
Who should call the database without show tables in WEB UI?
The ModelEntity or model/MVC?
Is it necessary to use mapper in this case?
Your controller will be your middle man between the web ui and models, which represent tables in your database.
Normally, you web UI will use ViewModles, which may not be consistent with your ModelEntity, and that's when a tool like AutoMapper is very helpful.
This is how I usually have mine separated out:
1) Data layer: entity models, EF mappers, EF contexts
2) Domain layer: domain models, entity to domain model mappers, query objects, query handlers, command objects, command handlers, services
3) Application layer: view models, domain to view model mappers, application facades
4) UI layer: controllers, razor views, maybe some other view models that didn't fit into the application layer

Where to put Business Logic classes in an Entity Framework - ASP.NET MVC 4 Solution?

I have a Solution with one project is Entity Framework and have my ASP MVC project, I looking for some advice or opinion about the idea of create in top of my POCO objects and the DBContext, a Business Logic Layer with static classes that have the all the methods (example a ContactBLL class with GetContactByID, GetAllContacts, GetContactsByType) to allow the access to the model data and that can be accessed in the Controllers Actions. In that way I don't have to put the implementation code of this methods in Controller Actions methods, and it can be reusable invoking this methods in other Action Controllers. I will appreciate your opinion because it could guide me to respond a question I've asking to myself around a week based in the answer to this one (about where to define the DBContext and how use it).
You can create different projects according to core functionality.
Data Access Layer(DB context and repository etc.) you can make Project.DataAccess, it will have only db context class and repository.
Business Logic Layer(Project.Business) it will have business logic and make call to data access layer.
UI Layer(Project.WebUi) it is mvc project.
and so on.
for detail info you can see this http://prodinner.codeplex.com/ code
Create separate class library for your POCO,
then create another class library for your repository, this should
include only the interfaces needed for your repository
and the implementation will be on another class lib like Project.EF,
Project.NH which will include Entity Mapping, Migration, Repository
implementations. but in reality, chances are you wont be changing
your ORM lib once it was implemented because it will just cause you
a lot of headache(just my 2cents).
you'll create your business layer(class lib) and
web project as separate lib. Models folder of your MVC project will contain your ViewModels.
this is what Im using right now and of course not the best structure, it just something that Im happy with :). hope it helps.
In general, there are four standard projects in a ASP.NET MVC - Entity Framework solution. They are 1) MVC, 2) Core/Business Logic Layer(BLL), 3) Data Access Layer/DBContext (DAL) and 4) Common/Utility.
Standard MVC project consists three main elements which are Model, View and Controller. However, middle to complex solution usually cuts off the Model element from MVC project and moves it back to BLL, we call it as ViewModel(POCO). Following this structure, MVC project is now responsible for employ/use the services from BLL and control the UI through controller.
Business Logic Layer (BLL) is the core of implementing business logic. It is responsible for serving request from the MVC project and work with DAL to persist data. As said above, BLL is the place to define ViewModel, its relations as well interface/ abstract class to support implementing design pattern. Viewmodel(POCO) is likely mapping one-one to data entity at DAL but we do not use the data entity directly on View. Following this structure will help to increase the customization on ViewModel like adding constrains
DAL is the place for DBContext and its data entities.
Common project consist of shared functions like Logging which is used in 1) 2) and 3)
Please read more at
https://www.codeproject.com/Articles/70061/Architecture-Guide-ASP-NET-MVC-Framework-N-tier-En
https://chsakell.com/2015/02/15/asp-net-mvc-solution-architecture-best-practices/

Pass EF context on a project with multiple layers

I have an application that is separated into 4 layers to keep code organized and be able to reuse it.
My layers are:
presentation layer: an mvc4 project
business layer: a c# library project whit the Business logic
Data layer: a c# library that contains all the linq to the db
model layer: a c# library that contains a edmx ef5 for my database
So the idea is that for each controller or our mvc project we have 1 business class and 1 data class. and if some functionality needs to make use of code on other class, they do at business logic layer (different business logic classes can create new instances of other business logic classes.)
The problem I was having is that I was creating too many DbContext and I was getting some errors and problems because of it. Like loosing the lazy loading on my BL layers or not been able to assign objects like list to other objects when they came from different DbContext.
For example, if I have a medic controller/logic/data and I use a patient logic/data to get a list of patient for today, I get an error when I try to do medic.patients = patienstList;
So what I need to do is use one DbContext per web request, so the DbContext will be created on the controller and injected to the logic layer and those will inject to other logic class or to the data classes?
How can I do it?
There are number of ways of doing IOC in MVC.
Example would Unity.. where you can register an instance of DBContext.
Of course if the lifetime of you IOC container every extends beyond web requests. your are in for nasty time.
Even if you think it is 1 Context per request that you need. Be very careful if you use ASP pipeline events and access DbContext, you may actually need 1 context per Thread. But if you are happy to say you access starts at MVC Controller level. Then you are looking for a way to handle inversion of control only.
Unity from microsoft
dependency injection docu
https://unity.codeplex.com/documentation
IMHO the Business Object should not have to use another Business Object because that violates the Single Responsibility Principle.
The Data Layer object should be able to do everything the Business Object needs it to.
So you should write methods in the Business Layer Object and Data Layer Object method GetPatientsForMedic.
You may say "but the Hospitals Business Object can get me a list of Hospitals really easily". That is not it's job, because you said it's job is to service the Hospitals controller.
HOWEVER the problem only happens when you pass a Hospital object from the HospitalsBO to the MedicBO. So don't.
On the Hospitals controller, write a method GetListOfHospitalIDsAndNames. Then, if you need a dropdown of hospitals, call that, and use the IDs and text names.
You can indeed share a DbContext between two Business Objects by sharing a Unit of Work. But you probably shouldn't.
However i'm no expert... i avoided these problems by having one GINORMOUS business object with everything in it. That is also a BAD THING.

Categories

Resources