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.
Related
I'm developing N-Tier application in C#. Server side consists of this layers:
Data access layer (EF Code First Entities and DbContext)
Business layer (contains all business logic and objects)
WCF Service layer (per-call instanstiated services that expose some operations from business layer)
Now client requests are processed in this way:
Client creates Request DTO and sends it to Service layer
Service layer maps this DTO to business object and calls BL method
Business layer does something useful, makes requests to DAL, and then returns some business object to service
Service layer maps business object to DTO Response and returns to client
It works nice despite code duplication which is mitigated by Automapper. The actual problem is this:
Client shows same objects in different views: grid, form, etc. For example, grid(list) view requires only Id and Name from User object, while Form(details) view needs every User's property. But Business layer knows nothing about views. It can only provide full UserBL object to Service calls and then it's the Service responsibility to map this UserBL to UserListDto or UserDetailsDto. And for some heavy objects, fetching extra fields from DB become a performance issue.
So, should Business layer provide different methods for different client operations? I don't like this solution because it looks like domain logic polluting, but I don't know what else could be done.
Client shows same objects in different views: grid, form, etc. For example, grid(list) view requires only Id and Name from User object, while Form(details) view needs every User's property. But Business layer knows nothing about views. It can only provide full UserBL object to Service calls and then it's the Service responsibility to map this UserBL to UserListDto or UserDetailsDto. And for some heavy objects, fetching extra fields from DB become a performance issue.
I usually return different representations of a business entity depending of the type of action that is made in the BL. For instance when searching a return a search representation of user which just contains the minimal set of properties required to identity a user. When fetching a specific user I return a complete business object.
Regarding your issue with code duplication. It is not duplication. Those different representations of a user have different responsibilities.
DTO: Responsible of transferring a user and creating a loose coupling between the business layer and the consumer
BO: Responsible of encapsulating and performing business operations
DB entity: Responsible of making the BO object persistent ignorant
Thus if you would use only one representation of a user you would merge all those responsibilities and therefore have to do sacrifices in good design to be able to use it everyone. The only really gain is that you have to write a few lines less code. Keep that in mind when you start to maintain the released application. You saved a few lines, but got a lot harder application to maintain.
Domain layers are communicating the other layers via Data Transfer Objects(DTOs). I confused about DTOs.
DTO 1 is between Domain and Presentation Layer.
DTO 2 is between Domain and Data Layer.
Should I create two different DTO objects between layers or only one DTO. Which is the proffesional way?
Lets go through all your layers:
Data Access Layer (DAL). It is used in order to get data from database (DB).
Usually it knows about Domain Entities and Domain Layer.
The DAL can return either Domain Entities or DTOs (DB oriented data structures). These DTOs or Domain Entities can be used in order to build DTOs of Presentation Layer (view models) if it is needed.
Domain Entities usually are heavy and require data mappers or any ORM. I prefer working with Domain Entities, map them and avoid other DTOs. Otherwise DTOs should be mapped also.
Domain Layer (Domain model). It is used in order to represent Business entities and their behaviour, business rules, pure business logic.
Domain Layer should know nothing about the way the entities are stored somewhere (e.g. in DB). It can have its own DTOs which can be results of refactoring Introduce Parameter Object.
Presentation Layer (UI). It is used in order to present UI to users.
It should know about Data Access Layer to load data from DB and about Domain Layer to have access to its business logic.
It can have its own DTOs - view models, which are user interface friendly representation of Domain Entities or DB friendly DTOs. It is responsibility of Presentation Layer to know about view models.
If you are going to have only one presentation your Application Infrastructure can be implemented as part of presentation layer also, but usually it is a separate Application Layer.
It really depends on your your specific needs.
In a general sense, you should create 2 sets of DTO's. This allows for better de-coupling of different layers and makes the architecture of your system more flexible. The specific reasons or cases where it is needed are for example:
Sharing DTO's may not be possible, e.g. because there are differences in technologies used, e.g. a web service and data layer are written in C# and the presentation layer is written in Java.
DTO's are not necessarily the same, i.e. your DTO for the interaction with the database layer may be modelled on the database structure but you may expose it differently to the presentation layer.
Having said that, if you can live with the limitations of having one set of DTO's, you can share them if it suits your needs as it produces less code to write and maintain.
Your image shows two DTO object named DTO1 and DTO2.
DTO1 is sharing data between presentation layer and domian layer. You can call them as ViewModel classes.
DTO2 is sharing data between domain and data layer. You can call them as Data Transfer Objects (DTOs).
So You can use two different transfer objects.
If we assume that you use two separated DTOs (DTO1 and DTO2),
answer is simple:
You must create two separate DTO in this case: DTO1 and DTO2.
Even if they are identical, they should be implemented as separated classes.
It is because DTO1 is created in Domain Layer but DTO2 is created in Data Layer (according to yor picture).
Note that in some solutions, two DTOs are not used - sometimes, there is only one DTO.
When creating a Business Model in which layer (GUI, BLL, DAL) entities class must be defined?
Your entities are a part of your Business Logic. In your entities you define your business rules.
They should be ignorant of the type of Data Access you use. This can be done by using the Repository pattern. In your BLL you define your Repository interfaces which act on your entities. In a separate infrastructure project, you will define an implementation for the Repositories.
If you pass your entities to your GUI is a matter of choice. Sometimes it can be beneficial to use special crafted classes for passing data to your view but in a small project you could opt for passing your entities directly to your GUI.
You can define it in two places
Either create a new Layer Model/Entities (preferred)
or
Define them in Data Access Layer
I would say: in their own layer. The GUI, the business layer and the data access layer all use the entities. But the GUI doesn't depend on the data access layer, and the data access layer doesn't depend on the service layer. So entities must be in their own domain layer.
It depends from the way you want to use your entity. If it's simple POCO object, that used as DTO from db to you application, so i think that best place will be DAL. If you want to use your entity like part of business logic and it has some functional - so BLL will be the best place. But I don't think that there are some cases when it should be used and defined in GUI
I think that it's a good practice to have an ViewModel for any GUI purposes. Because when you use EF than it means that you interact with SQL somehow (in most cases). So you data is normalized. For there other hand many times you need denormalized data for GUI. That why i prefer to use ViewModel for GUI.
I have an ASP.NET app with a three layer architecture:
Presentation layer: ASP.NET
Bussiness Layer: C# library.
Data Access Layer: C# library with
ADO.Net Entity Framework objects.
Some methods on Bussiness layer would return ADO.NET entity objects but, data access layer is not visible at Presentation layer I can't do that.
My question is: On a design view, Is it correct to expose Entity Objects in the Presentation Layer? I think I only have to link Data Layer library with ASP.NET app.
Thank you!
It's absolutely desirable to have your entity objects available for use and consumption in your presentation tier. That's what all the work is for.
Binding collection of objects to a grid/listview/dropdown
Splashing a single object (i.e. customer) onto a form for read/update/delete
This makes your life easier by far. Otherwise you'd have to pass string after int after double after string between your presentation and business layers.
These may be Entity objects or even your own POCO objects that were hydrated from the Entity objects.
I would even go so far as to say that your Entites should be in their own assembly separate from the DAL.
I suggest that you look into the concepts of View objects...or Data Transfer Objects (DTO). You might consider using a tool like AutoMapper or similar which will create a view specific domain object out of your entities. In general you may have screens that need an entity present to perform its work. But more often than not you will need to pass several different entities. In this case you are better off creating one DTO that contains all of these entities. By doing this you are adding a layer of separation between your presentation layer and your business layer. Often times your entities have more power than you might want to expose to your presentation layer. And...vice versa. Frequently you may need to get some UI messages out to the presentation layer based on some validation flagged in your business layer. Rather than make your ui more complex than it needs to be (by passing in your full entities) you can only pass in what the UI needs in the form of the DTO. Also, there is never a need for your business objects to care about anything specific to the presentation layer. I suggest that you not databind directly to anything as far back as the data access layer. Technically your presentation layer should know as little as possible about your business layer. In the case of MVP or MVC this is very easy to achieve by disconnecting the front end and the back end by way of this additional separation!
I think no, it is not, the best way to do that is to separate data classes from behavior, and reference only data classes in presentation level.The good approach I think to use WCF see this link
See Supervising Controller and Passive View
If you pass the Entity, you are essentially Supervising controller. Otherwise you are Passive View.
Supervising controller is less work, but less testable. Supervising Controller also says databinding is OK.
Passive view is testable but a LOT more work. No databinding. Lots of properties.
Typically I stick with Supervising Controller. You typically don't need that level of testability and it isn't worth the extra trouble.
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.