MVVM: Businesslogic is part of the ...? RRS feed

  • General discussion

  • Hi

    concering MVVM if have some question I actually should be able to answer my self,
    but there still is some unclarity.

    Which layer do we put the "BusinessLogic" in?
    Lets say project is a webshop, now a new customer is added.
    We need to validate all the input data, first formally, then app-specific.
    Whose job is it, Model, ViewModel, "depends" , both or "who cares"?
    Lets say the customer orders his first order, now there are quite are lot
    of jobs do do, write the data to DB, send some emails, notify the
    logistics, check if the goods are in store, etc pp.
    Most of it happens behind the scenes and has no representaion in the view.
    So it goes to the model? Or do we need an extra layer, the good ole controller, application layer?

    Should a view do any validation, for example simple and basic stuff such as checking numeric ranges
    spelling, casing, trimming. Or is the view supposed to be fully dead and passive - which is what i think?

    The VM:?
    Some say the VM is only a set of properties with INotifyPropertyChanged
    some say the VM replaces the controller and adds DataBinding.
    What actions is the VM supposed to execute, and is it "good programming style"
    to have lots of methods in your VMs (that are not delegates of some ICommand.Execute)
    Or are the VMs simply POCOs+INPC?

    The model:
    Is it just the entity of entities or also a place where the or part of the
    Businesslogic should be placed? The CRUD stuff is certainly part of the model!?
    Should a model do notifications upstream to the viewmodel?
    Or is just something considered to be solid and static?
    May it even implement INotifyPropertyChanged or ObservableCollection?
    I used to think that both are Big NoNos for the model, but
    there are some websides that recommend both for the model?
    Right, wrong, depends?

    Lets say we have some things that reflect the "current state"
    or "selected state" of our view (selected customer or selected order, for example)
    Lots of other things depend on the selected thing.
    To my point of view something that is solely part of the View and the VM,
    but never ever the model?
    This data it is not preserved (even it is stored to freeze and restore the view, its just a
    convenience thing), also a model should be able to handle multiple Views just the same way
    it handles a single one  - because it is not aware of any view at all.
    And from the point of view of the model it doesn't matter if an
    certain calculation is performed against a selected entity or
    one that is not selected or displayed at all. The model
    Just is interested in the data themselves.
    So all the "current" stuff is non-modelish. Right?

    Tuesday, March 6, 2012 9:02 PM

All replies

  • Basically, the way that I like to explain this is that your business logic and entities comprise the model.  This is what your specific application is using, but could be shared across many applications.

    The View is the presentation layer - anything relating to actually directly interfacing with the user.

    The ViewModel is basically the "glue" that's specific to your application that links the two together.

    I have a nice diagram here that shows how they interface: 


    In your case - lets tackle some of the specifics...

    Validation: This typically comes in 2 forms.  The validation related to user input would happen in the ViewModel (primarily) and the View (ie: "Numeric" TextBox preventing text from being entered is handled for you in the view, etc).  As such, the validation of the input from the user is typically a VM concern.  That being said, there's often a second "layer" of validation - this is the validation that the data being used matches the business rules.  This often is part of the model itself - when you push data to your Model, it may cause validation errors.  The VM will then have to remap this information back to the View.

    Operations "behind the scenes with no view, like writing to DB, sending email, etc": This is really part of the "Domain Specific Operations" in my diagram, and is really purely part of the Model.  This is what you're trying to expose via the application.  The ViewModel acts as a bridge to expose this information, but the operations are pure-Model.

    Operations for the ViewModel:  The ViewModel needs more than just INPC - it also needs any operation that are specific to your application (not your business logic), such as saving preferences and user state, etc.  This is going to vary app. by app., even when interfacing the same "model". 

    A good way to think about it - Say you want to make 2 versions of your ordering system.  The first is in WPF, and the second is a web interface.

    The shared logic that deals with the orders themselves (sending emails, entering into DB, etc) is the Model.  Your application is exposing these operations and data to the user, but doing it in 2 ways.

    In the WPF application, the user interface (what the viewer interacts with) is the "view" - in the web application, this is basically the code that (at least eventually) is turned into javascript + html + css on the client.

    The ViewModel is the rest of the "glue" that is required to adapt your model (these operations related to ordering) in order to make it work with the specific view technology/layer you're using.

    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Tuesday, March 6, 2012 9:15 PM
  • Hi Reed

    Well thanks a lot for your very comprehensive and detailed reply.
    Really helped to shed some light into most if not all of mvvm's twilight zones.
    And more over: Having a nice diagram for the meeting &
    presentation today actually saved my day :-).

    I have one special question left.
    Sometimes separating the UI from ViewModel
    turns into an acrobatic exercise.
    E.g. opening a dialog window through a command.
    Since the ViewModel shall not have any knowledge of the
    view (in terms of referencing it or reference WPF UI assemblies (shouldn't it?))
    we will probably won't hardcode something as:

    ICommand _openConfigDialogCommand = new RelayCommand(param => new ViewLayer.ConfigWindow(). ShowDialog ());
    as a VM-Command property.

    So how to open a window from the viewmodel?
    Simply ignore the VM and open the window from the view's code-behind in Button_Click?
    Pass some opener-delegate or interface as the CommandParameter?

    Thanks again for the great reply,

    Wednesday, March 7, 2012 11:58 AM

  • So how to open a window from the viewmodel?
    Simply ignore the VM and open the window from the view's code-behind in Button_Click?
    Pass some opener-delegate or interface as the CommandParameter?

    There are a few different approaches here, but they all center on one basic precept - you shouldn't think of it as "opening a window from the ViewModel" as much as the ViewModel deciding to do some "action", and the View responding as opening a window.

    Take a classic example - prompting for user input.  This often requires opening some form of modal window with a separate interface for the user to input information, etc, and then a way to retrieve that information.  From the VM's point of view, this really doesn't need to have anything to do with "opening a window" as much as "retrieving information from an outside party".

    In this case, what I do (there are various approaches here) is typically make some form of service to handle this, and use DI to add it to my VM.  For example, I may have an IPromptService interface, and inject this into my VM, and then, when the VM needs to "prompt" the user, it can just create the appropriate ViewModel for the information, and use IPromptService.Display(thePromptVM);.  DataTemplates work to provide an appropriate view for that VM in WPF, and things just work.  Of course, for the WPF side, it means making a "class WindowPromptService : IPromptService" that handles this by creating a window with a content presenter bound to the specified VM, and often including another interface the VM must implement (ie: to be able to notify of completion, etc).  However, it completely decouples all of the logic from the presentation - you can reuse the same exact VM in SL for Phone, or WinRT, etc - only the prompting mechanism (the service) changes.

    There are other approaches that are similar - such as using a messaging service (like MVVM Light) to "broadcast" a request to show information, etc - but the idea is the same.  You try to design your VMs without worry about how the information will be retrieved - only focus on what specific data you need.  The View Layer handles presenting your VM appropriately and returning the data.

    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Wednesday, March 7, 2012 5:13 PM
  • Showing a windows is a problem unless you want info back from it.

    Laurent Bugnion addresses this very issue in a video, explaining the use of MVVM light.


    Wednesday, March 7, 2012 5:38 PM
  • Thanks all for the excellent discussion!

    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us

    Friday, March 9, 2012 1:22 AM