4

With infrastructure items like loggers, security, configuration and so forth, should these things really be injected to every class that needs them or should they be injected into a service locator and then the classes can use the service locator to resolve the dependencies (or some other mechanism)?

It just looks really ridiculous with all classes having 10 parameter ctors to satisfy dependencies via DI. Its a code smell IMO. I can understand things like repositories or service proxies/connectors but not logging.

ILovePaperTowels
  • 1,445
  • 2
  • 17
  • 30
  • 1
    You can inject them to a global application context. and consume from that. after all, container is a singleton of singletons. – DarthVader Jun 01 '12 at 16:28
  • 2
    The smell may not be coming from your DI, but rather from your 10-parameter class that might violate the philosophy of doing-one-thing-and-doing-it-well. – qxn Jun 01 '12 at 16:58
  • @ken Thats my point, DI isn't a smell, it's the 10 param ctor. – ILovePaperTowels Jun 01 '12 at 17:02

3 Answers3

4

there are a couple of options.

  1. use property injection and set the default in the ctor. for example

    class foo 
    {
        public ILogger Logger {get;set;}
    
        public foo()
        {
           Logger = NullLogger.Instance;
        }
    }
    
  2. use an AOP type approach. using a dynamic proxy you can wrap public calls with logging statements but the logging is never actually injected into the component itself. See Castle.DynamicProxy or custom .Net Attribute for more ideas on this approach.

then there is the question, why are so many infrastructure concerns being injected into the component? what you describe are considered cross cutting concerns and typically this is handled through some for of AOP (aspect oriented programming) so there isn't a lot of duplication in the core system.

Jason Meckley
  • 7,589
  • 1
  • 24
  • 45
  • 2
    +1 for AOP. Normaly I would agree with you on AOP, but I'm not a fan of runtime AOP frameworks and the team doesn't understand AOP concepts. They barely understand IoC concepts. – ILovePaperTowels Jun 01 '12 at 16:35
  • I fully understand :) your better option then is #1 with optional property injection. I cannot stand service locator. it feels wrong like a shim for pure IoC. – Jason Meckley Jun 01 '12 at 18:27
2

It all depends on where you draw the line between infrastructure and the rest of the code. Do you consider a database connection to be infrastructure? I do not.

Property injection is a code smell since it hides the dependencies and the classes are not properly initialized when the constructor is done. Only use it to solve cyclic dependencies.

For the very specific case of logging I do use a singleton to get the logger.

Normaly I would agree with you on AOP, but I'm not a fan of runtime AOP frameworks and the team doesn't understand AOP concepts. They barely understand IoC concepts

You might find my IoC introduction useful.

jgauffin
  • 99,844
  • 45
  • 235
  • 372
1

Regarding logging - Just use NLog (or your favorite logger) and be done with it. Unless you are in a really strange scenario, there is no reason to abstract and/or inject your logger.

Regarding configuration - Only a few classes should be consumers of configuration, so this shouldn't cause constructor bloat. See also this question for a good discussion of configuration and DI.

Regarding security - Again, I think only a few classes should be consumers of security dependencies. If many classes are concerned with security, you might need to revisit your design.

In general - If a class has too many constructor parameters, it's probably because it's doing too much, regardless of whether the dependencies are infrastructural.

Community
  • 1
  • 1
default.kramer
  • 5,943
  • 2
  • 32
  • 50