NickD wrote:
jeffreygg wrote:
The one problem with this approach, however, is the temptation to treat the entity classes as having an instrinsic meaning or purpose. It is instinctive to want to aggregate your process's data in an entity hierarchy and pass it to a service for execution, but the entity classes themselves have no indication of their use for any particular purpose, in this case as the minimum set of data required to execute the process. There is no way to know which data is required in order to meet the service's requirements as the entities are simply Data Transfer Objects, no more.
I'm making these decisions right now, so I'm glad to have found this thread. I'm curious to know what you do then, if you do not pass the entities back to the BL? Maybe I'm not understanding your post correctly, but let me present a scenario and you tell me what you see as potential pitfalls. Let's say we have a datagrid whose DataSource is an EntityCollection of EmployeesEntity. The user edits the employee's last name and clicks update in the grid. How would you go about saving that change? Would you call a single method in your BLL that is "SaveEntityCollectionChanges(myEntityCollection)" or would you simply call the DataAccessAdapter.SaveEntityCollection(myEntityCollection) inside of your UI? Or would you do something else? Both of my ideas feel like I'm missing something, so clue me in.
Well, in order to validate properly at the business layer, you need to have endpoints that have a semantic meaning. For example, in your case, you might expose a "SaveEmployeesBulk()" method. From this perspective, the argument passed in is important as it is within the the user's expectations are set as to what's required. In the save employees case, this may not be important, but consider a different scenario:
Purchase Orders have line items which reference vendor's catalog items which reference internal catalog items. If I have a "SavePO" method that takes in a PurchaseOrderEntity, which possibly contains within it's object graph the PO Line Items, the Vendor Items, and the Internal Items, how do I know what's being communicated to me if the PurchaseOrder.POLineItems collection is empty? Does that mean there are no changes? Does it mean that all of the line items should be deleted? How do I validate that object graph, especially the PO line items, when there is no inherent, intrinsic meaning to it as it's just simply a DTO? How does the caller know what to populate the Purchase Order with?
As a means of communicating data, the entities are beautiful; as a means of communicating intention or meaning they suck, because that's not what they were intended for.
All of that being said, however, if you're a single developer or on a small team with good communication, this all may be unimportant. However, if reuse is important at the business layer level you may want to reconsider using entities to communicate to your business layer.
Jeff...