3

Simple case: I have an interface for logging messages, like this:

public interface ILogger
{
   void Log(string message);
}

And maybe three different classes implement this interface.

Now, I could write in one place, line for DI, something like:

kernel.Bind<ILogger>().To<ConsoleLogger>();

My question is, how use that interface in many classes, but without injecting everyone via constructor. Because we can have so many different interfaces we want use, and declaration on that class constructor can be messy.

Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
mike00
  • 438
  • 1
  • 6
  • 17

4 Answers4

5

Having too many injected items in your constructor is a code smell. This normally means your class is doing more than one role. The single responsiblity principle says that each class should have only one purpose which is entirely encapsulated in the class.

Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
undefined
  • 33,537
  • 22
  • 129
  • 198
  • I think, there is small misunderstood. SRP can be broken if I would create this logging "engine" inside as a function in this class. But I want only, use in some classes this ILogger. I think, Dmitry has right. – mike00 May 21 '12 at 06:58
  • 2
    If you need to inject the ILogger in many classes, you are probably already violating the SRP, since logging is a cross cutting concern and should in many cases be modeled using interception or (even better) with decorators. – Steven May 21 '12 at 08:36
  • @Steven Can you provide sample? – mike00 May 21 '12 at 08:39
  • @Maniekb: Take a look at this question (and the answer): http://stackoverflow.com/questions/9892137/windsor-pulling-transient-objects-from-the-container. – Steven May 21 '12 at 08:47
2

In dependency injection, using property injection outside of legacy scenarios is considered poor form. Injecting a value via properties suggests its optional, and thus not really a dependency.

If you have a type that has lots and lots of constructor dependencies, that may suggest you need to do some refactoring. Perhaps some types are used together and can be refactored into their own component. Either way, if you are using an IoC framework such as Ninject, does it really matter how many constructor parameters a type takes? The container will do the injection for you regardless.

moribvndvs
  • 42,191
  • 11
  • 135
  • 149
  • +1 for highlighting the difference in intent between constructors and properties. -1 for proceeding down the path of maintenance / testing pain of unbridled parameter injection. – lzcd May 21 '12 at 00:56
1

While what @LukeMcGregor says it's true in general, a Logger looks like a cross-cutting concern, and could also be solved via AOP if you don't want to pollute every constructor with an ILogger. Ninject seems to support AOP via ninject.extensions.interception.

Filippo Pensalfini
  • 1,714
  • 12
  • 16
0

You can implement an ILogger Logger { get; set;} property in the classes and use the property injection feature that most IoC containers support.

Dmitry S.
  • 8,373
  • 2
  • 39
  • 49