Coffeehouse Thread

28 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

MVVM

Back to Forum: Coffeehouse
  • User profile image
    spivonious

    Anyone using this pattern? I think I understand the idea behind it, but I think that in most projects it's overkill to separate the ViewModel from the View.

    I can definitely see the benefit from a unit testing standpoint though. It also doesn't seem to mesh well with Datasets, which I'm forced to use because of our Oracle backend. The project isn't complex enough to benefit from me spending time coding custom business objects.

  • User profile image
    JohnAskew

    Put the DataSets inside the ViewModel --

    More and more adopt this pattern. It is the best way to provide test coverage and portablity of code, imho.

    There are a lot of different takes on the finer aspects of MVVM, you should check out fellow member wkempf 's blog http://wekempf.spaces.live.com/default.aspx and sacha barber's too http://sachabarber.net/

    Don't forget P&P's MVVM WPF/Silverlight composite framework http://compositewpf.codeplex.com/  (a.k.a. Prism)

  • User profile image
    bitdisaster

    I use it in my current SL project. It's not so much work and you avoid a messy code behind file. Another benefit is that your UI is "blendable" and you can easily provide dummy data for your designer.

  • User profile image
    vesuvius

    JohnAskew said:

    Put the DataSets inside the ViewModel --

    More and more adopt this pattern. It is the best way to provide test coverage and portablity of code, imho.

    There are a lot of different takes on the finer aspects of MVVM, you should check out fellow member wkempf 's blog http://wekempf.spaces.live.com/default.aspx and sacha barber's too http://sachabarber.net/

    Don't forget P&P's MVVM WPF/Silverlight composite framework http://compositewpf.codeplex.com/  (a.k.a. Prism)

    I'm not so sure. I am now a full time WPF developer of sorts, and naturally I have a few pet projects in the pipeline. Coming from Windows Forms, I feel I could do the projects quicker and better but have stuck with WPF.

    Recently I reviewed fully i.e. did the actual code sample of Josh Smiths famous article rather than blog about it. I then had to decide whether to use the Entity Framework, and that was a resounding no because you have to create a POCO mapping to an ORM. Very stupid of the EF team, but this is addressed in VS 2010 (Guys a lot of WPF code has been written now and this is an oversight that ought not to have have happened)

    The natural replacement is Linq, but that is now no longer in development which negates my (or anyone with any sense) election of it for a large project requiring maintenance, but it is the lesser of the two evils.

    If you are going to use MVVM or MVP, then you may as well use Prism with the bootstrappers, Unity, Regions and Eventing. MVVM is great for testing, but in the real world that is only one minute aspect, people tend to forget that!

    The only real issue is if you look at Josh Smith's article, however simple it might look, it actually is a very complicated bit of code. Not without its drawbacks, especially around exception handling.

    I also think it completely wrong to use MVVM with a disconnected dataset, as that has all your change tracking already in it, only to create a POCO representation inheriting ObservableCollection. That is just plain wrong.

    In general the dataset you return is your model-view, and passing that as a data context object in the "Window's" constructor and calling TableAdapterManager.UpdateAll() is in some ways just as eloquent as MVVM. It's just that datasets are passe, but they do cut out a lot of ceremony with WPF and the MVVM. I would say use MVVM with ORM's only.

  • User profile image
    JohnAskew

    vesuvius said:
    JohnAskew said:
    *snip*

    I'm not so sure. I am now a full time WPF developer of sorts, and naturally I have a few pet projects in the pipeline. Coming from Windows Forms, I feel I could do the projects quicker and better but have stuck with WPF.

    Recently I reviewed fully i.e. did the actual code sample of Josh Smiths famous article rather than blog about it. I then had to decide whether to use the Entity Framework, and that was a resounding no because you have to create a POCO mapping to an ORM. Very stupid of the EF team, but this is addressed in VS 2010 (Guys a lot of WPF code has been written now and this is an oversight that ought not to have have happened)

    The natural replacement is Linq, but that is now no longer in development which negates my (or anyone with any sense) election of it for a large project requiring maintenance, but it is the lesser of the two evils.

    If you are going to use MVVM or MVP, then you may as well use Prism with the bootstrappers, Unity, Regions and Eventing. MVVM is great for testing, but in the real world that is only one minute aspect, people tend to forget that!

    The only real issue is if you look at Josh Smith's article, however simple it might look, it actually is a very complicated bit of code. Not without its drawbacks, especially around exception handling.

    I also think it completely wrong to use MVVM with a disconnected dataset, as that has all your change tracking already in it, only to create a POCO representation inheriting ObservableCollection. That is just plain wrong.

    In general the dataset you return is your model-view, and passing that as a data context object in the "Window's" constructor and calling TableAdapterManager.UpdateAll() is in some ways just as eloquent as MVVM. It's just that datasets are passe, but they do cut out a lot of ceremony with WPF and the MVVM. I would say use MVVM with ORM's only.

    There is no need to create a POCO mapping of a DataSet that is a member variable within a ViewModel, is there?

    If the DAL hands you a ready made datatype, be it ADO Entity or a DataSet, why not use it in the ViewModel?

    The ViewModel is, among other things, a land of normalizing data for UI consumption, so you can resurface the DataSet as a property from the ViewModel and bind the UI directly to it. Regardless of any protests, you've insured proper seperation of concerns of UI and non-UI. If there is some business logic to perform on the data within the DataSet, you have it in your ViewModel read for processing...

    Prism does have major plumbing ready to use, but sometimes it is also overkill for smaller applications. It is for composite applications, like those sporting plug-in architecture and painless deployment.

    I would not hesitate to use a ViewModel class for the most mundane and small applications for the purpose of building a good habit as well as adding quality to your code via unit testing and re-use portablility. 

  • User profile image
    wkempf

    vesuvius said:
    JohnAskew said:
    *snip*

    I'm not so sure. I am now a full time WPF developer of sorts, and naturally I have a few pet projects in the pipeline. Coming from Windows Forms, I feel I could do the projects quicker and better but have stuck with WPF.

    Recently I reviewed fully i.e. did the actual code sample of Josh Smiths famous article rather than blog about it. I then had to decide whether to use the Entity Framework, and that was a resounding no because you have to create a POCO mapping to an ORM. Very stupid of the EF team, but this is addressed in VS 2010 (Guys a lot of WPF code has been written now and this is an oversight that ought not to have have happened)

    The natural replacement is Linq, but that is now no longer in development which negates my (or anyone with any sense) election of it for a large project requiring maintenance, but it is the lesser of the two evils.

    If you are going to use MVVM or MVP, then you may as well use Prism with the bootstrappers, Unity, Regions and Eventing. MVVM is great for testing, but in the real world that is only one minute aspect, people tend to forget that!

    The only real issue is if you look at Josh Smith's article, however simple it might look, it actually is a very complicated bit of code. Not without its drawbacks, especially around exception handling.

    I also think it completely wrong to use MVVM with a disconnected dataset, as that has all your change tracking already in it, only to create a POCO representation inheriting ObservableCollection. That is just plain wrong.

    In general the dataset you return is your model-view, and passing that as a data context object in the "Window's" constructor and calling TableAdapterManager.UpdateAll() is in some ways just as eloquent as MVVM. It's just that datasets are passe, but they do cut out a lot of ceremony with WPF and the MVVM. I would say use MVVM with ORM's only.

    Hmm... lots in that post, while not giving enough "meat" to fully grok what you're saying.

    In general, it seems your complaint is with EF and LINQ to SQL (not Linq as you said, because Linq is most certainly still under development), for various reasons.  Neither is relevant to MVVM, really.  Personally, I rarely do DB development, so my models don't come from an ORM. And, as you say, some ORMs don't have the issues you find in EF and LINQ to SQL, not to mention EF in 4.0 should address any of your concerns.

    I'll agree that using the DataSet directly is problematic, but depending on many variables not presented here (need to bridge legacy code and size of application are a few things that come to mind), it may well be the best solution.  For those of us not using DBs, it's common to have to hand code various adapters for legacy APIs anyway, and MVVM is STILL a majorly useful pattern.

  • User profile image
    wkempf

    Just because you're backend is an Oracle DB doesn't mean you have to use DataSets.  NHibernate would work well as a replacement.  Regardless, though, I don't see this as being a reason to not use MVVM.  If you do it the "traditional WPF way" using the code behind, you still do data binding to the DataSet.  What difference does it make if the DataSet is exposed in the code behind or in a ViewModel?

    Coding ViewModels is a little more complex than doing code behind.  Especially in certain areas that everyone runs into when first starting out, like event handling, focus control and other similar concepts.  However, there's solutions to these if you utilize an MVVM framework, and learn to use the MVVM triad: commands, attached behaviors and services.  Everyone has their own command infrastructure, but the best to look at if you don't know about this already is the DelegateCommand in Prism.  Attached behaviors were an old school pattern for leveraging attached dependency properties to modify a controls behavior by listening to events and modifying properties in response. This has recently been made more reusable and toolable with the advent of Blend Behaviors, though I think the old school pattern is still something to leverage from time to time. Services are the final "silver bullet" and you just need a way to provide services to the ViewModel.  Onyx (disclaimer: I'm the author, and it's still alpha quality code at best), which you can find at http://wpfonyx.codeplex.com, provides ONE solution to that.

    After a while, it's generally just as easy to code using MVVM is it is to code using "code behind spaghetti", while giving you all the benefits of decoupling (especially being able to test).  You'll still run into things that take a while to devise the "best" solution using one of the MVVM triad concepts, but really, that's true of any code you right. And like any such issue, you code it once, and then have a new tool in your belt for the next time.

  • User profile image
    spivonious

    JohnAskew said:
    vesuvius said:
    *snip*

    There is no need to create a POCO mapping of a DataSet that is a member variable within a ViewModel, is there?

    If the DAL hands you a ready made datatype, be it ADO Entity or a DataSet, why not use it in the ViewModel?

    The ViewModel is, among other things, a land of normalizing data for UI consumption, so you can resurface the DataSet as a property from the ViewModel and bind the UI directly to it. Regardless of any protests, you've insured proper seperation of concerns of UI and non-UI. If there is some business logic to perform on the data within the DataSet, you have it in your ViewModel read for processing...

    Prism does have major plumbing ready to use, but sometimes it is also overkill for smaller applications. It is for composite applications, like those sporting plug-in architecture and painless deployment.

    I would not hesitate to use a ViewModel class for the most mundane and small applications for the purpose of building a good habit as well as adding quality to your code via unit testing and re-use portablility. 

    I've looked at the code for the infamous Josh Smith artice in MSDN magazine and am having trouble seeing how a Dataset could be worked into the ViewModel.

    Is there a good example out there that ties a Dataset with the MVVM pattern?

    I took a quick look at NHibernate, but I'd rather stick with libraries that are part of the Framework, at least until I get a handle on MVVM.

  • User profile image
    wkempf

    spivonious said:
    JohnAskew said:
    *snip*

    I've looked at the code for the infamous Josh Smith artice in MSDN magazine and am having trouble seeing how a Dataset could be worked into the ViewModel.

    Is there a good example out there that ties a Dataset with the MVVM pattern?

    I took a quick look at NHibernate, but I'd rather stick with libraries that are part of the Framework, at least until I get a handle on MVVM.

    Like I said, this is data, and data is handled the same whether it's done from MVVM or the code behind.  To make it more concrete, your ViewModel would expose the DataSet, and the View would data bind to it.

  • User profile image
    JohnAskew

    spivonious said:
    JohnAskew said:
    *snip*

    I've looked at the code for the infamous Josh Smith artice in MSDN magazine and am having trouble seeing how a Dataset could be worked into the ViewModel.

    Is there a good example out there that ties a Dataset with the MVVM pattern?

    I took a quick look at NHibernate, but I'd rather stick with libraries that are part of the Framework, at least until I get a handle on MVVM.

    ViewModels are "always" the View's DataContext, so a property in the ViewModel will be bindable to the View's controls. One of those properties is your DataSet.

    If you use the designer to build the DataSet, save it and then have the ViewModel create the same DataSet programmatically - remember you're seperating from the View, which also means not relying on the designer for managing the DataSet schema, etc.

    Does this make sense to you V?

  • User profile image
    spivonious

    I found this blog post which builds a very basic MVVM app around a DataSet. It still seems like an unnecessary separation to me, but it does make the code more structured.

    http://wesaday.wordpress.com/2009/02/13/mvvm-in-wpf-part-ii/

    John - the DataSet designer isn't part of the applications View...I'm confused as to why yout think I'd need to create everything in code.

  • User profile image
    JohnAskew

    spivonious said:

    I found this blog post which builds a very basic MVVM app around a DataSet. It still seems like an unnecessary separation to me, but it does make the code more structured.

    http://wesaday.wordpress.com/2009/02/13/mvvm-in-wpf-part-ii/

    John - the DataSet designer isn't part of the applications View...I'm confused as to why yout think I'd need to create everything in code.

    Create everything in code is one way to insure the ViewModel requires no assistance from a designer, more testable & portable.

    Unit tests don't involve any UI elements, just instantiate the ViewModel and mock or stub data for it ~ the DataSet schema needs be readied for this one way or another -

  • User profile image
    spivonious

    spivonious said:

    I found this blog post which builds a very basic MVVM app around a DataSet. It still seems like an unnecessary separation to me, but it does make the code more structured.

    http://wesaday.wordpress.com/2009/02/13/mvvm-in-wpf-part-ii/

    John - the DataSet designer isn't part of the applications View...I'm confused as to why yout think I'd need to create everything in code.

    Okay, I think I have a basic MVVM app working. Here's how it's set up:

    Model - for this I just used the strongly-typed DataSet class. I added methods to support my commands directly to the class file.

    ViewModel - this contains an instance of the DataSet and properties matching up to all of the tables in the DataSet, as well as instances of Josh Smith's RelayCommand.

    View - this is standard XAML with zero code-behind. I added <Window.DataContext><MainViewModel/></Window.DataContext> to the XAML, getting rid of the need to set the datacontext in code.

    Did I do things right? This will at least get me table-level abstraction.

  • User profile image
    wkempf

    spivonious said:
    spivonious said:
    *snip*

    Okay, I think I have a basic MVVM app working. Here's how it's set up:

    Model - for this I just used the strongly-typed DataSet class. I added methods to support my commands directly to the class file.

    ViewModel - this contains an instance of the DataSet and properties matching up to all of the tables in the DataSet, as well as instances of Josh Smith's RelayCommand.

    View - this is standard XAML with zero code-behind. I added <Window.DataContext><MainViewModel/></Window.DataContext> to the XAML, getting rid of the need to set the datacontext in code.

    Did I do things right? This will at least get me table-level abstraction.

    There's any number of things you could have done differently, but you did it "right" as far as what's needed by the pattern.  Please not I'm not suggesting there's anything I'd do different, just pointing out there's a lot of different takes when it comes to implementing the pattern.  Things like "View first" (which is what you did) and "ViewModel first", for example.

    If there's no business logic in the code behind, minimal to no UI code in the code behind, and you have a testable ViewModel, you've done things "right".

  • User profile image
    spivonious

    wkempf said:
    spivonious said:
    *snip*

    There's any number of things you could have done differently, but you did it "right" as far as what's needed by the pattern.  Please not I'm not suggesting there's anything I'd do different, just pointing out there's a lot of different takes when it comes to implementing the pattern.  Things like "View first" (which is what you did) and "ViewModel first", for example.

    If there's no business logic in the code behind, minimal to no UI code in the code behind, and you have a testable ViewModel, you've done things "right".

    Okay, that means I understand the pattern then, which is good. It's definitely different using commands instead of events.

    Thanks everyone for your posts. It's good to see things from a different perspective.

     

    Oh, one last question. My commands (currently just a save and a load) are in the ViewModel, as are the functions they call when executed. Since these functions are just simple mappings to functions in the Model, would it be "wrong" to attach the command execute directly to the model?

  • User profile image
    JohnAskew

    spivonious said:
    wkempf said:
    *snip*

    Okay, that means I understand the pattern then, which is good. It's definitely different using commands instead of events.

    Thanks everyone for your posts. It's good to see things from a different perspective.

     

    Oh, one last question. My commands (currently just a save and a load) are in the ViewModel, as are the functions they call when executed. Since these functions are just simple mappings to functions in the Model, would it be "wrong" to attach the command execute directly to the model?

    If you are considering the 'model' being a DataSet within the ViewModel, sure, wire up to it. I would request you refer to the DataSet not as the model, but a datatype within your ViewModel that was delivered from The Model (Oracle/DAL/etc)... Perhaps it's a trivial distinction, but I'm sure you get my meaning.

    But if you mean you want to call functions that are on the Model directly from the ViewModel, well, it is the place to call into the Model...

    What would be handy is to be mindful of dependencies on the Model with regard to your unit tests. If you use an interface for the Model to implement, then you can Mock that Model within unit tests that can fully exercise the ViewModel.

    HTH

  • User profile image
    wkempf

    JohnAskew said:
    spivonious said:
    *snip*

    If you are considering the 'model' being a DataSet within the ViewModel, sure, wire up to it. I would request you refer to the DataSet not as the model, but a datatype within your ViewModel that was delivered from The Model (Oracle/DAL/etc)... Perhaps it's a trivial distinction, but I'm sure you get my meaning.

    But if you mean you want to call functions that are on the Model directly from the ViewModel, well, it is the place to call into the Model...

    What would be handy is to be mindful of dependencies on the Model with regard to your unit tests. If you use an interface for the Model to implement, then you can Mock that Model within unit tests that can fully exercise the ViewModel.

    HTH

    Good advice.  One needs to be careful with any tight-coupling, and not just because of testing concerns.  Of course, there's the pragmatic side to this as well... over engineering for a small "throw away" application just to adhere to enterprise "best practices" can be a waste of time.  If this were a mission critical and/or large application, I'd recommend the repository pattern here.

  • User profile image
    spivonious

    wkempf said:
    JohnAskew said:
    *snip*

    Good advice.  One needs to be careful with any tight-coupling, and not just because of testing concerns.  Of course, there's the pragmatic side to this as well... over engineering for a small "throw away" application just to adhere to enterprise "best practices" can be a waste of time.  If this were a mission critical and/or large application, I'd recommend the repository pattern here.

    Yeah, for this project there's really no point to force loose coupling on the model side of things, as changing our system from Oracle to something else would be a nightmare (thanks to all of the existing tightly coupled apps Smiley )

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.