Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which pattern to use for logging? Dependency Injection or Service Locator?

Consider this scenario. I have some business logic that now and then will be required to write to a log.

interface ILogger {     void Log(string stuff); }  interface IDependency {     string GetInfo(); }  class MyBusinessObject {     private IDependency _dependency;      public MyBusinessObject(IDependency dependency)     {         _dependency = dependency;     }      public string DoSomething(string input)     {         // Process input         var info = _dependency.GetInfo();         var intermediateResult = PerformInterestingStuff(input, info);          if (intermediateResult== "SomethingWeNeedToLog")         {             // How do I get to the ILogger-interface?         }          var result = PerformSomethingElse(intermediateResult);          return result;     } } 

How would you get the ILogger interface? I see two main possibilities;

  1. Pass it using Dependency Injection on the constructor.
  2. Get it via a singleton Service Locator.

Which method would you prefer, and why? Or is there an even better pattern?

Update: Note that I don't need to log ALL method calls. I only want to log a few (rare) events that may or may not occur within my method.

like image 814
CodingInsomnia Avatar asked Apr 21 '10 11:04

CodingInsomnia


People also ask

What's the difference between the dependency injection and service locator patterns?

The main difference is how the dependencies are located, in Service Locator, client code request the dependencies, in DI Container we use a container to create all of objects and it injects dependency as constructor parameters (or properties). Dependency Injection doesn't require the use of a DI Container though.

What type of design pattern is dependency injection?

In software engineering, dependency injection is a design pattern in which an object or function receives other objects or functions that it depends on. A form of inversion of control, dependency injection aims to separate the concerns of constructing objects and using them, leading to loosely coupled programs.

Is service locator an anti pattern?

Service Locator is a dangerous pattern because it almost works. You can locate Dependencies from consuming classes, and you can replace those Dependencies with different implementations — even with Test Doubles from unit tests.

What is the main reason for using the dependency injection design pattern?

The dependency injection technique enables you to improve this even further. It provides a way to separate the creation of an object from its usage. By doing that, you can replace a dependency without changing any code and it also reduces the boilerplate code in your business logic.


1 Answers

I personally do a mixture of both.

Here are my conventions:

  • From a static context - Service Location
  • From an instance context - Dependency Injection

I feel this gives me the right balance of testability. I find it a little harder to setup tests against classes that use Service Location than use DI, so this is why Service Location ends up being the exception rather than the rule. I'm consistent in its use, though, so it's not hard to remember what type of test I need to write.

Some have raised the concern that DI tends to clutter constructors. I don't feel this is a problem, but if you feel this way, there are a number of alternatives that use DI, but avoid constructor parameters. Here is a list of Ninject's DI methods: http://ninject.codeplex.com/wikipage?title=Injection%20Patterns

You'll find that most Inversion of Control containers have the same features as Ninject. I chose to show Ninject because they have the most concise samples.

Hopefully this is helpful.

Edit: To be clear, I use Unity and Common Service Locator. I have a singleton instance of my Unity container for DI and my implementation of IServiceLocator is simply a wrapper around that singleton Unity container. This way I don't have to do any type mappings twice or anything like that.

I also don't find AOP to be particularly helpful beyond tracing. I like manual logging better simply for its clarity. I know that most AOP logging frameworks are capable of both, but I don't need the former (AOP's bread and butter) most of the time. This is just personal preference, of course.

like image 165
Anderson Imes Avatar answered Oct 13 '22 01:10

Anderson Imes