5

I have made an C# WPF Application using the MVVM Light framework. My Application uses the ViewModelLocator class to locate the viewmodels during runtime. The ViewModelLocator makes usage of the SimpleIoc class which also comes with the MVVM Light framework.

Here is my scenario: The user logs in an can use my application. On logout, i want to dispose/reset/recreate all viewmodel instances to provide a clean environment to the next user.

I tried to implement the Cleanup() method in the ViewModelLocator class but it is not working. Not working means that the (second) user sees the data from the user who was logged in before.

first try:

public static void Cleanup()
{
   SimpleIoc.Default.Reset();
}

second try:

public static void Cleanup()
{
   SimpleIoc.Default.Unregister<LoginViewModel>();
   SimpleIoc.Default.Unregister<TaskViewModel>();

   SimpleIoc.Default.Register<LoginViewModel>();
   SimpleIoc.Default.Register<TaskViewModel>();
}

third try (not what i want but it is a workaround):

public static void Cleanup()
{
   // I implemented the ICleanup interface in my viewmodels
   // The cleanup method clears all my variables eg: myCollection.clear();
   SimpleIoc.Default.GetInstance<LoginViewModel>().Cleanup();
   SimpleIoc.Default.GetInstance<TaskViewModel>().Cleanup();
}

How do i reset all instances in my ViewModelLocator class? I'm willing to use a more advanced Ioc Container if necessary.

Joel
  • 4,862
  • 7
  • 46
  • 71
  • What's wrong with the third approach? Can the objects not be reused? – Dustin Kingen Jun 11 '13 at 11:34
  • I have some logic in my constructors which prepare some things for the current user. This won't work any longer. I also have to write a lot of code which needs to be maintained (cleanup method for every viewmodel). The approach to throw away the old instances seems far more straightforward to me. – Joel Jun 11 '13 at 11:38
  • According to the MVVM Light maintainer this is the recommended approach. [SimpleIoc - can it provide new instance each time required?](http://stackoverflow.com/a/9350917/580951). If that doesn't fit your architecture then it might be better to switch to another IOC. – Dustin Kingen Jun 11 '13 at 11:43
  • Do you know other IOCs? – Joel Jun 11 '13 at 12:42
  • 1
    I've used [Simple Injector](http://simpleinjector.codeplex.com/) and [AutoFac](https://code.google.com/p/autofac/). IOCs aren't hard to write and there's a pretty good comparison at [IOC Battle](http://www.iocbattle.com/). – Dustin Kingen Jun 11 '13 at 12:51

1 Answers1

4

With SimpleIoC

I'd add a public static property with a private string backend for a unique Key

something like

private static string _currentKey = System.Guid.NewGuid().ToString();
public static string CurrentKey {
  get {
    return _currentKey;
  }
  private set {
    _currentKey = value;
  }
}

and have the cleanup method to unregister VM's with current key and finally reset the current key(invoke on each app reset stage):

public static void Cleanup() {
  SimpleIoc.Default.Unregister<LoginViewModel>(CurrentKey);
  ...
  CurrentKey = System.Guid.NewGuid().ToString();
}

and when calling GetInstance(...) just pass in the static CurrentKey.

SimpleIoc.Default.GetInstance<LoginViewModel>(ViewModelLocator.CurrentKey);
Viv
  • 17,170
  • 4
  • 51
  • 71
  • worked for me but i still prefer to change the IOC Container. Nevertheless this is a working solution and therefore the correct answer. – Joel Jun 11 '13 at 15:56
  • @Joel well if you choose to change the IoC container to a more elaborate one, you can take Unity where you can give your instances an `ExternallyControlledLifetimeManager` which will just let the GC garbage collect the instance of the VM once nothing is having a strong reference to it after your logout. You have couple more Managers as well to manage Life-time of your objects. however there is absolutely nothing "wrong" in `SimpleIoC` regarding this – Viv Jun 11 '13 at 15:59
  • yeah i use Unity now. This was not about right or wrong it was just that `SimpeIoC` doesn't fit all of my needs. – Joel Jun 11 '13 at 17:36