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

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.

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

UI -> WebAPI Controller -> Services Pattern

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

Entity Framework Core and REST client - code organization

I'm building a solution with three projects:
.Data (holds Entity Framework Core-classes and Writer.cs)
.ConsoleApp (Startup project, calls Writer.cs)
.CloudTalker (Web Services references and Fetcher.cs)
The purpose of the solution is to call REST APIs, get entities from the APIs and store them in a database using Entity Framework Core. All code is running fine but I am positive there are ways to improve the architecture.
Example code flow to fetch Customers from the REST API and write to the database:
Program.cs in .ConsoleApp instantiates Writer.cs and calls method WriteCustomers().
WriteCustomers get the latest modified date for Customers in the database
WriteCustomers calls GetCustomers( latestModifiedDate ) in Fetcher.cs in the CloudTalker project. This method returns and array of Customers (the class returned by the REST API, not Entity Framework).
WriteCustomers loops through the array, converts the REST-object to an EF Core-object and puts it in _context.Customers.
Context.SaveChanges() stores the Customers in the database.
Now to my questions/calls for opinions:
Have I done a decent separation of concerns? What is bugging me is that either the CloudTalker needs to know about the EF classes or the EF classes needs to know about the REST classes. Which way is preferred? Should CloudTalker.Fetcher.GetCustomers( lastModifiedDate ) return objects from the EF Classes or the REST type?
How should I handle naming of the classes? Right now I have two Customer - the REST kind and the EF kind. Not pretty.
Anything else I should do differently?
Thanks in advance for sharing any insights.
Seems to me that this should belong to codereview website but here's what I think about the architecture (I am disregarding the fact that this could be a simple project that can live with a quick and dirty solution)
The writer should be in a separate project and should only know about EF and DB, The fetcher should only know about REST and how to call remote services. You can then introduce a service layer that knows about the two former bricks and calls the fetcher to get the data, then pass the data to writer.
I assume there's no business logic so no need for a separate domain project. Your service layer can be directly in your UI/Console project.
For the naming, how about CustomerReadModel, CustomerWriteModel?
It seems that you also need to read from DB to get the last modification date, so I would suggest having a reader somewhere in your db project.

Converting ASP.Net MVC to N-Tier

I recently started learning about ASP.Net MVC and its various features MVC_3_MUSIC_STORE +
CODE .
It looks very structured and simple to understand.
I was reading about enterprise applications and how they are layered/tiered in different sections
(logical/physical)
I was wondering(for learning ) how to do separate(convert) the above MVC_3_MUSIC_STORE into n-tier or 3 tier application (since we already have a working example) in order to have a clean separation of concerns.
I don't have much prior experience in this.
What changes would be required?
What will be different DTO(s) or POCO(s) that would be needed?
The above example uses POCO entities around from controller to views.
Would it remain same, assuming EF Code first is used.
Also i was wondering what changes will be required if WCF Webservice is introduced as a data access layer. i.e.Instead of retrieving data from DAL ,Clients will request data to and from WCF Webservice. Client can be Web app or WinForms or Sliverlight app.
( [DAL <--> WCF WS] <--> N CLIENTS)
Would be interesting to know about various approaches.
Example code would be helpful and/or examples for same.
Edit 1 - Added
One of the things I noticed was when i move the model classes from Model folder to new project "MYMODEL" I will have to again add reference to "System.ComponentModel.DataAnnotations" and "System.Web.Mvc" in new model project?
How can this be avoided? How can these validations be moved to Business layer?
Edit 2
Looking for something similar to this
Advice For A Newbie About N-Tier Applications
Normally the only change that will be required is that you will provide an implementation of the repository (DAL layer) which will call a WCF web service to fetch the domain models from instead of some EF DataContext talking directly to the database. A change completely transparent to Controllers and Views.

Entity Data Framework and Web app architecture

I Am creating a web application and first use Entity Framework. I created Entity Data Model and now I am not sure, how to proceed now.
Premise: My database is really simple (Rating, WebPage, Visitor) and database tables corresponds to the business objects.
My suggestion is 3tier architecture but how to make it?
It is good idea create partial classes with the same name as Entity Framework objects (Rating, Visitor) and declare here new methods (GetAverageRating()...)? Or is better create some VisitorProvider, RatingProvider and place logic here?
It is better use EF objects in BLL and Presentation Layer or I should create my own BO objects on my BLL layer and transform EF object to BO?
I'm think, it is more practical use static methods on my DAL than instantiate classes on BLL. Do you agree?
Can you recommend me some best practices? I have many ideas how to create it, but I do not know what is the right.
3 layer architecture is quite popular but what it really means?
Presentation layer
Application layer
Database layer
If you ask what each layer means you can be pretty sure you will get several different answers. You can further divide each layer into sublayer and build layered hell like:
Client side presentation layer
Server side view layer
Controller layer
Service facade layer
Service layer
Domain objects layer
Repository + Factory layer
ORM layer
Stored procedure layer
Database view layer
Database table layer
WTF? That is just example that application can be easily over architected. It can go even worse if you insist that only neighbours can exchange data and if you decide to add special type of objects to be exchanged between layers instead of flowing sing set of objects through multiple layers.
Add layers which you need to make you more comfortable with developing the application and which will do reasonable separation of concerns and maintainability needed for the scale of your application. You can simply do the most simplest application which will be used just few weeks and must be developed as fast as possible. In such case you can do that within few days simply by using ASP.NET web forms and data source controls (or ASP.NET dynamic data). It can be badly extensible but in such situation it is exactly what you need to implement application quickly. Writing layers and doing all the stuff around maintainability and extensibility is reasonable if you need it. Another quick prototyping technique is ASP.NET MVC Scaffolding which can create quick multilayered skeleton of the application which can be further modified.
Both approaches are correct and it only depends on the approach you like. The first is called active record pattern but it is not used very often with entity framework. The second approach is more popular. You can either use EF directly in some middle class which you called Provider (common name is also Service). This class will do both data access logic and business logic. In more complex applications developers like to somehow wrap EF to separate class following repository pattern and call the repository either from service or directly from web app. code behind or controller (depending on amount of business logic). Try to do it without repository first. My personal opinion is that people should start to use repository only once they understand EF itself.
Again both approaches are correct. In a simple application it is fully acceptable to create EF model with POCO classes (EFv4.x) and use them in all layers. If you are using ASP.NET MVC you can find that you need special classes as view models to fully represent needs of your individual views. In a more complex application you can have separate objects exposed from a business layer - this is especially used if the business layer is exposed as a remote service (WCF).
It depends how you write these DAL methods - it is absolutely necessary to not share the EF context among requests! It also depends if you want to write some test or not. Layer defined by static methods is something which goes directly against testable architecture where you want unit test just single layer (unit testing with EF can be hard). It also depends if you want to use dependency injection which is based on instances.

Categories

Resources