0

Context: WPF MVVM App using Prism

We have a ServiceLocator that is responsible for returning the singleton instances of our ViewModel classes.

For example:

var viewModel = ServiceLocator.Default.GetInstance<MyViewModel>();

Is there a reason why I shouldn't just simplify that access to something like:

class MyViewModel 
{
    public static MyViewModel Instance => ServiceLocator.Default.GetInstance<MyViewModel>();
}

And so in this way, usage would be:

var viewModel = MyViewModel.Instance;

What are the advantages/disadvantages?

From what I can tell:

Disadvantage: would be adding the dependency on ServiceLocator to MyViewModel.

Advantage: much simpler access and readability. The app already has a dependency on ServiceLocator anyways

  • _"What are the disadvantages?"_ - You lose testability. You gain mutable shared state (bad). You lose the ability to have multiple open windows of the same type, but with different data. You lose compatibility with `Microsoft.Extensions.DependencyInjection` (which replaced `ServiceLocator` over half a decade ago). [You lose](https://www.youtube.com/watch?v=fpK36FZmTFY) everything and gain nothing. – Dai Mar 24 '23 at 23:45
  • 1
    Also, [`ServiceLocator` is an anti-pattern](https://freecontent.manning.com/the-service-locator-anti-pattern/): https://stackoverflow.com/questions/22795459/is-servicelocator-an-anti-pattern – Dai Mar 24 '23 at 23:48
  • What do you mean by "ServiceLocator injected via the constructor"? That's no different to passing `IServiceProvider`. – Dai Mar 25 '23 at 00:21
  • 1
    You should use dependency injection and logical singletons rather than static classes. And you should have some way of getting to that di container in your app that allows testing mocks to work. Some sort of mock able service finder ticks those boxes. Any service locator should be providing objects for ctor – Andy Mar 25 '23 at 00:24
  • singleton view models are undesirable, too – Haukinger Mar 25 '23 at 07:15
  • Having a static instance usually tries to solve the problem that you want to *share* a particular instance. Aside from already mentioned drawbacks, you mess up instance lifetimes: the static instance and *all* its references (reference tree) will be kept alive for lifetime of the application i.e. garbage collector won't collect it (leak). For example when the static instance allocates resources or has a collection of instances or references instances that themselves have expensive allocations, then all those instances are forcefully kept alive (in memory) and continue to block resources. – BionicCode Mar 25 '23 at 10:39
  • You usually solve it by creating a shared instance which you pass to the constructor of the classes that depend on this shared instance. In a larger scope you would use dependency injection to manage shared dependencies or object lifetime in general (and also eliminate the service locator). Your mentioned advantages are none: because Service Locator hides dependencies you negatively impact readability. You compromise/eliminate extensibility and testability. When something is difficult to read and to extend it is always difficult to maintain too. – BionicCode Mar 25 '23 at 10:40
  • Additionally, you violate data encapsulation rules (public static variables are globally visible/exposed). Service Locator or Singleton usually leads to bad class design that impairs readability, extensibility and maintainability further more. Access is *not* simpler (simpler than what?). Local instances are always "simpler" and more intuitive to access. The only public static variables should be constants. – BionicCode Mar 25 '23 at 10:40
  • That the application already infected with the Service Locator pattern doesn't mean you have to spread the pestilence any further. Leave the code smells to the legacy code and write fresh code that implements best practices according to your best knowledge. Write code that encourages good class design. You obviously have a choice. Why implement something when disadvantages outweigh any advantages and when there are robust and clean alternatives? – BionicCode Mar 25 '23 at 10:40
  • Why do you all reply as comments instead of posting a reply? It's difficult to read. I bought the book linked above. – lavantgarde Mar 29 '23 at 20:45

0 Answers0