Abstract
For the past few months I have been programming a light weight, C# based game engine with API abstraction and entity/component/scripting system. The whole idea of it is to ease the game development process in XNA, SlimDX and such, by providing architecture similar to that of the Unity engine.
Design challenges
As most game developers know, there are a lot of different services you need to access throughout your code. Many developers resort to using global static instances of e.g. a Render manager(or a composer), a Scene, Graphicsdevice(DX), Logger, Input state, Viewport, Window and so on. There are some alternative approaches to the global static instances/ singletons. One is to give each class an instance of the classes it needs access to, either through a constructor or constructor/property dependency injection(DI), another is to use a global service locator, like StructureMap's ObjectFactory where the service locator is usually configured as an IoC container.
Dependency Injection
I chose to go the DI way for many reasons. The most obvious one being testability, by programming against interfaces and have all the dependencies of every class provided to them through a constructor, those classes are easily tested since the test container can instantiate the required services, or the mocks of them, and feed into every class to be tested. Another reason for doing DI/IoC was, believe it or not, to increase the readability of the code. No more huge initialization process of instantiating all the different services and manually instantiating classes with references to the required services. Configuring the Kernel(NInject)/Registry(StructureMap) conveniently gives a single point of configuration for the engine/game, where service implementations are picked and configured.
My problems
I often feel like I am creating interfaces for interfaces sake
My productivity has gone down dramatically since all I do is worry about how to do things the DI-way, instead of the quick and simple global static way.
In some cases, e.g. when instantiating new Entities on runtime, one needs access to the IoC container / kernel to create the instance. This creates a dependency on the IoC container itself (ObjectFactory in SM, an instance of the kernel in Ninject), which really goes against the reason for using one in the first place. How can this be resolved? Abstract factories come to mind, but that just further complicates the code.
Depending on service requirements, some classes' constructors can get very large, which will make the class completely useless in other contexts where and if an IoC is not used.
Basically doing DI/IoC dramatically slows down my productivity and in some cases further complicates the code and architecture. Therefore I am uncertain of whether it is a path I should follow, or just give up and do things the old fashioned way. I am not looking for a single answer saying what I should or shouldn't do but a discussion on if using DI is worth it in the long run as opposed to using the global static/singleton way, possible pros and cons I have overlooked and possible solutions to my problems listed above, when dealing with DI.
Should you go back to the old-fashioned way?
My answer in short is no. DI has numerous benefits for all the reasons you mentioned.
I often feel like I am creating interfaces for interfaces sake
If you are doing this you might be violating the
Reused Abstractions Principle (RAP)
Depending on service requirements, some classes' constructors can get
very large, which will make the class completely useless in other
contexts where and if an IoC is not used.
If your classes constructors are too large and complex, this is the best way to show you that you are violating a very important other principle:
Single Reponsibility Principle. In this case it is time to extract and refactor your code into different classes, the number of dependencies suggested is around 4.
In order to do DI you don't have to have an interface, DI is just the way you get your dependencies into your object. Creating interfaces might be a needed way to be able to substitute a dependency for testing purposes.
Unless the object of the dependency is:
Easy to isolate
Doesn't talk to external subsystems (file system
etc)
You can create your dependency as an Abstract class, or any class where the methods you'd like to substitute are virtual. However interfaces do create the best de-coupled way of an dependency.
In some cases, e.g. when instantiating new Entities on runtime, one
needs access to the IoC container / kernel to create the instance.
This creates a dependency on the IoC container itself (ObjectFactory
in SM, an instance of the kernel in Ninject), which really goes
against the reason for using one in the first place. How can this be
resolved? Abstract factories come to mind, but that just further
complicates the code.
As far as a dependency to the IOC container, you should never have a dependency to it in your client classes.
And they don't have to.
In order to first use dependency injection properly is to understand the concept of the Composition Root. This is the only place where your container should be referenced. At this point your entire object graph is constructed. Once you understand this you will realize you never need the container in your clients. As each client just gets its dependency injected.
There are also MANY other creational patterns you can follow to make construction easier:
Say you want to construct an object with many dependencies like this:
new SomeBusinessObject(
new SomethingChangedNotificationService(new EmailErrorHandler()),
new EmailErrorHandler(),
new MyDao(new EmailErrorHandler()));
You can create a concrete factory that knows how to construct this:
public static class SomeBusinessObjectFactory
{
public static SomeBusinessObject Create()
{
return new SomeBusinessObject(
new SomethingChangedNotificationService(new EmailErrorHandler()),
new EmailErrorHandler(),
new MyDao(new EmailErrorHandler()));
}
}
And then use it like this:
SomeBusinessObject bo = SomeBusinessObjectFactory.Create();
You can also use poor mans di and create a constructor that takes no arguments at all:
public SomeBusinessObject()
{
var errorHandler = new EmailErrorHandler();
var dao = new MyDao(errorHandler);
var notificationService = new SomethingChangedNotificationService(errorHandler);
Initialize(notificationService, errorHandler, dao);
}
protected void Initialize(
INotificationService notifcationService,
IErrorHandler errorHandler,
MyDao dao)
{
this._NotificationService = notifcationService;
this._ErrorHandler = errorHandler;
this._Dao = dao;
}
Then it just seems like it used to work:
SomeBusinessObject bo = new SomeBusinessObject();
Using Poor Man's DI is considered bad when your default implementations are in external third party libraries, but less bad when you have a good default implementation.
Then obviously there are all the DI containers, Object builders and other patterns.
So all you need is to think of a good creational pattern for your object. Your object itself should not care how to create the dependencies, in fact it makes them MORE complicated and causes them to mix 2 kinds of logic. So I don't beleive using DI should have loss of productivity.
There are some special cases where your object cannot just get a single instance injected to it. Where the lifetime is generally shorter and on-the-fly instances are required. In this case you should inject the Factory into the object as a dependency:
public interface IDataAccessFactory
{
TDao Create<TDao>();
}
As you can notice this version is generic because it can make use of an IoC container to create various types (Take note though the IoC container is still not visible to my client).
public class ConcreteDataAccessFactory : IDataAccessFactory
{
private readonly IocContainer _Container;
public ConcreteDataAccessFactory(IocContainer container)
{
this._Container = container;
}
public TDao Create<TDao>()
{
return (TDao)Activator.CreateInstance(typeof(TDao),
this._Container.Resolve<Dependency1>(),
this._Container.Resolve<Dependency2>())
}
}
Notice I used activator even though I had an Ioc container, this is important to note that the factory needs to construct a new instance of object and not just assume the container will provide a new instance as the object may be registered with different lifetimes (Singleton, ThreadLocal, etc). However depending on which container you are using some can generate these factories for you. However if you are certain the object is registered with Transient lifetime, you can simply resolve it.
EDIT: Adding class with Abstract Factory dependency:
public class SomeOtherBusinessObject
{
private IDataAccessFactory _DataAccessFactory;
public SomeOtherBusinessObject(
IDataAccessFactory dataAccessFactory,
INotificationService notifcationService,
IErrorHandler errorHandler)
{
this._DataAccessFactory = dataAccessFactory;
}
public void DoSomething()
{
for (int i = 0; i < 10; i++)
{
using (var dao = this._DataAccessFactory.Create<MyDao>())
{
// work with dao
// Console.WriteLine(
// "Working with dao: " + dao.GetHashCode().ToString());
}
}
}
}
Basically doing DI/IoC dramatically slows down my productivity and in
some cases further complicates the code and architecture
Mark Seeman wrote an awesome blog on the subject, and answered the question:
My first reaction to that sort of question is: you say loosely coupled code is harder to understand. Harder than what?
Loose Coupling and the Big Picture
EDIT: Finally I'd like to point out that not every object and dependency needs or should be dependency injected, first consider if what you are using is actually considered a dependency:
What are dependencies?
Application Configuration
System Resources (Clock)
Third Party Libraries
Database
WCF/Network Services
External Systems (File/Email)
Any of the above objects or collaborators can be out of your control and cause side effects and difference in behavior and make it hard to test. These are the times to consider an Abstraction (Class/Interface) and use DI.
What are not dependencies, doesn't really need DI?
List<T>
MemoryStream
Strings/Primitives
Leaf Objects/Dto's
Objects such as the above can simply be instantiated where needed using the new keyword. I would not suggest using DI for such simple objects unless there are specific reasons. Consider the question if the object is under your full control and doesn't cause any additional object graphs or side effects in behavior (at least anything that you want to change/control the behavior of or test). In this case simply new them up.
I have posted a lot of links to Mark Seeman's posts, but I really recommend you read his book and blog posts.
Related
I am getting deeper into the Dependency Injection concept and more I read, more I like the idea behind it. I have been using it for some time already, but still many things confuse me every now and then, and I feel that I am not using its full potential.
Imagine the code below. In this class, (probably a few things can be improved but..) we have one method that returns a string value. There is no need for constructor injection (or at least that's what I think, correct me if I am wrong), but then at the last line in the try block, we create new instance of the StreamReader class to be able to pass the response stream to it and to get the result using the ReadToEnd method.
The idea behind Dependency Injection is to avoid creating instances inside a class, but how to deal with this scenario?
public class WebClientService : IWebClientService
{
public async Task<String> GetApiResponseAsync(string Url)
{
String responseText = await Task.Run(() =>
{
try
{
HttpWebRequest request = WebRequest.Create(Url) as HttpWebRequest;
WebResponse response = request.GetResponse();
Stream responseStream = response.GetResponseStream();
return new StreamReader(responseStream).ReadToEnd();
}
catch (Exception e)
{
LogMessageDispatcher.Instance.Log(e);
}
return null;
});
return responseText;
}
}
I am going over 'Mark Seemann's book - Dependency Injection', but I still have a lot to cover.
This is a very trivial example and relatively easy to define as your coupling is a basic Class without any service related functionality. Let's start from the definition of DI in wikipedia:
In software engineering, dependency injection is a technique whereby one object supplies the dependencies of another object. A "dependency" is an object that can be used, for example as a service. Instead of a client specifying which service it will use, something tells the client what service to use. The "injection" refers to the passing of a dependency (a service) into the object (a client) that would use it. The service is made part of the client's state.[1] Passing the service to the client, rather than allowing a client to build or find the service, is the fundamental requirement of the pattern.
What does that mean though. Should we never create a StringBuilder object when we use DI? The answer is no (or better yet not always). Can I create a new float without DI? Would it make sense to create a builder service and create the StreamReader from there?
You will see that StreamReader is a very basic implementation public class StreamReader : System.IO.TextReader and the classes do not even implement any other interface other than IDisposable. You can't seriously consider injecting StreamReader for IDisposable in any class.
If you want to decouple from StreamReader then that means that you might want to use something else in the future. You could create a StreamService and create your stream however you like, but at the end of the day the StreamService would have the Coupling as StreamReader can't be injected.
That's why wikipedia infers that Services are injected. Objects might be decoupled but you might want to use other patterns like Factory.
By the way use StreamReader always with the Using keyword so that the object can be properly disposed of.
Dependency Injection is powerful in some points
Testing : Decoupling is essential for unit testing and DI is the good way to achieve that so you can have one interface and Multiple implementations and based on what you want you can write unit test for your code and inject specific concrete class.
Control objects creation : It give you control on how (specific) objects get created and what is the life time of your objects.
So you have to know at the beginning
What type of classes and interfaces you want to centralize/control their objects creation ?
What is the functionality that if any changes happens to it in the future you want your code to keep working without big changes ?
In your case you are using StreamReader, it's a built-in class in C# so you have to think about How many times I'm going to use that class in my code? Do I need to change it in the future?
If I were you I'll think about two options
I don't care about the StreamReader it's a built-in class in C# ,it works well and I'm not going to write unit test to test the StreamReader functionality so I'll use it like what you did in your code sample.
I'm using StreamReader in many places in the code and I've some repeated logic I used to do every time after reading stream so I'll create IStreamReader interface with the main methods I want to use then use the DI to inject the concrete implementation.
Note: while using DI you are not going to Inject all the Objects in your system.
The idea behind Dependency Injection is to avoid creating instances inside a class, but how to deal with this scenario?
That's not at all the point. One of the central points of DI is to enable loose coupling to Volatile Dependencies. Not all types a class depends on are volatile. Some are stable and there is no need to prevent creating stable dependencies from within a class. Chapter one of both Dependency Injection in .NET (by Mark Seemann) and its successor Dependency Injection Principles, Practices, and Patterns (by Mark and I) have a detailed description of what Volatile Dependencies and Stable Dependencies are and how they differ.
The main question you should ask is whether any of the types that WebClientService depend on are Volatile Dependencies or not. The answer depends on your particular context, and you should be able to figure this out after (re)reading chapter 1. This chapter can be read online freely.
I'm working on a project that uses Unity Dependancy injection but the load performance is slowly getting worse. I am trying to adjust the code to utilise Lazy<T> (or Func<T>) so i'm trying to find a way to either register the classes with the container using Lazy<T> (or Func<T>) or have some sort of factory that could either adjust the registered types or the constructor but i am not able to seem to find a possible way to do this
At present i have numerous service classes like
public Service1(IClassLogic<GetReq, GetRes> getClass, IClassLogic<AddReq, AddRes> addClass, IClassLogic<UpdateReq, UpdateRes> updateClass, IClassLogic<DeleteReq, DeleteRes> deleteClass....){...}
then i have registrations similar to
container.RegisterType<IClassLogic<GetReq, GetRes>, GetClass>();
container.RegisterType<IClassLogic<AddReq, AddRes>, AddClass>();
container.RegisterType<IClassLogic<UpdateReq, UpdateRes>, UpdateClass>();
container.RegisterType<IClassLogic<DeleteReq, DeleteRes>, DeleteClass>();
...
Ideally i would like not to have to go an change all the signatures to
public Service1(Lazy<IClassLogic<GetReq, GetRes>> getClass, Lazy<IClassLogic<AddReq, AddRes>> addClass...
Any pointers would be greatly appreciated
Prevent using Func<T> and Lazy<T> as dependencies to prevent slow object graph initialization. These are leaky abstractions, because they leak implementation details into the consumer. The implementation detail here is that such service is costly to create.
The fact that it takes too much time to create a dependency is an indication that your injection constructors do too much, while they should be simple, fast and reliable.
Another obvious problem is the Single Responsibility Principle violation in your components. Having more than 5 dependencies in a constructor is a code smell and an indication of a Single Responsibility Principle violation. Some containers get slower when you need to resolve really big object graphs, but when you make your components small and focussed, this problem will quite likely go away, since the object graph to construct will be much smaller.
First off some tips concerning DI in general:
You're right, you do not want to change the signature of the constructor. You're IoC container (Unity in your case) should enable you to design the interfaces and consumers as you like. Otherwise it isn't a good container.
When struggling starting with DI (and containers) I would advise wiring it up yourself. This gives you great insight in how it works and provides flexibility. Mark Seemann has written a lot about this stuff.
Your service's dependencies seem awfully crowded. Can't you refactor to less dependencies by combining some (maybe by a Facade)?
Making interfaces specific (not generic) makes things a lot simpler. Generics sometimes cause more harm than good.
I've coded up a quick example which compiles (I haven't tested it). I've used a generic interface in line with your example but used some fake implementation and string types as generic params (which aren't used):
If this is an implementation of an interface:
public class ClassLogic : IClassLogic<string, string>
{
public void Do()
{
// do stuff
}
}
Then you could implement a provider which only creates the implementation when needed (via a given Func) like this:
public class ClassLogicProvider : IClassLogic<string, string>
{
private readonly Func<IClassLogic<string, string>> innerLogicFactory;
public ClassLogicProvider(Func<IClassLogic<string, string>> innerLogicFactory)
{
this.innerLogicFactory = innerLogicFactory;
}
public void Do()
{
var classLogic = this.innerLogicFactory();
classLogic.Do();
}
}
And wire it up like this:
var container = new UnityContainer();
Func<IClassLogic<string, string>> classLogicFunc = () =>
{
// Create implementation on demand
return new ClassLogic();
};
container.RegisterType<IClassLogic<string, string>>(
new InjectionFactory(c => {
return new ClassLogicProvider(classLogicFunc);
})
);
This should give you the desired Lazy creation when to implementation is needed.
It should be a very quick question. I am trying to learn CQRS pattern and there is one thing which is not clear. There are two dispatchers: for commands and queries. Both of them need to have DI kernel injected in order to get appropriate handler. For example:
var handler = _resolver.Resolve<IQueryHandler<TQuery, TResult>>();
Isn't it violating the concept of DI that Resolve should never be used and everything should be injected with constructor/properties?
There is a bigger example: http://www.adamtibi.net/06-2013/implementing-a-cqrs-based-architecture-with-mvc-and-document-db
Please check out this method:
public void Dispatch<TParameter>(TParameter command) where TParameter : ICommand
{
var handler = _kernel.Get<ICommandHandler<TParameter>>();
handler.Execute(command);
}
I've found this solution on 3 different pages. Why is it done this way instead of creating a factory to map Query to QueryHandler?
If you consider the dispatcher to be a part of the infrastructure, calling Resolve() within it does not violate the DI concept you describe.
Handlers are generally thought of as entry points for logic pipelines (or threads, or however you want to think of them). This is similar to controllers in MVC, or the Main() method in a console application. So like these other constructs, the dispatcher is considered a top-level object in the dependency chain, and is thus a perfectly legitimate place to reference the container.
Edit
So the comments mention Composition Root (CR), which is a term I like but deliberately tried to avoid in this answer, as it tends to confuse people. Is the CR a specific class? An assembly? I tend to think of it more as a concept than a specific construct. It's the logical place in the application where object graphs are composed.
To clarify what I meant about controllers: the controllers would be the entry point, and (as #Zbigniew noted) the controller factory would be (part of) the CR. Similarly, handlers would be the entry point, and the dispatcher would be the CR. Handlers/Controllers would not have a reference to the container, but the Dispatcher/ControllerFactory would.
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;
Pass it using Dependency Injection on the constructor.
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.
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.
The logger is clearly a service that your business logic depends upon, and should thus be treated as a dependency the same way you do with IDependency. Inject the logger in your constructor.
Note: even though AOP is mentioned as the way to inject logging I do not agree that it is the solution in this case. AOP works great for execution tracing, but will never be a solution for logging as part of business logic.
My little rule of thumb:
If it's in a class library, use either constructor injection or property injection with a null-object pattern.
If it's in a main application, use the service locator (or singleton).
I find this applies pretty well when using log4net. You don't want class libraries reaching out to things that might not be there, but in an application program, you know that the logger is going to be there, and libraries like log4net are based heavily around the service-location pattern.
I tend to think of logging as something sufficiently static that it doesn't really need DI. It's extremely unlikely that I'll ever change the logging implementation in an application, especially since every logging framework out there is incredibly flexible and easy to extend. It's more important in class libraries when your library might need to be used by several applications which already use different loggers.
YMMV, of course. DI is great but that doesn't mean everything needs to be DI'ed.
Maybe this will be little offtopic, but why do we need injecting logger at all, when we can just type at the beggining of the class:
Logger logger = LogManager.GetLogger("MyClassName");
Logger doesn't change during development and later during maintenance. Modern loggers are highly customizable, so argument
what if I want to replace text logger with database?
is missed.
I don't negate using dependency injection, I'm just curious about your mind.
We switched all our Logging/Tracing to PostSharp (AOP framework) attributes. All you need to do to create logging for a method is add the attribute to it.
Benefits:
Easy use of AOP
Clear separation of concerns
Happens at compile time -> Minimal performance impact
Check out this.
I would prefer Singleton Service.
Dependency injection would clutter the constructor.
If you can use AOP, that would be the best.
You could derive another type e.g. LoggableBusinessObject that takes a logger in its constructor. This means you only pass in the logger for objects that will use it:
public class MyBusinessObject
{
private IDependency _dependency;
public MyBusinessObject(IDependency dependency)
{
_dependency = dependency;
}
public virtual string DoSomething(string input)
{
// Process input
var info = _dependency.GetInfo();
var result = PerformInterestingStuff(input, info);
return result;
}
}
public class LoggableBusinessObject : MyBusinessObject
{
private ILogger _logger;
public LoggableBusinessObject(ILogger logger, IDependency dependency)
: base(dependency)
{
_logger = logger;
}
public override string DoSomething(string input)
{
string result = base.DoSomething(input);
if (result == "SomethingWeNeedToLog")
{
_logger.Log(result);
}
}
}
DI would work nicely here. Another thing to look at would be AOP.
I'd recommend neither of these approaches. Better to use aspect-oriented programming. Logging is the "hello world" of AOP.
Generally, I like to keep an application completely ignorant of the IoC container. However I have ran into problems where I needed to access it. To abstract away the pain I use a basic Singleton. Before you run for the hills or pull out the shotgun, let me go over my solution. Basically, the IoC singleton does absolutly nothing, it simply delegates to an internal interface that must be passed in. I've found this makes working with the Singleton less painful.
Below is the IoC wrapper:
public static class IoC
{
private static IDependencyResolver inner;
public static void InitWith(IDependencyResolver container)
{
inner = container;
}
/// <exception cref="InvalidOperationException">Container has not been initialized. Please supply an instance if IWindsorContainer.</exception>
public static T Resolve<T>()
{
if ( inner == null)
throw new InvalidOperationException("Container has not been initialized. Please supply an instance if IWindsorContainer.");
return inner.Resolve<T>();
}
public static T[] ResolveAll<T>()
{
return inner.ResolveAll<T>();
}
}
IDependencyResolver:
public interface IDependencyResolver
{
T Resolve<T>();
T[] ResolveAll<T>();
}
I've had great success so far with the few times I've used it (maybe once every few projects, I really prefer not having to use this at all) as I can inject anything I want: Castle, a Stub, fakes, etc.
Is this a slippery road? Am I going to run into potential issues down the road?
I've seen that even Ayende implements this pattern in the Rhino Commons code, but I'd advise against using it wherever possible. There's a reason Castle Windsor doesn't have this code by default. StructureMap does, but Jeremy Miller has been moving away from it. Ideally, you should regard the container itself with as much suspicion as any global variable.
However, as an alternative, you could always configure your container to resolve IDependencyResolver as a reference to your container. This may sound crazy, but it's significantly more flexible. Just remember the rule of thumb that an object should call "new" or perform processing, but not both. For "call new" replace with "resolve a reference".
That's not really a singleton class. That's a static class with static members. And yes that seems a good approach.
I think JP Boodhoo even has a name for this pattern. The Static Gateway pattern.
Just a note: Microsoft Patterns and Practices has created a common service locator (http://www.codeplex.com/CommonServiceLocator) that most of the major IoC containers will be implementing in the near future. You can begin to use it instead of your IDependencyResolver.
BTW: this is the common way to solve your problem and it works quite well.
It all depends on the usage. Using the container like that is called the Service Locator Pattern. There are cases where it's not a good fit and cases where it do apply.
If you google "service locator pattern" you'll see a lot of blog posts saying that it's an anti-pattern, which it's not. The pattern has simply been overused (/abused).
For typical line of business applications you should not use SL as you hide the dependencies. You also got another problem: You can not manage state/lifetime if you use the root container (instead of one of it's lifetimes).
Service locator is a good fit when it comes to infrastructure. For instance ASP.NET MVC uses Service Locator to be able to resolve all dependencies for each controller.