Re: N-Tier and passing data
Your DAL will retrieve the data from the persistence layer in some specific form, e.g. DataTables or EF entities. It will pass the data up the BLL in that form. As such, both the DAL and BLL have to understand that form. If you're using an EF model or the like then it should be defined in a separate assembly that both the DAL and BLL projects reference. The BLL will then convert the data to DTOs, which contain nothing but the data. Because they are as simple as possible, they are as efficient as possible for passing to and from a web service, which your BLL will often be. The UI then receives the data from the BLL as DTOs. Because both the UI and BLL must understand those types, they must be defined in a separate assembly that both the UI and BLL projects reference. The UI then might transform the data again into a form required for display to the user, i.e. a view model, or it may just use the DTOs as they are.
On the reverse journey, the UI maps the data from view models to DTOs if required and passes the DTOs to the BLL. The BLL then converts the DTOs to EF entities or whatever and passes them to the DAL, which sends them to the persistence layer. The mapping between entities and DTOs and back again can be handled by a tool like AutoMapper to reduce the amount of tedious code required. The same approach can be used between DTOs and view models.
Re: N-Tier and passing data
Many thanks. I thought as much and just needed to unconfuse myself with what people are doing wrongly and "deep" thinking into it.
But lets say we arent using EF - just custom objects like Customer or Order. This pretty much would be the DTO that all layers would understand because the DAL would construct the objects being read from the DB, the BLL would request the DAL for this (like GetCustomerById), the BLL then returns this object back to the UI to be bound to the view/page (either web, MVC or winforms). Would this not be true?
what would the difference then be between DTO and ViewModel? Surely the DTO is the viewmodel when we are talking about the context of the UI?
Happy Holidays
Re: N-Tier and passing data
You could use the DTOs end to end but then how will you implement validation? It would need to be completely manual in that case. Like I said, DTOs should be nothing but the data. To make things neater, it's a good idea to use attribute-based validation, either on the back-end entities or the front-end view models or both. If you put validation attributes on DTOs then they cease to be true DTOs. If you want to go that way then that's your choice but it would not be best practice. At my office we do some work for the NSW Ministry of Health and they have a development framework and application management system where their original standard was to use the Microsoft Enterprise Library to decorate NHibernate entities with validation attributes while we tended to EF at the back-end and we used view models decorated with Data Annotations attributes to allow client-side validation in MVC apps.
Re: N-Tier and passing data
right. I wouldnt do validation on the DTO at all. I would do the validation at the BLL or the UI layer. UI for input before it being converted to a DTO and further validation at the BLL layer before finally doing the thing it needs to do.
I agree with the attributes for validation but then it depends on your business domain validation. its a good idea to do the attributes validation for just that - input validation. But then it means doing 2 things here on the UI layer:
1) create a viewmodel which has properties from the input and do validation here
2) once validation succeeds, to convert the viewmodel to a DTO (which contains just data) and pass that to the BLL which in turn eventually passes it to the DAL.
just to be clear, that is what I use for MVC based apps which is a great way. But what if we werent using MVC? but instead classic web forms (ASP.NET) or maybe even winforms? What if we didnt want to use this approach in MVC but wanted a one size fits all approach?
what is the best practice here really? One way or another, all layers concerned need to agree on a level of understanding in terms of the objects/entities to be passed to and from. DTO is the way sure but then it kind of contridicts the validation aspect you rightfully raised.
but one thing is cleared for sure - to pass data from UI to DAL, put it in a DTO object if we have multiple inputs from the UI or just a single input from the UI if it is a non complex type.
hmm. clusterf*** :)
Re: N-Tier and passing data
There is no one-size-fits-all approach. The presentation layer is going to be different for each type of application, which is the whole point, so each presentation layer will do what's appropriate for itself. For an MVC app it is appropriate to use Data Annotations on custom view models. Those view models would generally just be copies of the DTOs with the appropriate attributes added. I've done very little Web Forms work myself but I would think that you would do the same thing to support client-side validation. For WinForms you might handle Validating events and then hand the actual validation off to a dedicated class that was written to work with Data Annotations.
Note that it would always be a good idea to have validation supported at the back-end entity level whether you implement it at the front-end view model or not. If you want to provide some automated tool at some point, that would bypass your UI and therefore any view model validation.
Note that client-side validation is most important when you're talking about a web app, because your app will be more responsive if you can do validation in the browser than on the server. You may not want to do validation in the browser though, plus there could be some more complex validation that must be done on the server. If your BLL is behind a web service, performing validation on the back-end entities exclusively becomes less attractive because of the time and traffic involved in pushing data down that cannot be persisted. If a web site or Windows app invokes the BLL via a web service, performing validation in the web site or Windows app will make validation failures more efficient.
Re: N-Tier and passing data
Right. thank you once again for the great information :) Really appreciate it.
so many ways and I know there is no one size fits all approach but would hope there somewhat is a guideline of some kind to use throughout the different platforms of solution.
So I guess with the standard webform app, it would be a good idea to use the MVC approach where we have viewmodels with validation methods on them and a DTO transition to and from the BLL with that viewmodel where it will pull out the properties it needs to construct the DTO after successful validation.
Then when obtaining data, we construct the DTO from the DAL, passed back to the BLL then finally the UI layer will convert that to a viewmodel and bind it to the UI.
Re: N-Tier and passing data
The BLL is basically the heart of your application so the app should still work in basically the same way if you swap out the UI or the DAL. That's why validation on the back-end entities is important. If there is no actual UI and the BLL is invoked by an automated tool then you still have all the validation in place. If you're going to have validation attributes on your back-end entities and front-end view models, that means that the only place for DTOs is between the BLL and the UI.
Re: N-Tier and passing data
right, which is why i said earlier that you could do the validation at the BLL layer and return back some form of a response object which contains the DTO object which failed the validation. Then the UI can convert that into a ViewModel along with binding the validation error message from the BLL :)
seems overly killed in terms of DTO to ViewModel and viceversa
Re: N-Tier and passing data
So classic ASP.NET does not support things like binding from DTO to UI and vica versa. Sure you could create a method which uses reflection to bind the properties of an object to a control/container but performance would be the problem (# of controls could vary but also reflecting the type of object and so on).
Means that you do have to manually bind from DTO to ViewModel, then from ViewModel to the actual controls on the page themselves and the other way around after postback.
hmm.
Re: N-Tier and passing data
I'm afraid I can't really help with too many details where Web Forms is concerned because I've done very little work in that area and none recently.
Re: N-Tier and passing data
no worries. Thank you :)
going back to an earlier post of yours, you say validation on back end entities - can you elaborate on that please? What exactly do you mean?
Re: N-Tier and passing data
I mean the EF entities or equivalent. The service layer receives the data from the presentation layer and transfers the data from DTOs to back-end entities and validation is performed primarily via attributes decorating the properties of those entities. If the data passes validation then the service layer passes it on to the data access layer for persistence, otherwise the appropriate error information is passed back to the presentation layer.
Re: N-Tier and passing data
I see...I think it was a terminology thing.
I always do my validation on the UI before it being transferred down the chain. My DTO are really entities constructed from the DB and only contain data needed and nothing else.
For example I wouldn't pull customer and all their addresses unless the UI needed it. then when user edits the addresses, it takes that and converts it into the DTO entity, along with custID, to the BLL, after validation, then off to the DB.
sounds right?
Re: N-Tier and passing data
I addressed this in an earlier post. Yes, do the validation at the UI in a web app or the like for efficiency but, if you want to be able to use the same service layer and data access layer in an automated tool then you don't have a UI so it's appropriate to use the entities to perform the validation. You said that you wanted the most general solution and that's part of it.
Re: N-Tier and passing data
Thanks. Sure I understand.
This then leads to another question - when you are talking about automated tests or systems where there is no UI And validation needs to be done (at the BLL). What kind of response would you return back to the caller if the validation failed? And if it didnt fail then how would you return back the result of that operation?
For example, would you have a Response object in the context of UpdateCustomerDetials which has:
ValidationErrors collection, which is null if operation is a success or if not a success then a collection of the errors
CustomerDetails object which contains Customer object containing the updated details after the update from the DAL/DB and ValidationErrors is null
what do you do with your scenarios? :)
Re: N-Tier and passing data
Re: N-Tier and passing data
thanks. good - at least I am not totally insane :)