Mikhail Orlov
Mikhail Orlov

Reputation: 2857

A few general questions about Service Reference and MVVM pattern

There is a web service.

So the idea is - GetZoo allows me to get a list of animal ids + names, and then GetAnimalStuffById fetches full animal info.

I add a "service reference" to that service in VS and want to write a MVVM app. Some things I don't fully understand and need to be brainwashed about.

  1. Is it OK for autogenerated classes to be my models?

  2. Not related to the example, but anyway: what "collection type" should I specify when adding service reference? Is ObservableCollection an overkill and a bad practice for models?

  3. Say, user goes to an application page showing full animal info. Obviously, initially I have an AnimalViewModel with only Id and Name values (taken from GetZoo). As the page is navigated to, I call GetAnimalStuffById and get an Animal object with all the data. What should I do next? Replace the DataContext of my view with a new AnimalViewModel created from new Animal object (A), or just replace the values in it (B)?

  4. If the answer is (A), how do I replace the DataContext in all the views?

  5. If the answer is (B), what should cause that update? Should the VMs subscribe to some fancy manager's event about getting an Animal update? Or is there some other approach?

  6. What is the purpose of INotifyPropertyChanged in the autogenerated classes? They are always returned fresh from the webservice in my case. Does Microsoft suggest to use them also as ViewModels in some scenarios?

Thanks.

Upvotes: 2

Views: 331

Answers (2)

Cameron MacFarland
Cameron MacFarland

Reputation: 71856

And here's answers based on my experience (mainly to provide another point of view)

  1. It's fine to autogenerate Models from an endpoint. But I would recommend POCO Models without any INPC cruft. Two reasons, a) it makes the Models simpler and easier to maintain and b) You won't be tempted to expose your Models directly to the View, or if you do they won't work properly.

  2. Continuing on from #1, I would not use ObservableCollection in Models. Again to keep things simple and to avoid presenting Models directly to the View.

  3. Option (B)

  4. -

  5. All the properties in the ViewModel should implement INPC. Then when you change them the binding will automatically update. You can either have all the AdditionalData values as properties of your AnimalViewModel which is flattening the data, or you can have an AdditionalDataViewModel object to hold the extra data. To map data from an AdditionalData object to AdditionalDataViewModel consider using a mapping tool like AutoMapper or ValueInjecter.

  6. I don't know why the autogenerator added INPC stuff into your models. What tool are you using? In any case as I've said I do not recommend having INPC in Models, or exposing Models to the View. Instead you should be mapping from Models to ViewModels and only exposing ViewModels to the View.

Upvotes: 1

Sphinxxx
Sphinxxx

Reputation: 13017

Here are a few answers based on my own experience with MVVM (which may or may not be "best practice"..)

  1. Absolutely! No need to do everything twice - see #5 and #6 (although there are people who disagree here).

  2. Yes, unless you actually need the functionality of an ObservableCollection server-side, I would say it's overkill, and possibly confusing to others. Techincally, there's no overhead to the messages being sent across the wire, but I would go with something simpler, like an array.

  3. Go with option B.

  4. -

  5. For example, you could have a single property in your AnimalViewModel to hold all the additional stuff: public Animal AdditionalData { .... Now, whoever calls GetAnimalStuffById can just update the current ViewModel's AdditionalData with that Animal object.

  6. I assume you already know that INotifyPropertyChanged is there to let the View know that some data has changed somewhere (if not, googling "inotifypropertychanged mvvm" should get you started). Now, connecting the dots from #1 and #5, your View can now bind to the animal's additional data by going through the AdditionalData property without having to recreate everything in the ViewModel: <TextBox Text="{Binding Path=AdditionalData.HeightOrWhatever}" />.

Note: If your View isn't WPF or Silverlight, that last point won't make much sense..

Upvotes: 1

Related Questions