问题
I am trying to understand how to probably make use of a view model, a command and the database entity
At the moment I think there is a lot of manual mapping between this, and I am unsure if I should use a tool like AutoMapper to map ViewModel <-> Command <-> Entity
when there is a lot of properties (like 10-15).
Take this example (written quickly in notepad, may not compile - in my real applicaiton I use dependency injection and IoC):
public class Student {
public int Id { get; set; }
public string Name { get; set; }
public string AnoterProperty { get; set; }
public string AnoterProperty2 { get; set; }
public string AnoterProperty3 { get; set; }
public string AnoterProperty4 { get; set; }
public string AnoterProperty5 { get; set; }
public int StudentTypeId { get; set; }
public StudentType StudentType { get; set; } // one-to-many
}
public class CreateStudentViewModel {
public string Name { get; set; }
public DropDownList StudentTypes { get; set; }
}
public class DropDownList {
public string SelectedValue { get; set; }
public IList<SelectListItem> Items { get; set; }
}
public class CreateStudent {
public string Name { get; set; }
public int StudentTypeId { get; set; }
}
public class HandleCreateStudentCommand {
public void Execute(CreateStudent command) {
var student = new Student {
Name = command.Name,
StudentTypeId = command.StudentTypeId
};
// add to database
}
}
public class StudentController {
public ActionResult Create() {
var model = new CreateStudentViewModel {
StudentTypes = new DropDownList {
Items = // fetch student types from database
}
};
return View(model);
}
public ActionResult Create(CreateStudentViewModel model) {
var command = new CreateStudent {
Name = model.Name,
StudentTypeId = Convert.ToInt32(model.Items.SelectedValue);
};
var commandHandler = new HandleCreateStudentCommand();
commandHandler.Execute(command);
}
}
What worries me here is that I do a lot of manual mapping between the different parts. And this example only contains a few properties.
I am especially worried about a possible update command which will most likely contain all possible properties of the student entity.
Is there a neat solution, or should I go with AutoMapper and map from ViewModel <-> Command
and Command <-> Entity
?
回答1:
One possible way to deal with less classes and mappings / projections / conversions:
For all the views used in the WRITE-SIDE of your application (the views that allow the user to submit a form or so), let the Command to be their Model (View Model).
That is, you can have:
[HttpPost]
public ActionResult Create(CreateStudent command) {
commandHandler.Execute(command);
}
As for the get action, I see that you have to populate a drop-down list...
[HttpGet]
public ActionResult Create() {
// var model = create the view model somehow
return View(model);
}
Now, as for the model in the latter snippet, you may have these options (and perhaps others):
- let the Command object (CreateStudent) be the model of the view (as the view is a... view for a command, a view for a request) and pass the items for the drop-down using the ViewBag
- derive from CreateStudent command just to make of it a view model that can also hold the items for the drop-down
Notice that there is no need to add the suffix "Command" to your command object. Just give it a name that means doSomething - a verb phrase (verb + object) - and it should be fine.
In the end, some command objects really are the models for some views - no need to define another view-models for those and then have a lot of duplication etc.
Also, you may find these interesting:
- http://cqrs.nu/Faq
- http://cqrsjourney.github.io/
- https://github.com/mspnp/cqrs-journey-code/tree/master/source/Conference
来源:https://stackoverflow.com/questions/25054416/viewmodels-cqrs-and-entities