What to put in Business Logic Layer? [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have read lots of articles and they seem to vary from one author/developer to the next. In my situation, I am thinking about this setup for testing a project:
Presentation Layer via ASP.NET MVC
Service Layer (my plan is ASP.NET MVC Web API; this is on separate assembly)
Business Logic Layer
DAL using EF
Some articles said I should not put CRUD operations on BLL and BLL should only contain business logic. Also, some said BLL should not access DAL. But what if a business logic needs data stored in DB to calculate/work on logic? I guess my questions would be:
If BLL shouldn't access DAL, how about those business logic that needs data in DB for it to be able to perform the logic?
BLL are entities, right? Are they the same as POCO or would I still have POCO in DAL?
Also, is DBContext in BLL? Some say it should so I'm confused.
What about the no CRUD in BLL? Should I do that?
Repository interface is in DAL?
Any additional comments/suggestions/information on what my planned setup would be very welcome (even if it is not related to BLL).

I worked on a project some time ago.
Our project arquitecture ressembled to what you suggest.
We had an ASP.NET MVC site, which accessed a WEB API (in an external solution).
The WEB API also referenced an external solution entirely made up of static libraries, which contained the data layer (just entities) and the persistence layer.
We also had Data Transfer Objects (MSDN) for communication between the web service and the clients, and to decouple the entities entirely from external solutions.
We had the business logic in the WEB API project. We would create, manipulate and store the entities from within the WEB API HTTP methods.
But we didn't accessed the data and persistence layer directly, we had an intermediate layer, we called it entities manager. These managers would be injected on our WEB API controllers (We used Ninject for Dependency Injection) and would handle the creation of the entity, and also the persistence, so we'd decouple everything.
This approach worked very well for us, and we made a pretty well maintainable and scalable project.
I hope it may be of help for you, and of course, there probably exist better techniques.
PS:
We used an IRepository interface provided to us by the entites manager to persist the entities. This was our only access to the persistence layer. Inner logic, such as persistence strategies (like EF's DbContext, or File IO) would be internal to the persistence project.
This is an example of our bussiness logic in one of our WEB API HTTP methods:
// "repository" is an IRepository<Entity>
entityManager.Transaction( (repository) => {
Entity ourEntity = repository.CreateNew();
//Manipulate the entity somehow
repository.Add(ourEntity);
});

The data will take different forms, for example in the data storage DS (SQL Server for example) they are on relational tables, in the data access layer DAL they are in the Data Model (object model) like Entity Framework EF, in the presentation layer PL they would be in View Model, and on the HTML page or desktop form they will live inside a UI component.
At a single point when a layer calls another layer they have to have a communication channel and a data container that would change the data from one form to another.
Whenever a DAL asks for some data from DS it should be changed from table form to a object model form, so the DAL does not care about the table form. When you send the data back from the DAL to the PL it should be changed to be in a View Model form and again the PL does not care about the object model form, and so on.
You might ask about the BLL layer, I guess this layer most of the time is just a delegate in the middle when there is no logic in the middle, so for some performance matters the PL would access the DAL directly.
I hope this would answer your questions.
EDIT
For the BLL you consider as the mind of the system, the PL is just showing what it receives, and DAL just returned what is asked for to return by acquiring the right DS entities. So the CRUD would be in the DAL.
For Example you need to search for a list of employees, the BLL here is just a delegate layer where it delegates the PL call to the DAL and return back the results. But in case of adding a new employee, the BLL would have an interface with function like AddNewEmoloyee which will do some business logic functions like for example making sure that the salary is according to the employee level range, and then it will call the needed CRUD actions in the DAL.

Related

Can I Return DTOs From DAL [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I have started using an onion architecture because I wasn't satisfied with my previous project structure. My main question is, can I return DTOs from the data access layer?
This is my current structure:
/Core
- Application
- Domain
/Infrastructure
- Persistence
- Identity
/WebApi
- WebApi
Quick explanation:
Application layer is where I have all my business logic
Domain layer is where all the entities/models are defined
Persistence layer is where I query the database
Identity layer is for user management
WebApi layer is where I have my controllers
The data flow is the following:
Client <- WebApi Layer <- (DTO) Application Layer <- (Entity) Persistence Layer
As of right now, the persistence layer returns the actual database entities which are defined in the domain layer which the application layer transforms to DTOs.
My problem here is that often, the persistence layer actually needs to perform different queries which will make the type different from the entity type. For example, I could join different tables, apply groupings, etc. Thus, I cannot return an entity type.
Am I allowed to return DTOs from the persistence layer (data access layer)? If yes, where do I defined these DTOs? Defining them along with the other DTOs in the application layer and using these DTOs in the persistence layer would make it dependend on the application layer (not so great in my opinion since we want to minimize couplings). Another option would be to create them in the domain layer along with the entities (probably the better approach)? For consitency's sake, should I only return DTOs from the application layer or is it fine to return entity types as well as DTOs?
Lots of questions that I couldn't find. Just trying to become a better programmer:)
My main question is, can I return DTOs from the data access layer?
Yes. Noting that:
Yes, because who's going to stop you?
Yes, as in it's a common enough recognized pattern, and generally speaking no kittens will die if you take that approach.
Am I allowed to return DTOs from the persistence layer (data access layer)? If yes, where do I defined these DTOs?
My default "in the absence of a reason not to" architecture for layered apps is to use DTO's, which I typically define in a common library. Detailed write-up of that here (pdf). The Data access, business logic and UI all share this as a common vocabulary.
This makes them useful for where you use Dependency Injection to abstract out your data access - the interfaces you define will also have to use the DTOs in their signatures.
If you want to, you could define DTO's that only the data access layer, and it's consumers know about - the question is why would you want to? Not to say you can't - only that you should only do that if you have thought it through and have a meaningful reason to do it.
My problem here is that often, the persistence layer actually needs to perform different queries which will make the type different from the entity type. For example, I could join different tables, apply groupings, etc. Thus, I cannot return an entity type.
Sometimes you'll have scenarios where the DTO's you create are very scenario specific (don't get reused). Only you can say if that's acceptable or not. It's a trade-off between how much code you want to maintain, and how fit-for-purpose DTO's are. I don't think having scenario specific DTO's is bad in of itself, if it means the architecture remains clean and how you implement the scenario is sensible.

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

Structuring an MVC application - Model and Data Access [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I'm rewriting a web app in MVC and I am trying not to get hung up on the architecture, but then, MVC has patters which I want to stick to
My application has views which display data retrieved from a database.
Normally, I would write my controller action as follows
public ActionResult Index()
{
var model = new IndexModel();
model = DbHelper.GetData(); // business layer
return View(model);
}
But I have been doing some reading saying that data access should be done in the model, so is something like this better?
public ActionResult Index()
{
var model = new IndexModel();
return View(model);
}
And IndexModel:
public class IndexModel
{
public string EmailAddress { get; set;}
public IndexModel()
{
// Fetch data in here...
EmailAddress = DbHelper.GetEmail(); // for example
}
}
So, should the controller include the logic to fetch the data, or should the model handle it? A lot of the MSDN examples show the controller populating the model, but that seems to break the layers of MVC
The question is somehow opinion based. But considering the following ideas may help:
Model
Let it be responsible for transferring data between layers.
Use plain classes as View Models or Input Models.
Don't put business logic or data-access into model classes.
View
Let it be responsible for rendering the UI.
Just use Model and don't call business logic classes directly.
Controller
Let it be responsible for handling requests and providing response. Also responsible for controlling flow of application.
Controllers should only call Business Logic methods and they should not contain any business logic
Don't interact with Data Access Layer directly. Let this Business Logic Layet take this responsibility.
Business Logic
Let it be responsible for business operations like changing data, processing data, search and loading data.
Use data access layer methods for CRUD operations. Don't rely on database directly. Let Data Access Layer handle CRUD operations.
Create each business method as a single unit of work which
Data Access
Let it be responsible for CRUD operations with data.
While you can use a ORM instead of this layer, but in a large application, you can also create this layer as layer which uses ORM.
General considerations
Create abstractions for different layers.
Controller should rely on Models and Business Logic Abstractions.
Business Logic should rely on Models and Data Access Layer Abstractions.
Data Access layers should rely on Models and ORM
You can use different model types for different layers or create a shared model library.
You can have a shared library for cross cutting concerns like log.
MVC (Model View Controller) is a broader design pattern governing the ASP.NET MVC applications architecture, but its not the only pattern a given application shall stick to. The ultimate goal is to have neat and clean code, loosely coupled artifacts and focus on code re-usability.
Usually my approach to project architecture is have a separate project for Data-Access Layer(usually a class library project) and another for Business-Layer (to implement business-level decisions) (also a class library project) and an ASP.NET MVC project as a Presentation-Layer project . The Business-Layer project has a dll reference of Data-Access project and Presentation-Layer project (ASP.NET MVC Project) shall have references of both Data-Access and Business-Layer projects.
Now I use dependency injection approach to provide data-access dependencies to controllers in their constructor, something like this
private IDbHelper dbHelper;
public HomeController(IDbHelper _dbHelper)
{
dbHelper=_dbHelper;
}
So the db-access class shall be made available through a dependency injector (Ninject for example) and the individual action methods shall not have to worry about how to create objects. Now your action method shall simply make calls to the dbHelper class like this
public ActionResult Index()
{
return View(dbHelper.GetData());
}
Also please note that besides using Models your application shall need to create View-Models (VMs) (Models returned from database and modified by business layer to meet the business specific needs).
So in short a good project is a combination of several different patterns and architecture styles that are implemented to make the code re-usable, neat and clean and easy for testing.
Thanks.
Consider using dependency injection, especially if you're going to be doing a lot of unit testing (e.g., with Moq). Obaid (user who made a post above) posted good information about this.
See the following reference for more information:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2
Note: As shown in the above reference, you will need to configure your services in your Startup class (or whichever type you chose to configure all of your services for MVC).

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.

n-Tier Architecture Feedback Needed

I started my website, like stackoverflow, with a little technical debt that I'm trying to pay off. Being a contract developer, I've been in many places and see many different methods of achieving this result, but the way I'm going is..
Presentation (web)
Business Layer (old fashioned entity classes and BL layer)
Data Layer (DA classes to SQL Server via Stored Proc)
My question primarily concerns the Business Layer. Right now I have an Entity namespace and a BusinessLogic namespace.
The BL has a reference to the DA and the Entity.
The Entity has a reference to the DA
(The DA is "unaware" of the BL or Entity)
I really want all my churning of turning Data into Entities to occur within the BL -- thus the Business Logic. However, I want the Entity to be able to access the BL if need be -- and thus remove the Entity's reference to the DL.
So...
Is is "wrong" to have the BL and Entity objects within the same namespace so they can work together?
Essentially, I'm trying have an entity object like Employee (classic example, eh?) and have the Employee have a
public Hashtable[] SubordinateEmployees
property that returns a Hashtable of other Employee objects that report to this employee. But I don't want to load it until it's needed. So for most employees the property would never get accessed, but when it does, it self-loads with a call to the BL, which calls the DA.
Does the question make sense?
If so, does my solution?
Thanks so much in advance!
The usual way to deal with the kind of situation your example represents is with facades. Instead of trying to get the subordinate employees from the Employee object, you use a call to the business logic to get it.
hashtable = BL.GetSubordinateEmployees(supervisor);
That way you have a single point of access to the subordinates, and there is only one thing (the BL) accessing the data layer and creating Entities.
Let me see if I can show you a better way to think about this
you have your data access (sql server, mysql, flat xml files, etc.) all of this should be abstracted away nothing else in your application should care or know how you are getting your data, only that it dose, if anything else knows how you are getting your data you have a layer violation. if the DAL dose anything other then get data you have a layer violation. Next you implement a data access interface something like IDAL that your business layer uses, this is very important for making your code testable by forcing you to separate your layers.
Your data entities can be placed in the DAL name space or give them there own, Giving them there own forces separation. Data entities are dumb objects and should contain very little to no logic and are only aware of themselves and the data they have, THEY DO NOT CONTAIN BUSINESS LOGIC!, DATA ACCESS LOCIC, OR UI LOGIC. if they do you have a layer violation. The only function of a data entity is to hold data and be passed from one layer to the next.
Biz layer implements a data access interface like the IDAL we talked about before you can instantiate this with a factory, an IOC container, or all else failing a concrete type, but add a setter property so this can be changed for testing. The Biz Layer Only handles Business logic, it doesn't know or care where the data came from or where it's going, it only cares about manipulating the data to comply with business rules, this would include date validation, filtering (part of this is telling the DAL what data it needs, let the DAL figure out how to get it). Basically the BIZ handles all logic that isn't UI related or Data retrieval related. Just like the DAL the Biz should implement an Interface for the same reason.
The UI layer Accesses the Biz layer the same way the Biz layer accesses the DAL for the same reason. All the UI layer cares about is displaying data and getting data from the user. The IU Layer should not know anything about the business rules, with the possible exception of data validation required to populate the Data Entities.
The advantage of this architecture is it forces separation of concern making it easier to test, more flexible, and easier to maintain. Today you are building a web site but tomorrow you want to allow others to integrate vi a web service, all you have to do is create a web service that implements the IBIZ interface and your done, when you have to fix a bug in the BIZ layer, it's already fixed in both your website and web service.
Taking this to the next level, lets say you are doing a lot of heavy number crunching and you need more powerful servers to handle this so all you have to do is implement an IDal and IBIZ interface that are really wrappers to WCF that handles the communication between your servers, now your application is distributed between multiple server and you didn't have to change your code to do it.

Categories

Resources