I am currently implementing a system and I have a question regarding the interaction between different elements in the system with the class that interacts directly with the database (the one opening and closing connections, executing sql queries, etc).
So far, my Business Logic Layer is deferring the construction of all SQL queries (depending on certain inputs) to my Database Access Layer, which in turn would call the database-handling class to execute each query. Note that right above my Business Logic Layer is the GUI.
The question is: would it be bad practice to include the construction of SQL queries in the Business Logic Layer? I am asking this because I need to implement a procedure that gets data from database DB1, manipulates it, and then writes it into DB2. Thus I find that hardcoding these SQL queries would be easier to keep in my business layer.
Please let me know your thoughts and if this is a clean design to some extent from an architectural point of view, or if I should include this logic all in my Database Access Layer.
would it be bad practice to include the construction of SQL queries in the Business Logic Layer?
Most likely. The business layer should generally be database-agnostic.
I need to implement a procedure that gets data from database DB1, manipulates it, and then writes it into DB2
So you need two data layer objects - one to get the data from DB1 and one to save it in DB2. The "manipulation" can be done in either place (business layer or data layer), depending on the nature of the manipulation. For example, is it purely a data conversion, or does it depend on other aspects of the business layer?
You don't need to bring this logic to Business layer at all.
Follow this steps
Request data from DB1 from the business layer
Data Access Layer returns the Data from DB1 to Business Layer
Manipulate the Data in Business Layer. (Calculations, transformations and what not)
Request the Data Acess Layer to insert this new Data to DB2 and pass along the processed data to Data Access Layer
Data Access Layer writes to DB2
This way is more elegant and you can keep your current architecture unchanged.
EDIT
You can create a separate Data Access Layer for accessing DB2 and have the Business layer call it on step 4. That way you can keep Data access layers more coherent.
Related
My project has 4 layers: Presentation, application, domain, infrastructure.
I am using ORM for the write side. Read side, sometimes I have cases that have a complex query. I process by using a native query.
I write it at the infrastructure layer. But, I see some projects such as "ESHOPONWEB" write a native query in application layers.
Which layer should contain the native query?
I wasn't familiar with ESHOPONWEB aka eShopOnWeb, a reference architecture & implementation that Microsoft put out, but I see it has an accompanying eBook which includes an "Architectural principles" section, another on "Common web application architectures", and at a glance other sections explain the architecture in more detail.
Using the book and code should give you a good way to learn the relevant concepts at your own pace.
Which layer should contain the native query?
I'm not 100% sure what you mean by "native query". I did a quick search through the eBook and didn't see any obvious references to that.
Typical best practice architecture (like what is in the eBook) says that queries in the Application / Business Logic layer should be agnostic - meaning they should not contain any code or dependencies that tightly-couples the Business Logic to a specific Data Access provider.
So, if you need to query a data base, the database specific query code (or reference to a Stored Procedure in the database or any other database specific concept) should be in the Data Access code, which is in the Data Access (Infrastructure) layer.
If something in your Business Logic layer wants to do a query, there's three approaches that come to mind:
It wants to query itself, which it is free to do, using agnostic code against objects it already has.
It wants to query data from the database, it gets the Data Access to do that. The query inputs and results need to be transported between these layers agnostically. E.g. query results might come back as a collection/array/list of Data Transfer Objects (DTO) or Plain Old CLR/Class Objects (POCO).
You take some section of data from your database / Data Access layer, pre-load that as a database agnostic data model in the Business Logic layer, which it can query just like #1.
I'm not sure, but your Domain layer might be what you can use to do #3?
Does that make sense, and answer your question?
Regarding Layers
As the eShopOnWeb book explains, you want to keep various "concerns" (like business logic, UI, and data access all separate. The separation is to make maintenance and change easier to manage, especially over a long time. E.g.:
Keeping the business logic layer/code separate from the UI layer/code means that you should be able to add new types of UI without having to re-write the application code.
Keeping the business logic layer/code separate from data access layer/code means that you should be able to add/swap data providers (e.g. different types of database), and the business logic should be less impacted by database changes.
In the two points, above I say "should" because it depends on how clean and effective your separation is.
To translate that to your layers, UI is obviously your Presenation layer, Business Logic sounds like your Application and Domain layers, Data Access is your Infrastructure layer.
In the eBook they give an example (fig 5-1, pg 16) where they logically have those four layers you use but in the one code-base / package (it will all get deployed together).
If I have a C# application with a 5 layer architecture, much like what is presented here http://msdn.microsoft.com/en-us/library/ee658109.aspx, and I take the strict interaction approach of allowing a layer to only interact with the layer below, I am running into trouble when getting data in my Data layer and passing that data back up to my Business layer.
For example, if I have a business object called MyObject that is defined in my Business layer, but information needed to construct an object of type MyObject is retrieved from the database in the Data layer, my Business layer needs a reference to my Data layer in order to interact with the database. But, my Data layer then also needs a reference to the Business layer, since that is where the MyObject definition lives and the Data layer needs to construct an object of that type from the database results and give that data back to the Business layer. Now we have a circular dependency between the Business layer and the Data layer.
I am wondering what the proper approach is to solve this problem.
I have thought about using DTO objects defined in my Data layer to pass information back to the Business layer. This would work since the Business layer is able to interact with the Data layer, but not vice versa. It just seems like this might be an awful lot of duplicate code to basically mimic the business object definitions in the Data layer.
I also thought about creating interfaces for all of my business objects and putting those interfaces into a separate project that both the Business layer and Data layer can interact with. That way, I can pass instances of the interface and the only common reference between the Business layer and Data layer is the project where the interfaces are defined. I don't see many implementations of this either.
I am wondering what others have done to solve this problem.
Sounds like you would benefit from AutoMapper.
https://github.com/AutoMapper/AutoMapper/wiki/Getting-started
Each layer of your application should have it's own "version of the truth." The data layer has POCOs that are shaped based on the storage format of the data. Then your interface between data and business layers should take those data POCOs and map them into business POCOs. Rinse and repeat for the business/ui boundary or any other layers you may have.
The shape of the data that describes an object best in one layer shouldn't dictate how another layer can best describe an object. (i.e. The data layer might need foreign key ids, but the view can do just fine with an in-memory reference.)
If you need to construct the data on the Data side, then define the type in the data access layer. If the object is constructed in the DL, then that's where the type belongs. This allows you to avoid the circular reference. Just reference the Data project in the business layer project, and you have access to the type.
Another solution is to return raw results from the data access layer, and construct the object in the Business layer from the raw results.
I want an opinion from technocrats,
We are migrating legacy system build in Oracle forms using Oracle 8i
database. Client wants to redevelop this legacy system in web
application so we choose MVC3 framework. Client wants us to re use all
stored procedures of legacy system, which contains business logic of
application.
If every business logic is written in stored procedure than i think we
don't need a Business layer in our system.
So i created three layers -:
Interface Layer -> MVC 3 application
Data Layer -> Used to fetch information from stored procedure
DTO Layer -> Used to transfer data from Interface layer to Data Layer.
I did not created Business object or business layer , since all
business logic is inside Stored procedures. I don't like creating
business layer who just forward request from Interface layer to data
layer and don't have any business layer in it.
Is this approach is correct ?
Business layer is separate project
If the business layer is a separate project, I would focus on the portions which are part of the project. It is entirely reasonable to have an interface layer, with minimal business logic (usually validation logic) in a server side application. You might want minimal business logic in the client to make it more responsive i.e. it doesn't go all the way back to the database to validate input.
You can have the business layer in the database (not that I would do such a thing), or in server side Java, or some of it in the client (not that I suggest doing that either to a significant degree)
I would recommend that you still create a business layer even if it just forwards all the operations to the stored procedures which are part of the data layer.
Since the client wants you to reuse all the stored procedures that have the business logic in them it also sounds reasonable that he will not want you to modify or add any more stored procedures. Events may occur that will require you to implement them differently or change the sequence of a business logic that you can then put into your business layer. Maybe you may need a business logic that is not data-centric - meaning it does not sound reasonable to have it in a stored procedure, like sending an email or coordinating with a third party system.
Good day. I have to pass the session value to a business logic layer, I can pass it to the function from presentation layer but how can I access it directly in my business logic layer ? Also is it a good approach to pass it directly to business logic layer like
GetMyRecords(Count,Session["userID"].toString()); ?
As per John's reply above, you ideally do not want to access any UI elements in your business layer.
You should pass the session values from your presentation layer to the business layer so that the business layer is only aware of the values - not where they are coming from.
As regards your second point about how to pass the values from presentation layer
I would suggest you should atleast wrap Session["userID"].toString()) as a property in your presentation layer.
Because its a property, you can add checking / validation logic if needed.
Also, i find it cleaner to have a wrapper SessionWrapper class and use that in the application for accessing the session values. The advantage of this is that if your Session Persistence changes, its usually a one place change. Of course, this is not necessary as the .NET Session Providers can be plugged in via configuration even if you create your own provider.
I would recommend to not access Session from within the business logic layer. The intention of having separate layers is that they serve different purposes. For example the business logic layer should not - generally speaking - contain any reference to the user interface technology, e.g. Session in this case.
The translation from the presentation layer (aka UI Layer) to what the business layer expects should be done in the presentation layer. Who knows? Maybe next week your boss asks you to move the business logic off that web server and onto an application server and use WCF based communication between them.
Clear separation keeps more (all?) of the paths open for tomorrow even if you don't know how tomorrow will look like.
How to develop program/website and minimize DB dependencies using C#.NET?
For example I have made some changes in my DB, after that I must rewrite half a project.
The strategy it to split your application to a different logical layers abstracting the data storage layer from the business logic and UI.
So a simple example will be to have:
Data Layer - your database engine;
Data Access Layer - code which will know how to read and manipulate data from the Data Layer;
Business Layer - will know how to represent Data Access Layer object within your data domain;
Presentation Layer - to display/edit Business Layer objects.
For not very complex domains you can use technologies like LINQ to SQL or ADO.NET Entity Framework to act as 2-3 layers.
Read about Repository pattern and nhibernate