I have an MVC app divided into the usual layers: MVC presentation layer, Business Logic, and Data Access Layer.
In the MVC app I have a search form. It's a complex one - lots of checkboxes, radios, dropdowns and text fields. When the开发者_运维知识库 user submits the form I create an "EditModel" (ActionModel?) object in the Controller that contains a set of properties encapsulating the form.
The DAL needs to use the properties in this object to construct a query that returns the right results based on the user's selection.
What is the best way of passing this through to the DAL (which obviously has no reference to the MVC project). Is it to create a DTO which is exactly the same as the EditModel (ActionModel?) , just for the purposes of passing it from MVC -> BLL -> DAL? Are there any better ways?
If the object would truly be "exactly the same," why wouldn't you just use it in the BLL and DAL? It would make sense to have an assembly referenced by both the model and the BLL (and DAL).
Make a core / domain / bll representation out of your view model. I use mappers for this. In this example the controller would use IGuestDetailsMapper
public interface IViewToDomainMapper<TModel, TViewModel>
{
/// <summary>
/// Map presentation model to domain model. If message has a key it will first be loaded (edit mode).
/// </summary>
/// <param name="message">presentation model</param>
/// <returns>domain model</returns>
TModel MapViewToDomain(TViewModel message);
}
public interface IGuestDetailsMapper : IDomainToViewMapper<LoginContact, GuestDetailsForm>
{
}
If you use a form object, it often isn't EXACTLY the same as a core object because you might find you are adding validation / ui display label attributes or other bits and pieces that don't need to be in your domain model.
Another way to avoid creating a new object (if you really need to) but still have separation from the view model is create an interface mirroring the view model's properties you are interested in for your search, and apply it to your view model.
Then make the parameter type in your search method of the Interface type, and you can use the view model directly then.
精彩评论