I've started a project using MVVM Light and have run into an issue where once a window is created a ViewModel is bound to it, however, if I close this window and reopen the same window another viewmodel is made.
Through the debugger I can see the code looping through properties and methods after interacting with forms. I can see many instances of the same collections/properties/methods being fired. This then creates errors of 'Out of Bounds" after deleting items, etc.
*Note: Using ViewModelLocator, bound within XAML and completely removed from the XAML.cs files. ViewModels not referenced anywhere else.
I've attempted the following. No Help.
(WPF/MVVM) Single Instance In MainViewModel
How should I handle this to eliminate multiple ViewModels and looping properties/methods. Methods/properties should only be looped once.
EDIT
I've solved my issue. By referencing a static class within windows resources I was creating a new instance per ListView. Thus forcing the ViewModel to loop to conditions to meet those instances each form that consumed an instance.
By eliminating the resource and moving all data to MVVM Light DataService and using Task from System.Threading.Tasks, I am able to bind to a collection within the ViewModel rather than a independent instance. No more looping. Thanks for the answers.
It's common to use viewmodel first and a single window application rather than multiple windows with their own viewmodels.
Partly since it's quite easy for users to "lose" multiple windows. It also closes off a number of sharing issue edge cases where you have window X open and when you open window Y the processing clashes.
With what you have now, one simple way round this is to use SimpleIOC to provide your viewmodels.
SimpleIOC gives you singletons for anything you ask for.
You may have seen code does:
SimpleIoc.Default.GetInstance<vmType>();
Which of course has a definite type inside those angle brackets.
An alternative is:
SimpleIoc.Default.GetInstance(vmType);
Where vmType can be a variable. A Type variable which matches the tupe of the viewmodel you want.
You could make a markup extension which takes a type as parameter and makes that call, returning the viewmodel.
I've not tried it, but I don't think you even need to register the type using that syntax.
You can always use Singleton Design Pattern
public sealed class Vm
{
//Private Constructor.
private Vm()
{
}
private static Vm instance = null;
public static Vm Instance
{
get
{
if (instance == null)
{
instance = new Vm();
}
return instance;
}
}
}
Related
MVVM, using PRISM 6 and Unity.
Bootstrapper takes care of creating intial View, which is in turn AutoWired to the ViewModel (i.e. View Model is resolved and it's DI's are taken care of).
Now the View Model has a Collection of other View Models.
This Collection can be added to with User Input, say with a button push.
The View Models in the collection require access to a singleton that I have to manage the "Workspace" (paths for image folders etc). So I would also want the creation of those objects to have that "Workspace" singleton injected into it.
In the method that would create a new ViewModel, what's the correct way to utilize DI/IoC to create it?
The only way I see it (dangerous to say "only" I know, that's why I'm asking for help) is:
Inject the Unity Container into the View Model that contains the
collection, then Resolve the new View Models as the button is hit.
The new View Models would be setup with a dependency on the
interface for the "Workspace" object.
Create a new View Model when the button is hit and pass the
"Workspace" into the constructor (of course the Workspace would need to be DI'd into the parent View Model to be passed down).
I have read multiple places that getting into passing the Container down via DI so that one can use Resolve<> isn't "correct".
Is this where creating a generic Factory would help? This still forces me to pass the container down, now it's just in the form of a factory though...
public T factory<T>(IContainer _container)
{
return _container.Resolve<T>();
}
Often when I read about DI, it is treated as the be all and end all. I more often than not use IoC heavily even in my small and simple projects, however, it is just pattern and has a place like everything else.
The Microsoft Press book Adaptive Code via C# explains SOLID well, justifies its use, covers the various forms of DI and the cost/benefit of each technique. For me, it made a lot of sense of these issues, managing project growth, and dealing with external dependencies.
I would NOT pass the UnityContainer to anything outside of my bootstrapper, other than a system which abstracts and breaks apart the bootstrapping/modularity process. In addition to the points you have made about this, Unity is a third-party dependency to your application just like anything else, and I would be very selective of which (if any) I tie myself to.
For your example above, I would use a simple factory. You could abstract this as far as you like, but a good compromise would be relieving your primary ViewModel of the burden of having to create its own children.
When using DI, there is nothing wrong with instantiating things yourself where appropriate. The most appropriate place of course is a factory. I wouldn't create a generic factory, as you stated, this is basically just like passing around the IoC container. Define a typed factory instead:
public interface IWorkspaceItemViewModelFactory
{
WorkspaceItemViewModel CreateWorkspaceItem();
}
The implementation of this might look something like this:
public class WorkspaceItemViewModelFactory
{
private readonly IWorkspaceManager _workspaceManager;
public WorkspaceItemViewModelFactory(IWorkspaceManager workspaceManager)
{
_workspaceManager = workspaceManager;
}
public WorkspaceItemViewModel CreateWorkspaceItem()
{
return new WorkspaceItemViewModel(_workspaceManager);
}
}
This class is an information expert with the single responsibility of creating WorkspaceItemViewModel instances. It has the right the use the new keyword, and have knowledge of WorkspaceItemViewModel dependencies. You may wish to insulate the ViewModel with an interface, but the value might be very little in your use case. Ultimately, you are using IoC, DI, and Interface Segregation for a reason, and when they stop delivering value to your particular application their use becomes noise.
Your view model could make use of this something like:
public class ExampleViewModel : ViewModelBase
{
public ExampleViewModel(IWorkspaceItemViewModelFactory workspaceItemViewModelFactory)
{
AddItemCommand = new ActionCommand(() =>
{
var newItem = workspaceItemViewModelFactory.CreateWorkspaceItem();
WorkspaceItems.Add(newItem);
});
}
public ICommand AddItemCommand { get; }
public ObservableCollection<WorkspaceItemViewModel> WorkspaceItems { get; } = new ObservableCollection<WorkspaceItemViewModel>();
}
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 some confusion in Linq to SQL.I am searching for an actual reason why Data context class gives follwing Exception some times .
"There is already an open data reader associated with this command which must be closed first
Specially in multitasking environment.Most people are saying that the reason is ,Data Context is not thread Safe.All are suggesting to use DataContex as one per unit of work.
Please refer following thread for best answer
Linq-to-SQL Data Context across multiple threads
But in my case,i am using another class call "A" which is implemented in Singleton pattern.Purpose of this class is ,provide Data context object in singleton manner.I am maintaining instance of this class "A" as global instance in derived class and calling to Datacontex by using particular instance.
My question is,
Will my method call cause uncontrolled memory growth ? based on my understanding,singleton maintaining one instance as static object .If my assumption is wrong ,please give me good explanation.
Note:
Any way my method call also throws same exception.So i am sure same problem is happen in this scenario also.
Your approach will cause problems in general. A DataContext is not intended to be a singleton. Just don't do it.
Even if A is a singleton, create a new DataContext within the appropriate methods within A, rather than having a DataContext as a variable within A. (You might also want to consider whether A should really be a singleton in the first place.)
I actually came here because I felt a singleton pattern would be perfect for the Linq Datacontext too. But after seeing your issues it makes since why it's not.
Here's an example of how I'd write a Singleton Linq DataContext:
class DataAccess
{
private static DataContext db = null;
private DataAccess()
{
}
public static DataContext GetInstance()
{
return db ?? (db = new DataContext());
}
}
In the singleton pattern you set the DataContext instance as static. Well, in a multi-threaded environment a static object is going to cause collisions like the errors you're seeing. You are lucky to get those errors. Using multiple threads you could submit changes from another thread and then have the original thread submit causing a big mess.
I'd stick to non static implementation. True me I know it's disappointing, I really wanted to use that pattern here too.
I have a WPF application with the main Window class called MainWindow.
Since I have other classes that need to access the Dispatcher of the UI thread to update bounded lists, I found this solution:
I made a static class:
static class UI
{
static public MainWindow window;
}
And added the following line in the app constructor:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
UI.window = this;
...
Now I can access the components of my GUI everywhere by using UI.window.Dispatcher.Invoke().
The question is - is this a good programming practice?
Is there a better method of doing so?
Thank you
Update:
I seem to get the exception thrown only when I update an ObservableCollection which is bound to a 3rd party control. I have another static OC bound to a listbox (to display updated messages) and I can update that one from other threads without using the dispatcher.
How come?
Is it because its a static OC or is it related to the control?
Since I have other classes that need to access the Dispatcher of the UI thread to update bounded lists
Personally, if you need this, I would just save a reference to the Dispatcher, not to the entire UI.
Providing a reference to the Window itself could, potentially, cause confusion. The intent here is not as clear.
In the general case, it isn't ideal - static has some gotchas if you expect threads to be independent, or if you expect garbage collection to collect the window - but arguably you can probably get away with it for you main window, since that is probably essentially singleton and lasts the lifetime of the app.
Personally I probably wouldn't - I'd pass it in via a property or constructor argument - but I'm a bit fussy.
If its only about the dispatcher, you can do this
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, (Action)delegate()
{
});
I am currently hoping to use a PropertyGrid to allow users to edit some of my classes, however I've hit a wall with passing objects to the UITypeEditor(s) they use. When the user presses the drop down I want to show a listbox of already loaded textures to choose from, if they want to use a texture the application hasn't loaded yet they can click a button to choose one from a file dialog. In case I make no sense here a mock of the form:
.
My problem: To fill the listbox I need access to the class that manages the list of resources from the UITypeEditor.
Now I've solved this problem for my own classes by giving them a reference on creation to their managing object. In the UITypeEditor I then use that reference to access what I need. However I can't do this for classes I haven't written, such as the XNA Texture2D class.
Here are what the classes I'm using look like:
class StaticGeometryChunk
{
// Geometry data to draw with. Contains a reference to its managing
// class for use in its UITypeEditor.
public GeometryData { get; set; }
....
}
class Material
{
// These are XNA classes. I can't just add a reference to its managing
// class (I think?).
public Texture2D Texture1 { get; set; }
public Texture2D Texture2 { get; set; }
....
}
I've been looking at my options and they seem to be:
Make the managing classes static.
I don't really want to do this. There are several managing classes as each resource is loaded differently. There are also classes that need to be created before these and are passed in.
Make the managing classes singletons.
I don't really want to do this either. It seems like a quick and dirty way to "hide" the problem instead of "solve" it. I also might want the option of having several managing classes in the future which the singletons eliminate.
Create a wrapper class which holds the reference to a managing class and its target (such as the XNA Texture2D).
This is currently what I'm thinking of doing. Its would be quite simple and quick to do but something about it nags me but I don't know what.
Any thoughts on the above or other methods to pass what I need into the UITypeEditor?
Thank you for reading.
In the EditValue method, you are given a context. Use context.Instance to access the object that holds your property. This object should also contain a property that gives you access to the list of things you want to display. You could test if context.Instance is ITextureProvider for example, then cast it and access the textures. Not sure if this makes sense in your design but let me know.
As an alternative you can try the following approach. I find it very elegant, because it does not require to store a list of available property values in the object. Therefore, for example, you can show one set of values on one form and another set on another.
Create an interface IYourDataProviderService.
Create an implementation of IYourDataProviderService, which knows the concrete data to provide.
Create a class implementing ISite. In GetService() method return an instance of class which implements IYourDataProviderService, if the serviceType parameter is typeof(IYourDataProviderService).
I left rest of ISite methods throwing NotImplementedException (except DesignMode property) and for me it worked, but probably this is not an ideal solution.
In 'Load' event handler assign your implementation to the Site property of your propertygrid.
Enjoy!