views:

142

answers:

4

Other than testability, what's the big advantage of utilizing D.I. (and I'm not talking about a D.I. framework or IoC) over static classes? Particularly for an application where you know a service won't be swapped out.

In one of our c# application, our team is utilizing Dependency Injection in the web web GUI, the service layer, and the repository layer rather than using static methods. In the past, we'd have POCOs (busines entity objects) that were created, modified, passed around, and saved by static classes.

For example, in the past we might have written:

CreditEntity creditObj = CreditEntityManager.GetCredit(customerId);
Decimal creditScore = CreditEntityManager.CalculateScore(creditObj);
return creditScore;

Now, with D.I., the same code would be:

//not shown, _creditService instantiation/injection in c-tors
CreditEntity creditObj = _creditService.GetCredit(customerId);
Decimal creditScore = _creditService.CalculateScore(creditObj);
return creditScore;

Not much different, but now we have dozens of service classes that have much broader scope, which means we should treat them just as if they were static (i.e. no private member variables unless they are used to define further dependencies). Plus, if any of those methods utilize a resource (database/web service/etc) we find it harder to manage concurrency issues unless we remove the dependency and utilize the old static or using(...) methods.

+5  A: 

The question for D.I. might be: is CreditEntityManager in fact the natural place to centralize knowledge about how to find a CreditEntity and where to go to CalculateScore?

I think the theory of D.I. is that a modular application involved in thing X doesn't necessarily know how to hook up with thing Y even though X needs Y.

In your example, you are showing the code flow after the service providers have been located and incorporated in data objects. At that point, sure, with and without D.I. it looks about the same, even potentially exactly the same depending on programming language, style, etc.

The key is how those different services are hooked up together. In D.I., potentially a third party object essentially does configuration management, but after that is done the code should be about the same. The point of D.I. isn't to improve later code but to try and match the modular nature of the problem with the modular nature of the program, in order to avoid having to edit modules and program logic that are logically correct, but are hooking up with the wrong service providers.

DigitalRoss
So for in-house services/components that are not particularly encapsulated (i.e. we would never swap them out), D.I. doesn't provide a whole lot of benefit?
Jess
You still might want to plug in mock objects and services for unit testing. If you already have a test framework and you will never reconfigure the service hookups, or you already have an acceptable plugin architecture, then sure, you win without D.I., although any sort of plugin or test framework could arguably look sorta like the D.I. design pattern.
DigitalRoss
+1  A: 

It allows you to swap out implementations without cracking open the code. For example, in one of my applications, we created an interface called IDataService that defined methods for querying a data source. For the first few production releases, we used an implementation for Oracle using nHibernate. Later, we wanted to switch to an object database, so we wrote and implementation for db4o, added its assembly to the execution directory and changed a line in the config file. Presto! We were using db4o without having to crack open the code.

Travis Heseman
+1  A: 

This has been discussed exactly 1002 times. Here's one such discussion that I remember (read in order):

  1. http://scruffylookingcatherder.com/archive/2007/08/07/dependency-injection.aspx
  2. http://ayende.com/Blog/archive/2007/08/18/Dependency-Injection-More-than-a-testing-seam.aspx
  3. http://kohari.org/2007/08/15/defending-dependency-injection
  4. http://scruffylookingcatherder.com/archive/2007/08/16/tilting-at-windmills.aspx
  5. http://ayende.com/Blog/archive/2007/08/18/Dependency-Injection-IAmDonQuixote.aspx
  6. http://scruffylookingcatherder.com/archive/2007/08/20/poking-bears.aspx
  7. http://ayende.com/Blog/archive/2007/08/21/Dependency-Injection-Applicability-Benefits-and-Mocking.aspx

About your particular problems, it seems that you're not managing your services lifestyles correctly... for example, if one of your services is stateful (which should be quite rare) it probably has to be transient. I recommend that you create as many SO questions about this as you need to in order to clear all doubts.

Mauricio Scheffer
But if a service is transient, why instantiate an object? Wouldn't stateless objects logically be better represented by a static class?
Jess
When using a DI container you just code your service and then configure the container with the appropriate lifestyle for each service (this could also be per-web-request, per-thread or anything) To do that the service has to be instantiable. Please create other questions if you have doubts.
Mauricio Scheffer
+1 for giving an exact count. LOL!
TrueWill
A: 

There is a Guice video which gives a nice sample case for using D.I. If you are using a lot of 3-rd party services which need to be hooked upto dynamically D.I will be a great help.

whatnick