Service locator - is it worth it?

We have a great solution (> 100 projects), and almost every type uses either a service locator (example 1) or our own type dictionary (example 2) to create an instance.

For example, we have:

IQuote quote = Registry.Resolve<IQuote>(); 

or

 IQuote quote = Registry.Find<IQuote>(args); 

The second example is disabled in the configuration file to find a specific object to instantiate using reflection.

This complicates life when using the code - because it is not clear which particular type is used, so we have to check the mappings many times, as we try to learn a part of the code. Using the example above, pressing F12 on: quote.DoSomething() will lead you to an interface definition.

This is also a bit more difficult to implement - we need interfaces + concrete class mappings ++, when the alternative is just 1 class.

Think about it - I don’t know what has ever been "replaced" by another type, therefore, although we implemented IoC, we did not use it, or at least very little.

So, is it really worth it? Have we implemented this / too much? I do not understand something?

+6
source share
5 answers

In my opinion, you do not need to work with each class with DI. I would use the following strategy:

  • Define the boundaries of the module.
  • Whenever possible, use specific classes inside the same module.
  • For intermodular communication, use DI where possible.

Modules should be relatively fine-grained.

There are some common places where you need to use DI, often these are removable data sources and (not so often) algorithms. Use common sense to check if something needs to be replaced or not. Feel free to give up early refactoring if you see that something needs a DI or suffers from it.

+4
source

What you guys are using is a Locator , which is considered an anti-pattern, due to:

  • All unit tests must use Locator <(with DI no DI Container )
  • You link your entire architecture with the Service Locator (in DI, only Root of Composition uses the DI Container )
  • It is not possible to immediately see component dependencies (with DI Constructor Injection )
  • Testing your device is becoming more complicated because you have to take care of your configuration so that no other test mistakenly uses a different configuration (Tear Down).

http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx

+4
source

What you are showing is not dependency injection, it is a custom registry (which is also a template, but completely different). So yes, it sounds like a bad idea and a kind of misunderstanding.

To be able to take advantage of a design pattern, you must understand the benefits in advance. If you do not know them, then you probably should not worry.

+2
source

If you're a unit test, dependency injection is needed to nullify or bully ... dependencies. (Unit tests should not affect dependencies such as file system, database, network, etc.)

+1
source

I think that you are misleading the more general concept of Injection Dependency using a DI container, which is a means to the end of implementing a very flexible form of DI. Here's a good article explaining DI as a concept.

In your scenario, it seems to me that you can get rid of the DI container, but you might still want to keep some form of DI, if only for verification (as others have already pointed out). The general implementation scheme for this is the implementation of "wide" constructors through which dependencies can be introduced and which are used in unit tests. In addition, narrower constructors will be created that will create specific classes and pass them to the "wide" constructor. They can be used in production code until there is a need for an actual exchange around dependencies.

Example:

 class MyClass { // This will be called from production code public MyClass() : this(new Foo(), new Bar()) {} // This will be called from tests and can be used in production code if needed public MyClass(IFoo foo, IBar bar) { //do whatever you want to do in the ctor here } } 
0
source

Source: https://habr.com/ru/post/919433/


All Articles