關於服務參考和 MVVM 模式的幾個一般問題 (A few general questions about Service Reference and MVVM pattern)


問題描述

關於服務參考和 MVVM 模式的幾個一般問題 (A few general questions about Service Reference and MVVM pattern)

There is a web service. 

  • It provides types Zoo and Animal.
  • Zoo has a dictionary of animal ids and names.
  • Animal has properties: IdName and (additional stuff).
  • It has a method GetZoo that returns a zoo object.
  • It has a method GetAnimalStuffById that returns an Animal object with IdName and the (additional stuff).

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.

‑‑‑‑‑

參考解法

方法 1:

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. 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.

  5. 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..

方法 2:

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. 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.

  5. 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.

(by Mikhail OrlovSphinxxxCameron MacFarland)

參考文件

  1. A few general questions about Service Reference and MVVM pattern (CC BY‑SA 3.0/4.0)

#mvvm #visual-studio-2012 #web-services #wcf






相關問題

WPF View 在關閉時將 ViewModel 屬性設置為 null (WPF View sets ViewModel properties to null on closing)

在文本框中正確輸入後啟用按鈕 (Button Enable After Correct Input In TextBox)

WPF說數據項不為空時為空 (WPF says that data item is null when it is not null)

MVVM - 如何將 ViewModel 包裝在 ViewModel 中? (MVVM - How to wrap ViewModel in a ViewModel?)

關於服務參考和 MVVM 模式的幾個一般問題 (A few general questions about Service Reference and MVVM pattern)

WPF MVVM 鏈接視圖 (WPF MVVM Linked Views)

wpf 樹視圖 mvvm (wpf treeview mvvm)

如何在 MVVM Light 的 ListView 中的 ComboBox 中顯示列表? (How to show a List in a ComboBox in a ListView in MVVM Light?)

多次調用 PropertyChanged 的 ViewModel 屬性 (ViewModel properties with multiple calls to PropertyChanged)

如何將圖像存儲在類庫中並從任何類訪問它 (How can i store an image in a class library and access it from any class)

Silverlight MVVM 隔離存儲 (Silverlight MVVM Isolated Storage)

如何將文本框的borderBrush屬性綁定到viewmodel中的屬性,類型轉換錯誤 (How to bind the borderBrush property of a textbox to a property in viewmodel, type conversion error)







留言討論