Is it a good idea to register views and view models as singletons in an IOC container

dependency-injectiondesign-patterns

I understand the benefits of injecting dependencies into objects, but have not found much guidance on the types of objects to inject and when to make them singletons.

If we take as as example an application with the following types of objects:

  • Services (including repositories and business services such as calculateprice)
  • Views
  • ViewModels

Services

Injecting services is the typical example given and it is clear these are not registered as singletons in the container as they are statelesss.

Was it the original intention that only services should be injected by containers?

Views/ViewModels & other stateful long lasting objects

The general way to access a long lasting object in several places has been to use a registry (or similar), assuming we cannot pass it around as a parameter. Now we have the option to register the object as a singleton in a container and inject it where needed.

I can't see any problem using the singleton in a container approach beyond the issue of removing the object from the container when its lifecycle ends (not sure how easy that is going to be – I use Unity).

Would be interested to hear of any problems others can forsee.

As an interesting aside, the MVVM Light framework uses a ViewModelLocator rather than injecting viewmodels.

Best Answer

Well, it depends on what you need. If you'll never ever have two or more views of the same type, then I guess it's ok to register them as singletons.

But then, what if you have a view composed of two other views (and their view models), for instance, if you are comparing some data? You'll can't use the same instance, since you need to populate those with different data.

Also if you have many views, and some type of navigation, where each view gets created when you get to it, then those singleton views would linger on somewhere when you navigate away from them. The container would be keeping a reference, and they would never get collected.

EDIT: With regard to your comment, I think you wouldn't have any issues if you registered the view as a singleton. Having said that, I wouldn't do it. I usually use "singletons" for stateless (or statefull, but where the state can't be changed after it's set when instantiated the first time) objects like repositories, or objects that absolutely have to be single instances during the whole application lifetime. In MVVM that would be some controller which is responsible for managing views (for navigation). I'd leave the views themselves, and their view models as normal objects, even if at first I'll be using just one of them. This is just my preference, though.

PS: I don't have experience with MVVM Light, but using the container as a service locator is generally considered an anti-pattern by many, as you are introducing a dependency to the container. Your views and view models (and domain models) should be as free as possible of the "infrastructure" constructs such as the container. When your code gets to the view model, it should just have all that it needs, and not look for it using the container.