So far as I understand, SimpleIoc uses GetInstance method to retrieve an instance of a class that is registered. If the instance doesnt exist, it will create it. However, this instance is cached and always retrieved, which mimics the singleton pattern.
My thinking is that there is no need to keep an instance of ViewModel in a memory if there is a small possibility that this ViewModel will be needed twice, so I would like to create new instance of it each time that is needed. If we have are having a factory for ViewModels, we will have a property like this:
public MyViewMOdel MyViewModel
{
get { return SimpleIoc.Default.GetInstance<MyViewModel>(); }
}
this one uses singleton pattern, which I think is not best practice in all cases. In order to circumvent this problem, I do this:
public MyViewModel MyViewModel
{
get { return new MyViewModel(SimpleIoc.Default.GetInstance<ISomeInterface>()); }
}
This one has a disadvantage that if I ever change a constructor for MyViewModel, I will need to update this property also. Not big deal, but still there is some sort of dependency.
How do you handle this scenario, and is there something I am missing? and why it was decided not to have non-shared instance returned.
And another question is, in MVVM Deep dive session Laurent uses GetInstance method right after he registers a particular ViewModel, in order to, as he says, ensure that there is already an instance of this ViewModel in container. Why exactly is this necessary? If you are fetching a ViewModel through ViewModelLocator, then you will create it whenever required. So why would I want to have them created upfront?
You can get a different instance each time by passing a different key to the GetInstance method. However the instances will be cached, so if you do not want to keep them in the cache, you will need to call Unregister with the corresponding key.
In the demo, I was creating the VM upfront because the MainVM was sending messages to the SecondaryVM. Since the registration to the Messenger is done in the SecondaryVm's constructor, it needs to be created before it can start receiving messages. The Messenger is great because it is very decoupled, but it is one of these cases where you need to do extra work to compensate the decoupling: The SecondaryVM is the target of messages even though the MainVM does not get any reference to it.
Hope it makes sense. Cheers, Laurent
After wrestling with SimpleIoC to provide new instances each time a specific type is requested and finding out this feature is not implemented (the key-based method accepted above doesn't fit scenarios where you want to say, perform a database operation and throw the connection away each time), I came up with a relatively decent solution combining IoC with the Factory pattern: Create a class that takes the responsibility of instantiating new instances of a certain type through a function:
class MyObjectFactory: IMyObjectFactory
{
public MyObject CreateObject()
{
return new MyObject();
}
}
Create the interface for MyObject factory class:
public interface IMyObjectFactory
{
MyObject CreateObject();
}
Then configure the IoC container to provide the factory to any classes that use instances of MyObject:
SimpleIoc.Default.Register<IMyObjectFactory, MyObjectFactory>();
Now any class requiring a new instance of MyObject would declare its MyObjectFactory requirement (instead of MyObject requirement) in the constructor for constructor injection:
public class MyObjectUser
{
MyObject _myObject;
public MyObjectUser(IMyObjectFactory factory)
{
_myObject = factory.CreateObject();
}
}
This way I think you're not bound by the limitations of the Factory pattern and have all the benefits of IoC containers and Constructor Injection, circumventing SimpleIoC's limitation as well.
SimpleIOC is what it is ... a simple IOC container. It will have some shortcommings ... but you are not bound to it you could always use another ICO container (e.g. Unity, Autofac, Castle, ...).
As Laurent states he modelled his SimpleIOC on this container. He also mentions this container as a source of his inspiration.
However, remember you are not bound to use a secific container with MVVM. In several of my projects I used Unity, but every other IOC container will to equally well, it is a matter of requirements, customer preferences, and - if everything else fails - plain old personal gusto.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With