we have a classical 3-tier-architecture application. Now we face a little problem and we don't know the best way to handle it.
In the last layer (database-layer) we have a POCO-class, that gets filled with data from a database. In the top layer we have a MVC3 asp.net web-application. The MVC application would work best, if it could just read the POCO-class.
But as the GUI-layer cannot access the database-layer directly, it cannot get the exact same class.
What is the best way to get a POCO-class from the last layer to the top layer?
The actual issue is that your entities should not be defined in the data layer. Data layer, as well as any other layer in your app, might get completely rewritten one day, and you don't want entities themselves to be tied to any of these layers.
In other words, define your entities in a separate project, and then reference it from all other projects:
- Entities
- Data access layer
+ references Entities
- Business layer
+ references DAL
+ references Entities
- Presentation layer
+ references BL
+ references Entities
The same goes for repository interfaces: if you are using a repository pattern to abstract your data access, Entities project is the one which should contain all repository interfaces, which can then be implemented by a specific DAL choice.
You can create a project of DTOs that is referenced from all the different layer projects. This way you can share the DTO POCOs between all the layers of your application.
Related
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.
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.
I'm creating an layered app in C# and trying to use EF 6 in it.
I want the code first approach (POCO).
My idea of layers (projects):
DAL (Entity Framework 6).
Entities (Where I have my classes that represent my tables in the DB, or entities representing my DB objects).
Business (I add via method extension methods to the Entites classes, like 'void CalculateTaxes()' to a Product class).
Presentation (UI, for now is Win Forms, later can be web...)
First, I'm relatively new to all of it and I'm studying layer architectures.
The question: The DAL layer gotta reference the Entities layer (where I have my DB objects) for creating and maintaning the DB and the Entities layer gotta reference the DAL layer to access the objects from the DB, and I cannot do this (circular dependency).
How should I procede in this scenario? For more experencied developers, is this the best approach?
Entities layer gotta see the DAL layer to access the objects from the DB
This is where you should break your dependency. The entities should be storage-agnostic. The current popular method of bridging the entities and EF is a Repository layer that encapsulates the CRUD (Create, Read, Update, Delete) logic.
Following the desing proposed here MVC3 and Entity Framework, I'm trying to create different layers for DAL, BL and web, using MVC4 + EntitiFramework5.
Quote from #Davide Piras
1 - ProjectName.Interfaces (Class library, entities's interfaces);
2 - ProjectName.DAL (Class library, the only one allowed to even know the EF is used, the POCO entities implement the interfaces of project 1 using another file where you redeclare same objects using partial classes...);
3 - ProjectName.BL (Class library, Business logic, references the two projects above 1 and 2);
4 - ProjectName.Web (ASP.NET MVC application, Presentation Layer, references two projects 1 and 3 but NOT 2);
I have a doubt on the connection between BL and DAL. DAL knows EF, BL shoudln't .. but how to implement it? I mean, I created the classes that represent my entitis on both the layers (and this seems a bit a duplication to me .. even if in BL I'll add validation and other sutff), but how I expose the database values to BL?
in the default MVC4 solution I have
DbSet<Entity> entity
that I can query (.Find, etc) .. I suppose I need to map them in my BL (IQueryable? IEnumerable? Isomething??)
compltely confused .. any helps is appreciate
The lines can become a little blurred when you speak of DAL and EF. In some cases you could consider EF the DAL. But I usually do not have the the BL access EF directly and abstract it to a higher level, so that you could easily swap out EF as your ORM if need be. I use the Repository Design Pattern to further abstract EF. The other advantage to this pattern is that it makes it easier to unit test and you can use dependency injection. I also use the Unit of Work Design Pattern to handle transactions in the system. So are the Repository and the Unit of Work part of the DAL or is it just EF. That is probably debatable and I know longer concern myself with trying to define the DAL. Here are the layers I would recommend using in an MVC 4 project.
The Application or Domain Layer is your BL Layer. I tend to incorporate concepts used in the Service Layer in this layer as I have not seen any benefit yet in separating it out. But there is the option of adding this layer on the top also.
No, the Business Logic layer needs to know about the DAL because it needs to call methods on the DAL in order to retrieve/update/add data (only using the Interfaces, it shouldn't be allowed to see the POCO classes). The BL doesn't know anything about EF (which is as it should be, incase you ever wanted to replace EF with something else).
So, for example to add a new record:
User adds the new details and submits the form
Web project calls AddItems in the BL layer (using a list of objects that are the interface)
BL project has some business logic, additional validation before passing the list of objects to the DAL (also has the error handling too maybe)
DAL creates the items in the database, then, if required, passes a list of the interface back
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.