I'm learning MVVM in a course from Brian Lagunas in PluralSight.
At the beginning, he was writting this two interfaces:
public interface IView
{
IViewModel ViewModel {get;set;}
}
public interface IViewModel
{
IView View {get;set;}
}
I was learning in that mode, and then he removed ViewModel from IView.
public interface IView {}
But I can't see the difference of it, perhaps there's advantages and disadvantages of it.
Is anything wrong if I put the first example?
This is of course to less context to leave any useful statements, but at first sight the interface
public interface IViewModel
{
IView View {get;set;}
}
seems very confusing for me because the main idea of the MVVM pattern is that the ViewModel is totally unaware of the View. If you equip the ViewModel with a reference to the View your are violating this idea.
According to this blog:
View-First: The View has a relationship to its ViewModel(usually
through data binding).
ViewModel-First: The ViewModel creates the view (usually through an
IoC container).
In both of these methods it presents a sticky-ness of the view to the
view-model. Also, both of these imply a one-to-one relationship which
while the common case, is not the always case.
Well, I haven't seen the pluralsight course, but I can talk generally about dependency management. In the original scheme, you have entity A that knows about entity B and B that knows about A. In this sense, there are two degrees of coupling: A depends on B and B depends on A. While they depend only on interfaces, which is a positive, that dependency still exists.
By removing one of those dependencies, you have a scenario where A depends on B, but B does not depend on, care about, or even know about A. In the original scenario, if you make changes to IView or IViewModel's API, these will be breaking changes. In the second scenario, you can make whatever changes you want to IViewModel and they will not affect the view implementations.
That's the advantage.
As for disadvantages, the only one is that you lose a convenience, but I consider that not really to be a disadvantage. In my book, anytime you can minimize coupling and dependencies (within reason), that's a win.
I think it's all about the idea to abstract the View through the ViewModel; the ViewModel exposes any property that must be presented to the View and the ones the View [user input in practice] can change (think to the two-way binding). It's the binding engine to take care through the PropertyChanged event to sync the UI with the ViewModel; in this way the ViewModel does not need to reference the View in use, it exposes to any view (you want to use) some properties...
Related
I have a WPF project using the MVVM pattern. I have an interface that for this purpose I'll call IMyData which I currently have 2 implementations of myDataImplA & myDatImplB. I want my ViewModel to be able to switch between using these 2 implementations on the fly. Currently I am passing in both implementations of the interface into the ViewModel's constructor and have Boolean property in which a ToogleButton in the View is bound to determine which one to use. I feel like there is probably a better way to do this and passing in both implementations of IMyData just feel wrong. Also if I end up having a 3rd implementation of IMyData my current method of using a Boolean to determine the implementation of IMyData to use won't work.
The interface could be updated on the fly from the view, but that would break MVVM as I think that would require extra code-behind in my View.I am looking for a more scalable solution which fits within MVVM.
You're assumption this is wrong is, IMO, accurate. The whole reason to implement the IMyData should be to avoid this behavior altogether.
I'm not sure how you have the project setup but just to help you along solving this logic consider the ViewModel just an endpoint where business logic does not live. Your ViewModel should communicate to a DAL (Data Access Layer), in which case, will pump out Model information that it updates against.
Since you're using an interface the DAL should provide that interface instantiated to the ViewModel. Implement a command (ICommand) in the ViewModel that dictates state only, such as an enum. Tell the DAL which state you want. When the DAL updates your ViewModel should be listening and react to it. At this point the ViewModel then updates the IMyData property, which should be notifying listeners, and the View will automatically change (If everything is wired up correctly.).
This probably sounds confusing so I'll try to simplify a different way.
Keep the references in a one way direction at all costs.
View -> ViewModel -> DAL (DAL is considered Model in MVVM, which in your case pumps out IMyData).
Let the View bind to a command in ViewModel stating if it wants StateN for example.
ViewModel then tells DAL to switch to StateN or automatically looks for StateN models.
DAL then changes the IMyData type to the type that works in StateN.
The ViewModel is listening to DAL for changes and when the DAL says StateNChanged the ViewModel updates the IMyData property from the DAL, which fires off a notification.
The View, bound to the ViewModel, then updates based on the new data.
If this doesn't make sense, post most of the code and I'll make the modifications and show it.
The view model shouldn't have any dependency upon any implementation of the IMyData interface. It should only have a dependency upon the interface itself.
Since you want to be able to switch the implementation dynamically at runtime, you could add a property to the view model that provides a default and interchangeable implementation:
public IMyData CurrentImplementation { get; set; } = new myDataImplA();
The view, or any other component, can then switch implemenation as requrired by simply setting this property.
I have been writing all my MVVM application with basic design pattern generally mentioned in MVVM examples available online. The pattern that I am following is described below:
Model
This section include DTO classes with their properties and Interfaces IDataService and like:
public class Employee
{
public string EmployeeName { get; set; }
public string EmployeeDesignation { get; set; }
public string EmployeeID { get; set; }
}
public interface IDataService
{
public Task<Employee> GetEmployeeLst();
}
Proxy
This layer contains Dataservice calls which implement IDataservice like:
public class DataService : IDataService
{
public async Task<Employee> GetEmployeeLst()
{
// Logic to get employee data from HTTPClient call
}
}
ViewModel
This layer contains ViewModel and reference to Model and Proxy layer from which all data is received:
public class BaseViewModel
{
public BaseViewModel(INavigationService nav, IDataService data, IAESEnDecrypt encrypt, IGeoLocationService geoLocation, IMessageBus msgBus, ISmartDispatcher smtDispatcher)
{
}
// This also include common methods and static properties that are shared among most of the ViewModels
}
All the ViewModel inherits BaseViewModel. Each viewModel also contains Delegatecommand which is executed when UI triggers an event. Which then fetches the data from the server by calling DataService in proxy layer and perform business logic and populates the properties in ViewModel which is binded to the view. For each View there is a VM which is binded to the Datacontext of the View.
ViewModel is also responsible for starting an animation I have used trigger to start storyboard which is binded to my enums in VM for state change of these trigger as in example in: http://www.markermetro.com/2011/05/technical/mvvm-friendly-visual-state-management-with-windows-phone-7/
View
In this layer I have all my Views, Usercontrols and business logic with implementation of certain dependencies like GeoLocation Service, AES encryption, NavigationService between Views etc.
Every View has .xaml and .xaml.cs file. In .xaml.cs file I have binded the data context of the view with VM like this:
this.DataContext = App.IOConatiner.GetInstance<DashboardViewModel>();
and from here on all binding happens.
My problem is that recently I had the knowledge that this pattern is not following a SOLID design pattern which I got know in this answer of my question:
Simple Injector inject multiple dependency in BaseClass
I am trying very hard to change my design as per the suggestion given in my previous question's answer. But I am not able to get some of the things like:
Currently View Datacontext is binded to ViewModel hence all the controls are controlled by a property in VM. How would I change this to your above mentioned pattern with Processor/Service or DialogHandler?
I am using Delegatecommands which are binded to command property of UI element. Execution of these command certain action happens like animation, usercontrol is displayed. How to do it in command pattern?
How can I start changing my current implementation to accommodate all those changes with best possible approach?
First of all an answer to your question 3
How can I start changing my current implementation to accommodate all those changes with best possible approach?
This is the very first step you need to take. It is not a case of some smart refactoring of your current code. You will need to take a step back and design the application. I once read some nice blog about (re)design.
Before starting to write any code, define how many different basic types of views you will want to show to the user? E.g.:
Just show (any type of) data
Edit data
Alert user
Ask user for input
...
When you defined your different requirements, you can translate this to specific interfaces that are tailor made for the job they serve. For example a view that lets the user edit data will typically have an interface that will look something like:
public interface IEditViewModel<TEntity>
{
public EditResult<TEntity> EditEntity(TEntity entityToEdit)();
}
Once you every detail of this design in place, you must decide how you will show your views to the user. I used another interface for this to handle this task for me. But you could also decide to let a navigation service handle this kind of task.
With this framework in place, you can start coding your implementations.
Currently View Datacontext is binded to ViewModel hence all the controls are controlled by a property in VM. How would I change this to your above mentioned pattern with Processor/Service or DialogHandler?
This will not change in this design. You will still bind your view to your viewmodel and set the datacontext to the viewmodel. With a lot of views the use of an MVVM framework like Caliburn Micro will come in handy. This will do a lot of the MVVM stuff for you, based on Convention over Configuration. To start with this model, would make the learning curve even higher, so my advice to start of by hand. You will learn this way what happens under the covers of such an MVVM tool.
I am using Delegatecommands which are binded to command property of UI element. Execution of these command certain action happens like animation, usercontrol is displayed. How to do it in command pattern?
I'm not sure if the command pattern you mention here is the command pattern I advised you in the previous answer. If so, I think you need to reread this blog, because this is totally unrelated to the commands I think you mean in this question.
Animation and that sort of stuff is the responsibility of the view, not the viewmodel. So the view should handle all this stuff. XAML has a lot of ways to handle this. More than I can explain here. Some ideas: Triggers, Dependency Properties
Another option: Code behind! If the logic is purely view related IMO it is not a mortal sin to place this code in the code behind of your view. Just don't be temped to do some gray area stuff!
For commands that just perform a method call in your viewmodel, ICommand is still possible and MVVM tools like Caliburn will do this automagically...
And still: Loose the base class....
Why are you injecting all these services in your viewmodel base class if the viewmodel base class does not make use of these services himself ?
Just inject the services you need in the derived viewmodels that do need those services.
I have a BaseViewModel which is inherited by multiple ViewModel classes. In my BaseViewModel I have a couple of dependencies which get injected from ViewModel. Now if I need to add a new dependency in my BaseViewModel I need to change all the VM which inherit BaseViewModel. Please let me know how can it be handled in Simple Injector. Following is my code structure:
How can I make my base class injection independent so that I don't need to make changes in all my inherited class?
Code:
public class BaseViewModel
{
protected readonly IAESEnDecrypt AESEnDecrypt;
protected readonly IDataService DataService;
protected readonly INavigationService NavigateToPage;
public BaseViewModel(INavigationService nav, IDataService data, IAESEnDecrypt encrypt)
{
AESEnDecrypt= encrypt;
NavigateToPage = nav;
DataService = data;
}
}
public class ViewModel
{
public ViewModel(INavigationService nav, IDataService data, IAESEnDecrypt encrypt) : base (nav, data, encrypt)
{
}
}
My BaseViewModel Contains some of the following Interfaces whose implementation is injected through constructor:
- NavigationService
- DataService
- GeoLocationService
- SmartDispatcher
- MessageBus which implement Message Aggregator
It also Contains some common properties as static variables whose data is used throughout the application like UserDetails. And also contains CancellationToken, IsBusy to display progressbar.
BaseViewModel also contain HandleException method which handle all the incoming exceptions from all ViewModel.
Also Contains some common Commands which are used in all the Views like Si
gnoutCommand, NavigationBar Commands.
Actually it has started to contain all kinds of common methods used among various ViewModel.
Please suggest how can i refactor this code?
Your last sentence:
Actually it has started to contain all kinds of common methods used among various ViewModel
Precisely describes your problem! As Steven already described, that you're building almost the complete application through a single base class. Thereby infringing the Open-Closed principle which you are heavinly experiencing now.
The trick is design your application around very small SOLID ViewModels of which you compose the application at runtime. By splitting the ViewModels and using a UserControl as your views you can compose big complicated views for the user, while you still get all the benefits from using a SOLID design. So let’s take a look at some of your different interfaces that you implement and some of the functions you ‘handle’ in the base class:
NavigationService
This sounds like a service which controls the flow in your application. This sounds to me like your mainview(model). You could create a single MainViewModel which as a single property, let’s say CurrentView.Assuming you’re using WPF you typically would bind this property to a ContentControl. The content of this control can be everything from a single TextBlock to a complete UserControl. The UserControls can still be very complicated as they could be composed of multiple child usercontrol and so on. Using a MVVM framework (like e.g. Caliburn Micro or MVVM Light) for this is optionally but will come in handy.
It could also be an application global service with some of kind of callback or delegate function to perform navigation to a certain View(Model). It is in any case an infrastructural part of your application that deserves it own class and shouldn't be put away in a base class.
DataService
A single dataservice was the way I worked for over 10 years. Every time I hit my head against the wall. There comes a point in time that you need something special which is not included in your dataservice and you will probably go through your complete code base to make the right adjustments. Speaking of the Open-Closed principle…
Than I learned about the Command/Handler and Query/Handler pattern. You can read about this here and here. Using this pattern everywhere you need data you just inject the correct IQueryHandler<,> and use it right there. Not every view(model) needs data and certainly not the same data. So why use a global DataService? This is will also improve your Lifetime management of your DBContext object.
HandleException
Why is your base class responsible for handling the exceptions of your viewmodel? What does the base class know about this exceptions? What does the base class do? Log the exception, show a message to the user (what kind of message?) and silently continue? Letting the application break down 3 minutes later and leaving a user ignorant of what happened?
I.M.O. exception should not be catched if you didn’t expect them to be thrown in the first place. Than log the exception at an application level (e.g. in your Main), show an ‘Excuse me’ message to the user and close the application. If you expect an exception, handle it right there and then and handle according.
UserDetails
Ask yourself the question how many of your 40 ViewModels actually need this information? If all 40 are in need of this information, there is something else wrong with your design. If not, only inject this details (or even better an IUserContext) in the ViewModels that actually use them.
If you use it for some kind of authentication consider using a decorator wrapping the task they need permission for performing it.
IsBusyIndicator
Again: do you need this in every ViewModel? I think not. I think furthermore, showing the user a busy indicator is a responsibility of the View, not the ViewModel and the as the length of the task determines if you need to show this, make it a responsibility of the task (assuming you’re looking at your tasks also in a SOLID manner by using e.g. the already mentioned Command/Handler pattern).
With WPF you could define a Dependency Property that you can bind to the view, thereby showing some kind of busy indicator. Now just inject a ShowBusyIndicatorService in the task that needs to show it. Or wrap all your (lengthy) tasks in a ShowBusyIndicatorDecorator.
Design
Now let’s look at some simple interfaces you could define to build up your View(Model)s. Let’s say we decide to make every ViewModel responsible for a single task and we define the following (typical LoB) tasks:
Show (any kind of) data
Select or choose data
Edit data
A single task can be stripped down to ‘Show data of single datatype (entity)’. Now we can define the following interfaces:
IView<TEntity>
ISelect<TEntity>
IEdit<TEntity>
For each interface type you would create a Processor/Service or DialogHandler depending on your semantic preferences which would do the typical MVVM stuff like finding a corresponding view and binding this to viewmodel and show this in some way (a modal window, inject it as usercontrol in some contentcontrol etc.).
By injecting this single Processor/Service or DialogHandler in the your ‘Parent’ ViewModel where you need to navigate or show a different view you can show any type of entity by a single line of code and transfer the responsibility to the next ViewModel.
I’m using these 3 interfaces now in a project and I really can do everything I could do in the past, but now in SOLID fashion. My EditProcessor, interface and viewmodel look like this, stripped down from all not so interesting stuff. I’m using Caliburn Micro for the ViewModel-View Binding.
public class EditEntityProcessor : IEditEntityProcessor
{
private readonly Container container;
private readonly IWindowManager windowManager;
public EditEntityProcessor(Container container, IWindowManager windowManager)
{
this.container = container;
this.windowManager = windowManager;
}
public void EditEntity<TEntity>(TEntity entity) where TEntity : class
{
// Compose type
var editEntityViewModelType =
typeof(IEntityEditorViewModel<>).MakeGenericType(entity.GetType());
// Ask S.I. for the corresponding ViewModel,
// which is responsible for editing this type of entity
var editEntityViewModel = (IEntityEditorViewModel<TEntity>)
this.container.GetInstance(editEntityViewModelType);
// give the viewmodel the entity to be edited
editEntityViewModel.EditThisEntity(entity);
// Let caliburn find the view and show it to the user
this.windowManager.ShowDialog(editEntityViewModel);
}
}
public interface IEntityEditorViewModel<TEntity> where TEntity : class
{
void EditThisEntity(TEntity entity);
}
public class EditUserViewModel : IEntityEditorViewModel<User>
{
public EditUserViewModel(
ICommandHandler<SaveUserCommand> saveUserCommandHandler,
IQueryHandler<GetUserByIdQuery, User> loadUserQueryHandler)
{
this.saveUserCommandHandler = saveUserCommandHandler;
this.loadUserQueryHandler = loadUserQueryHandler;
}
public void EditThisEntity(User entity)
{
// load a fresh copy from the database
this.User = this.loadUserQueryHandler.Handle(new GetUserByIdQuery(entity.Id));
}
// Bind a button to this method
public void EndEdit()
{
// Save the edited user to the database
this.saveUserCommandHandler.Handle(new SaveUserCommand(this.User));
}
//Bind different controls (TextBoxes or something) to the properties of the user
public User User { get; set; }
}
From you IView<User> you can now edit the current selected User with this line of code:
// Assuming this property is present in IView<User>
public User CurrentSelectedUser { get; set; }
public void EditUser()
{
this.editService.EditEntity(this.CurrentSelectedUser);
}
Note that by using this design you can wrap your ViewModels in a decorator to do crosscutting concerns, like logging, authentication and so on.
So this was the long answer, the short one would be: loose the base class, it is biting you and it will bite you more and harder!
Prevent having this base class in the first place. This base class is a big code smell and the result is your current pain. Such a base class will violate the Single Responsibility Principle (SRP) and will just act as a big helper class for all derived view models, or it even seems that you are putting cross-cutting concerns in there. The base class might even hide the fact that your view models violate the SRP. They probably do too much; have too many responsibilities.
Instead, try to do the following:
Move cross-cutting concerns out of the base class into decorators or find another way to apply cross-cutting concerns.
Group related dependencies together into a aggregate service and inject such aggregate service into your view model.
In a well designed application, there is hardly ever a need for having such base class that takes dependencies.
If you aren't able to change your design (but please do take a look it this; you will be in a much better place without that base class), you can revert to explicit property injection. Simple Injector does not do this out-of-the-box, but the documentation describes how to do this.
Basically, it comes down to writing a custom IPropertySelectionBehavior, moving the constructor dependencies of the BaseViewModel to public properties and marking them with a custom attribute.
But again, only use property injection as a last resort. Property injection will only hide the design problem; it will not solve it.
You can use the ServiceLocator (anti)pattern to make the injection independent, HOWEVER you should not do this as it violates the principles of SOLID. Mark Seemann - Service Locator violates SOLID
You should rather stick to adding the dependencies in the constructor as this is in line with SOLID OO design principles.
I have a MainViewModel, which features PersonViewModel and a HouseViewModel as properties. HouseViewModel has the property GetRooms. What is the best way to access this property from the PersonViewModel?
My solution at the minute is to pass through an instance of MainViewModel to PersonViewModel, then I can call MainViewModel.HouseViewModel.GetRooms. However, this seems a little wasteful.
I am happy to pass a function as a delegate, but I can't seem to do this with a Property. I have searched for an example of this and only come up with overly complicated techniques. I'm assuming there must be a simple way of doing this, as it seems like a common problem. Can anyone point out a strong example?
Or is there another, alternative method that I haven't considered?
If a method has to be shared across two viewmodel, it should be defined in base viewmodel or a service. The best way is a common Service class should hold all common methods like GetRooms, CheckIn, CheckOut, etc. And this service should be provided to every viewmodel using Dependency Injection.
public class HomeViewModel
{
public HomeViewModel(IRoomService roomservice)
{
}
}
public class PersonViewModel
{
public PersonViewModel(IRoomService roomservice)
{
}
}
In my ASP.NET app, I have a Person and a PersonViewModel.
My Person was generated by LinqToSql. It has the properties that will be persisted in the database.
My PersonViewModel has everything Person has, plus a couple "select lists", which will be used to populate combo boxes, as well as a FormattedPhoneNumber (which is basically a PhoneNumber with dashes and parenthases added).
I originally just made Person a property on my PersonViewModel, but I was thinking that would mean the page would have to "know" whether something was a Person property or PersonViewModel property. For example, for name, the view would request pvm.Person.Name, but for the phone number, the view would request pvm.FormattedPhoneNumber. If I use inheritance, then everything the view needs would always be a direct property of the view model, hence pvm.Name.
This sounds great, but, there is no real "is-a" relationship here (i.e., I don't really think it makes sense to say "a PersonViewModel is a Person), and it seems to fly in the face of "preferring composition over inheritance". Still, I'm having difficulty thinking of a scenario where I'd need the ability to swap out a Person for something else. If I do this, it would no longer be a PersonViewModel.
What say you? Inherit from Person or keep Person as a property (or something else entirely)? Why?
Update
Thanks for all the answers.
It looks like the inheritance idea has been almost universally rejected, and for some sound reasons:
Decoupling the classes allows the ViewModel to contain only the properties from the domain model that are needed, plus any additional properties. With inheritance, you naturally expose all public properties from the domain model, which may not be a good idea.
The ViewModel doesn't automatically need to change just because the domain model changed.
As Jay mentioned, decoupling the ViewModel facilitates view-specific validation.
As Kieth mentioned, using a Mapper (such as AutoMapper) can eliminate a lot of the tedious work in mapping common properties between classes.
Deriving from an object implies an "is a" relationship. So in this case you would effectively be saying that a PersonViewModel is a Person. It seems that this is not likely to be the semantics that you really want to convey, so use composition instead of inheritance here.
In reality it probably doesn't really affect the maintainability of the application (other than having a few more dots here and there) but using composition certainly feels cleaner to me. In addition, if it's a PersonViewModel then presumably the view should know that that's the type it is dealing with.
Make Person a private member, and expose the properties that your view requires in the PersonViewModel, even if those properties just pass through the corresponding property of Person.
pvm.Person.Name is the code smell here.
Edit:
You're also limiting yourself to client-side validation and/or validation in the domain model, the latter meaning that if you create a second or subsequent ViewModel for Person, you can't change the validation on Person's members. (Well, you could, but this is a violation of the open-closed principle and you're introducing view concerns into the domain.) By hiding your domain objects from the view, you give yourself a clean space to perform use-case-specific validation before changes get made to your domain object. The domain object may have its own set of validators, but they can be strictly domain-appropriate, without view-specific issues creeping in.
You should not inherit from Person or use composition to have Person on PersonViewModel. Instead you should add the properties that you need to the PersonViewModel and map between them. Tools like AutoMapper (http://www.codeplex.com/AutoMapper) make this dead simple.
You should not expose your domain model directly to the View for a number of reasons, including security (under-posting and over-posting).
I am thinking a partial class may be better here. keep the generated Person class and add anothe partial Person class with the extra stuff in it.
On the one hand:
What if you did this?
Person p = new PersonViewModel { //init some properties };
Would p do everything you'd expect a Person to do? If it would, then sure, use inheritance. If it would have some peculiarities related to the fact that it's really a PersonViewModel, and not a Person, then use composition.
On the other hand:
My inclination is to use inheritance largely as a way of avoiding lots of duplicated code. Since you're only inheriting from one parent to one child (rather than to many children), you're not avoiding a lot of duplicated code in the first place. So it's probably not worth it to use inheritance.
One trick I've used, not specifically with ASP.NET MVC but with a similar use case, is to create a class that contains specifically those items specific to the ViewModel class (i.e., those that are not just tunneling through to the person class), and supplying an extension property on the Person class to allow access to the extended properties. This isn't strictly a ViewModel in the classic sense of the word, but I feel it allows for much of the same functionality without introducing awkward inheritance or code duplication with tunneled properties.
Here's a quick example of what I'm talking about:
public static class PersonExtensions {
public PersonViewData ViewData(this Person p) {
return new PersonViewData(p);
}
}
public class PersonViewData {
public PersonViewData(Person p) {
this._person = p;
}
private Person p;
public string FormattedPhoneNumber {
get { return p.PhoneNumber.ToPrettyString(); // or whatever }
}
}