Fear of using dependency injection system

I read about Injection Dependency frameworks. I really fell in love with the idea of ​​separating problems and letting the objects do their main work, which is undoubtedly a great and long-standing design!

However, the more I read about DI frameworks, the more I worry: 1) The way they "automatically" resolve dependencies 2) The extreme complexities that are introduced in configuration files

Only at point number 2, I saw how my customers spent millions of dollars training people on products, most of which was how not to touch configuration files. Administrators are now afraid of these configuration files.

However, I see another template called Service Locators, where I could collect all the "global" services that I want at the beginning of my application (maybe the application host or the application context or something else). Make this service locator available worldwide and voila!

However, I see that using the Service Locator approach will have less flexibility if I need more than one type of “global” service based on a specific criterion (known to whom?)!

So here I am more confused than before, in which direction to take. Although I really like the design principle, the complexity of existing frameworks throws me off!

Is my problem genuine? Does anyone else feel the same way? If so, is there a good alternative for such huge “frames”?

+4
source share
6 answers

As Nate mentioned, “magic” is optional; you can configure everything manually if you want.

I would first avoid configuration files (or forever!) And configure the container in code. It is usually much easier to read and maintain. In most cases, you do not need configuration changes on the fly. Clients cannot touch configuration files because they do not exist.

Service locators have flaws; firstly, they tend to associate your classes with the locator class / framework. A good DI structure allows you to use regular Stain objects; you can only have one class in your project that actually uses the DI / IoC framework.

StructureMap and Unity are pretty simple; try it. Start small.

Here is a really simple Unity example (including inline configuration):

using Microsoft.Practices.Unity; static void Main() { using (IUnityContainer container = new UnityContainer()) { container.RegisterType<IRobot, MrRoboto>(); Console.WriteLine("Asking Unity container to give us a Model..."); Model model = container.Resolve<Model>(); model.MoveRobot(); } } // class Model public Model(IRobot robot) { // Unity will hand the constructor an instance of MrRoboto! } 
+2
source

I personally enjoy using Autofac . Container configuration is done using code, while eliminating verbose XML and supporting refactoring support.

One of the best features is modules . These are container configuration units that let you control the complexity of the many different components that make up your application.

I am currently working on a very large project, and the experience is about the same as when it was small, which means that this approach scales very well.

The basic principle of DI-enabled classes is that they do not reference infrastructure code. This is the opposite of the Locator Service pattern. The main fall of Service Locator is that in addition to adding complexity to classes that reference the container, there is no way to change which version of the dependency is allowed.

With pure classes that do not reference the container, the permitted version of any given dependency is external to the class being introduced.

+3
source

If you are really thinking about switching to the dependency injection path, I highly recommend that you read the article on Martin Fowler's excellent injection:

http://martinfowler.com/articles/injection.html

I am working on a Java project right now with a lot of configuration files. We chose the Singleton model to represent our configuration (somewhat similar to the global solution). Here are the things that drive me crazy and make me want us to have a dependency dependency pattern:

  • Unit testing with globalized crap patterns. Injection pattern dependencies are easy to simplify unit testing and, in particular, testing objects. In the case of the singleton type, you now have all of these unit tests that still need the global state available to run. With dependency injection, you can create test-specific configuration objects that you pass into your tests. I cannot exaggerate how much easier unit testing makes this. Another great article called "Endo-Testing: Unit Testing with Mock Objects": http://connextra.com/aboutUs/mockobjects.pdf

  • Using a globalized approach works best on small systems, but as the number of threads grows, they begin to compete for configuration resources. You may run into synchronization issues, and access to settings can even become a bottleneck. This has not been a big problem for us, but it is starting to annoy us all.

  • As soon as you deviate slightly from the route of injection without dependence, a real return does not occur. The transition from dependency injection to some kind of globalized scheme is annoying, but can be done in stages. Trying to move from a globalized template to dependency injection is a nightmare. I always want to do this in our project, and I just can't. It takes a whole development cycle.

In any case, hope that the article and experience will help you make a decision. I have a long way down the path you are thinking of moving down, and I would like us to choose the dependency injection path: -D

+2
source

None of these are “mandatory” for DIs - these are options provided by some DI frameworks. Personally, I also don’t like the “automatic” injection - I see that it works on really small projects, but causes problems in large projects. For item # 2 - I'm not sure I realized that I mainly used Spring. Spring provides XML and Java configuration options. It provides nested configurations. If there is a part of the configuration that you do not want anyone to change, and there is some part that you do - separate them into separate configuration files - or create a “plug-in” one XML and another Java. Spring also supports the use of values ​​from property files, and that’s all I expect from administrators — administrators are not programmers — they should not "reconnect" your application by simply providing the appropriate parameters.

+1
source

Depending on the language you use, there are some DI frameworks that are not so scary, although you will have some configuration files, but they should not be scary, but useful.

For example, I have one configuration file for development, one for testing and one for production.

So, depending on what I use, database connections can be changed, and I can change the database level for tests and use mock tests.

Sidadmins should control production configuration files, since developers should not insert anything into production, ideally.

Spring has a good setup for DI, although it is not lightweight.

I found that the Unity Framework is not trivial to learn, but once you use it, it's pretty easy to add new classes for injection.

So, something new can be intimidating, initially, but as you enjoy the concept, you can see the benefits, for example, I explained the three configuration files.

0
source

My situation may differ from yours, because we already have a system designed for a very flexible configuration, so adding dependencies to this configuration was almost trivial, but it seems to me that using the service locator template will not save you a lot of settings since you should specify how to find a service. The ability to flexibly inject false objects for testing is an almost invaluable advantage of using dependency injection, so I would say that the overhead of configuration can be just the cost of what you have to take in order to get the benefits.

0
source

All Articles