I'm developing a WPF Prism application, and everything is working fine. My view models all have interfaces, which are injected by MEF.
However, I don't really understand the benefit of interfaces for view models. After all, a view is tied to its view model, so I think there will never be other implementations.
Actually, I also have interfaces for my views. It seems that this is also overkill?
So my question is: can't I just remove all view and view model interfaces and inject the views and view models directly? Is there any reason to keep interfaces for views and view models?
Thx,
L
It is an overkill. I understand that you may want to mock your ViewModels, but I think it's more important to be practical. Plus, why would you even need to mock your ViewModels? Any logic that needs to be mocked should be put into a service class IMHO.
Interfacing your VieWModels gives you the benefit of mocking them in a test, interfacing your Views looks like some overkill indeed. You won't interchange your views and UI testing can be done on mocks of your ViewModel so you won't really need to interface them I think.
The biggest reason I can think of for interfaces for ViewModels would be that you can write mocks that implement those interfaces for use while unit testing. Since one ViewModel may talk to another, it enables you to stub out the second ViewModels behaviour when testing the first.
The MVVM pattern makes it easier to unit test the classes as it separates data and control from the UI layer (which is harder to write unit tests for). Personally, I don't write interfaces for my views though.
Related
When starting a new mvvm-wpf-application, I usually include mvvm-light right at the start. That works fine, until my application grows.
Some where along the line the ViewModelLocator becomes huge (many ViewModels for all kinds of ChildViewodels). And even further down the rabbit hole I need multiple distinct instances of the same viewmodel. (eg for a List of items, with which one would like to interact on the same screen). This is where the struggle begins, how to handle that nice, consistently en keep the code testable?
So, if i want to get rid of the ViewModelLocator (is it an antipattern? is feels like a ServiceLocator) should I move to ViewModel-first and create (many) abstract factories for all ViewModels?
The ViewModelLocator is a fancy name for a Navigation Bus used for Inversion of Control (IoC). Though this appears to be a newer technology, a navigation bus is really using a Service Bus in a different way. It is not anti-pattern if you have a static (shared in VB) container. The anti-pattern comes in if you are passing the container around in your ViewModels.
The thing to keep in mind in MVVM is that it is versatile design pattern, and you can extend it in many ways. The best solution for large projects is component design (a design where each feature of your application is in it's own namespace or project).
A design diagram may look like so:
Customer
Models
ViewModels
Services
Orders
Models
ViewModels
Services
etc...
It really comes down to the flavor of the developer. As long as your design is consistent.
Further reading:
To better understand the ViewModelLocator search for the Navigation Bus.
To better understand the EventAggregator, search for Message Bus
Well, yes, if you use the built in IOC container with MVVMLight. If you use things like AutoFac or Ninject, you can register all classes that are based on ViewModelBase. Another option is to use code generation to generate the ViewModelLocator. With the two approaches, you can get it down to one line per view model.
public MyViewModel MyView => serviceLocator.Resolve<MyViewModel>();
I'm over-thinking this and getting myself into a muddle but can't clear my head.
I'm new at WPF and I'm trying to get familiar with MVVM. I understand the theory. I need a view, a model and another model (called the view-model).
However, what happens if my model is constructed by a parameter of the View's constructor.
So, assuming I have a totally empty project, the only thing is I've an overloaded MainWindow constructor which takes the model:
public MainWindow(Logging.Logger logFile)
{
InitializeComponent();
this.DataContext = logFile;
}
The Model is the logFile. Can I still implement the MVVM when I don't have a separate Model class?
Any thoughts would be appreciated.
You're overthinking this.
There are several components to MVVM:
View:
The view provides a, well, view on the data. The view gets its data from a viewmodel
ViewModel:
The viewmodel is there to organise your data so that you can organise one or more sources of data into a coherent structure that can be viewed. The viewmodel may also perform basic validation. The ViewModel has no understanding of the UI so should not contain references to controls, Visibility, etc. A viewmodel gets its data from services.
Services:
Services provide data from external sources. These can be WCF, web services, MQ, etc (you get the idea). The data the service returns may need to be shaped so that it can be displayed in the UI. To do this you would take the raw data from the service and convert it to one or more Model objects.
Model:
A model object is an object that has been created so that it can be easily displayed/work with the UI.
You may find that you don't need to shape your data coming from your services (lucky you), in which case there's no need to create model objects. You may also decided that you don't want your services talking directly to your viewmodels but instead what to have them get their data via a "mediator" object. That's also good in some situations (usually when you're receiving a continuous stream of data from a source/multiple sources).
MVVM is a bit like porridge: there are lots of potential garnishes you can add, but you don't necessarily need to add them all. Or want to.
Does this help?
Edit: just stumbled on this: a more in-depth expression of what MVVM is:Mvvm Standardisation. This may also be useful
The Model is something the ViewModel will know about but not the View. If you need to present info about a Logger, you can certainly have a LoggerViewModel that knows about a Logger, and in turn the View winds up getting to know about the ViewModel. There are several ways to do that, and setting the DC in the view constructor is one of them.
After that basic understanding of who knows about who, what really makes the MVVM architecture pattern, IMO, is that ViewModel communicates to the View via databinding. Nothing more and nothing less. Lots of goodies come out of this, but that is the crux of it that makes it different than other separation of concerns patterns (like Presentation Model, MVP, etc)
That said, you need to get a feel for it by working through some sample projects. Asking questions here on SO is fantastic when you get stuck on something, but you must realize your question here is a bit fuzzy at best. Also, unless you are really looking to present logging info in your view, logging is not an MVVM concern. Its interesting alright but not MVVM.
Google Josh Smith's MVVM demo on MSDN for a perfectly meaty yet approachable beginning sort of project. And ask more questions or refine the one here as they come up!
HTH,
Berryl
forget the view! at least at the beginning ;)
try to think about what you want and what you need. what i understand is that you wanna handle a logfile. so you need a viewmodel for that.
public class LoggerViewmodel{}
you can put the logfile as a parameter to the vm ctor. now you have to think about what you wanna do with your logfile? for everything you want create a property (LastModified, LastRow, whatever) on your viewmodel.
btw there a two different ways to do mvvm, first is view first and the other is viewmodel first. i do both in my projects and take the appraoch wich fits better (viewmodel first the most time ;)) to my needs.
pls edit your questions and add what you wanna do with your logfile, then we can give you a better answer.
edit:
Can I still implement the MVVM when I don't have a separate Model class?
to answer your question the short way - yes you can. you have to seperate the view and viewmodel and use binding to bind the view to the datacontext(viewmodel).
I'm starting to use MVVM Light version 4,and i can't understand:
Why should i use DataService and IDataService?
Should i create a dataservice for any class in model?
First of all - as usual - in MVVM you do not have to do something, it is a recommendation or best practice. In general you are free to code the data access into your view model - and to do so might be a good practice for small projects or prototypical implementations.
However, you should consider that this also has some drawbacks. The reason for implementing a data service is that this component is reusable and even might be usable in other scenarios like an MVC application. Furthermore, it separates out the concern of getting model from a data store.
The reason for implementing an IDataService is that you can exchange the implementation when you need to, e.g. for supplying design time data. When you need this, you also have to consider the inversion of control pattern that heavily relies on interfaces. In this case also a IOC container might be interesting, although not necessary.
But, first of all the above are recommendations, patterns, design guidelines, and best practices that give you the freedom to design an application that best fits your requirements.
Edit: size of the data service
The design and scope of your data service depends on your application and it's requirements. It can range from a single data service for all you models to one data service per model. Furthermore, the design of you data service interfaces may be a separate decision. One service class can implement several service interfaces, thus allowing for hiding certain aspects (methods) of the implementation from the user.
When designing a data service you should look into the unit of work and repository patterns. There are several sample implementations around.
If you just need a very simple unit of work pattern that is based on a single query you can have a look at my blog, where I wrote about turning an IQueryable into a unit of work pattern. However, this fits only very simple cases, generally a complete implementation with a repository and a proper unit of work item is more advisably.
I am currently using caliburn.micro in my WP7 project and I am quite happy with it. My application is very data-heavy, so I took a look at Agfx (http://agfx.codeplex.com), seems it can save me a lot of time on data requesting and caching.
But the problem here is that agfx also provide a base view model, while I've already had one which inherits Screen of caliburn.micro. Of course I can encapsulate a new view model base which inherits ModelItemBase from agfx, and implements IScreen. But I kinda don't like this, is there any better soultion or best practice you can share with me about how to integrate the 2 great frameworks?
Best Regards,
-Peng
I am actually using AgFx with another UI framework which has its own ViewModelBase. My own understanding is, the ModelItemBase that's provided by AgFx is a model base rather than a viewmodel base. It basically takes care of the data.
My viewmodel which inherits from my ViewModelBase, does a lot more stuff like Tombstoning, application bar bindings, etc. It's designed for displaying the data on the view.
I think it fits in mvvm and works out really well. Hope this helps. :)
Guess we have simple model, e.g. let it be a Person { Name, Age }.
Now we want to display a list of persons.
Persons are read-only
We don't need to edit them
We don't need any additional stuff like presentation properties, etc.
Now question is if it is a good practice do not create PersonViewModel class that will probably be a copy of model class or will delegate all its properties? Is it a good idea to simply bind listbox to list of persons, not to their view models? It looks DRY enough, but what about idea of MVVM?
I have no issue with bypassing the VM and using the M directly in the View. Sometimes the models are so small and static that loading them into a wrapping VM is wasteful.
I've created standalone ViewModels, but generally not standalone models. The reason for this is DataBinding -- most POCOs don't implement the INotifyPropertyChanged interface and adding them in to make them pseudo-Models seems to defeat the purpose of re-using a simple class AND respecting the MVVM pattern.
Now, if you KNOW you're never going to be editing them, it may not be a bad idea. A VM with simple property redirects seems a bit pointless to me.
As far as I'm concerned, if you implement INotifyPropertyChanged, then it becomes a ViewModel, and you can bind to it. :) When I wrote SoapBox Core which is all MVVM, I took the approach that everything is a ViewModel. The only Model objects were classes from third party libraries that I brought in and wrapped in a ViewModel of my own.
I wouldn’t create a ViewModel for the Person business object when the ViewModel doesn’t introduce new required functionality.
You might be interested that there is a second approach in the MVVM community: Create a ViewModel per View and not per Business Object.
Sample applications that follow this approach can be found on the WPF Application Framework (WAF) website.