5

I'm wondering how to handle a ViewModel in the traditional sense, which includes both properties and methods, and another "view model" which is simply just the properties -- perhaps the ViewModel would return a this view "entity", or something.

Let me explain:

Domain Model:

public class Workout 
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string SomethingElse { get; set; }
    public List<Exercise> Exercises { get; set; }
    public DateTime CreatedDate { get; set; }
}

View Model:

public class WorkoutHistoryViewModel : IWorkoutHistoryViewModel
{
    private IWorkoutRepository workoutRepository;

    public WorkoutHistoryViewModel(IWorkoutRepository workoutRepository)
    {
        this.workoutRepository = workoutRepository;
    }

    // Here I'd like to return a slimmed down entity, not the full entity
    public IEnumerable<WorkoutHistoryViewEntity> GetExistingWorkouts()
    {
        return this.workoutRepository.GetList(); // some mapping logic
    }
}

And perhaps the desired "view entity" would just be:

public class WorkoutHistoryViewEntity 
{
    public int Id { get; set; }
    public string Name { get; set; }
}

I will also need to do something similar for, say, a WorkoutDetailsViewModel, which will require a different set of properties for its "view model", like:

public class WorkoutDetailsViewEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Exercise> Exercises { get; set; }
}

So, I guess the questions are:

  1. Am I doing MVVM all wrong? Should this ViewModel also have the desired properties on it? If so, then, when I do a GetExistingWorkouts(), am I really supposed to return a List<WorkoutHistoryViewModel>? In that case, I'd have a bunch of objects, all with repositories and methods, when really I just want the data.
  2. If I should create a third class, like the WorkoutHistoryViewEntity, what are these typically called (as ViewEntity doesn't really sound right).
3

You needn't worry about your ViewModels having more functionality than just providing data. That is, after all, their true function - to provide the data for display and any functionality required by the View. ViewModel's will normally contain properties, ICommands, at least one model and any references to services and repositories required to deal with modifications to the model.

In your case, your WorkoutHistoryViewModel will provide an ObservableCollection<WorkoutViewModel>, each of which has a Workout object as it's model.

so to answer your 2 questions:

  1. You're doing MVVM just fine. Don't worry about it seeming a little verbose - there's reasons for the separation. And almost all viewmodels will have some references to services as well as data.
  2. Don't create a "ViewEntity". Just create a ViewModel.
  • Mark, the idea to use WorkoutViewModel sounds good, but I want it to be a totally stripped down version for this History view, but then I need to use a different WorkoutViewModel for, say, a WorkoutDetails page, which will need many more properties than just the history list. – Tom Jun 24 '15 at 14:16
  • Tom, you don't really need a striped down ViewModel, you need a stripped down view. I'd suggest using one fully specc'd out, all bangs and whistles WorkoutViewModel in both cases but Lazy<> load the advanced properties for when they're needed in the details page. – Mark Green Jun 24 '15 at 14:22
  • Okay, I made this all work and it makes sense to me now. I was thinking each view could have it's own POCO to be mapped to, but that's overkill. Any view related to a workout exposes a WorkoutViewModel in it's own specific ViewModel – Tom Jun 24 '15 at 18:42
1

Returning a List<WorkoutHistoryViewModel> feels not as the way to go for me, even though it's done often. Your second option is better, and I think you got this quite right by intuition.

You are right though that WorkhoutHistoryViewEntity is not an appropriate name. It could mean almost anything. It's hard to find a name for the Id and the name because the first one is technical and the second one isn't. I assume here that the Id is unique and the name isn't. In this case, is there probably a way to either return only a list of names or a list of Ids? This could solve your problem, because I wonder if there is a good reason to return both information together. If there is a good reason, telling us might make it more easy to find a good name. Else you can also go with WorkoutIdAndName.

If both Id and name are unique, go with WorkoutReference or WorkoutIdentifier (and also use this class internal to store Id and an alias (here it would be the name)).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.