Question

I looked up these concepts, and I want to see if I've understood them correctly. Mainly, I'm trying to distinguish between these three concepts. From googling and other results on here, I saw a lot of detail on them that people provided, but many of them are either not completely clear to me, contradicting, or interchange the concepts (IoC/DI). I'm trying to define them in a simpler way that would be easier for me to digest, and I want to see if it's accurate enough.

Inversion of Control

The client class doesn't directly instantiate the implementation classes of its dependent fields as it depends on some other external class/source to supply them. In most cases, the fields are a parent class or interface that has one or more subclasses that will be supplied as the implementation.

Dependency Injection

The client class receives the implementation classes for its dependent fields, whether through a constructor, setter, or otherwise, and this implementation is a fresh new object instance. The supplying class might use another pattern, such as a factory, in order to determine what implementation to pass to the client (or it might even just straight up instantiate a new instance and pass it into the client's constructor).

Service Locator

The client class is the one that calls the service locator to supply its dependent fields. The implementation that is returned is an object instance that may be shared with any other client classes that rely on the same dependency.

My attempts at a very simple example:

DI:

public interface IX {

}

public class X : IX {

}

public class A {
    IX depField;

    public A(IX depField) {
        this.depField = depField;
    }   
}

public void main() {
    A myClass = new A(new X());
}

SL:

public interface IX {

}

public class X : IX {

}

public class A {
    IX depField = serviceLocatorObj.GetService<IX>(); 
    //where IX is mapped to X in the service locator class
}

public void main() {
    A myClass = new A();
}

IoC is the concept on the receiving side, where as DI and SL are two possible ways of dealing with the concept on the supplying side.

Thanks. Also I apologize if I incorrectly used any terms.

Edit: Thanks for the responses!

Was it helpful?

Solution

Yes, you are correct.

SL is typically used inside frameworks to be able to locate all services. From the developers point of view they are just using dependency injection as the framework hides the service location. A typical example is ASP.NET MVC where you can use DI in your controllers. ASP.NET uses service location internally through the DependencyResolver class to allow you to use DI.

For line of business applications DI is prefered over SL as SL hides the dependencies, which in turn makes it harder to maintain the applications.

OTHER TIPS

Service location also makes unit testing harder as they are usually static classes, which robs the ability to mock them.

Consider these examples of constructor injection and service location.

Service location:

 public class Foo
    {
        public void DoSomething()
        {
            var provider = ServiceLocator.GetInstance<IProvider>();

            provider.DoIt();
        }
    }

Constructor injection:

 public class Foo
    {
        private readonly IProvider _provider;

        public Foo(IProvider provider)
        {
            _provider = provider;
        }

        public void DoSomething()
        {
            _provider.DoIt();
        }
    }

It is simple to pass a mock/fake IProvider in the constructor, while in the service locator example this gets exponentially harder as you first need to abstract the ServiceLocator class.

    [Test]
    public void DoSomething_ShouldCallDoIt()
    {
        var mockProvider = new Mock<IProvider>();

        var foo = new Foo(mockProvider);

        foo.DoSomething();

        mockProvider.Verify(x => x.DoIt());
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top