HI WELCOME TO SIRIS
Showing posts with label Dependency Injection. Show all posts
Showing posts with label Dependency Injection. Show all posts

Dependency Injection in ASP.NET Core

Dependency Injection is the design pattern that help us to create application which loosely coupled. This means that object should only have those dependency that required during complete task. The main advantages of DI (Dependency Injection) is our application loosely coupled and has provide greater maintainability, testability and also re-usability. It is loosely coupled because dependency required by the class are injected from outer world rather than created them self directly win-in code.
There are three type of DI: Construction Injection, Setter Injection, Interface based Injection. The Construction Injection type of DI accept their dependency at constructor level it means that when create object of the class, their dependency pass through the constructor of the class. It provide the strong dependency contract between objects. The Setter Injection is also known as property injection. In this type of dependency injection, dependency pass through public property instead of constructor. It allows us to pass the dependencies when they required. It does not provide strong dependency contract between objects. The interface-based dependency injection can be achieved by creating the common interface and other classes are implements this interface to inject the dependency. In this type of DI, we can use either constructor injection or setter injection.
There is a built-in support of dependency injection in ASP.net Core. This supports is not limited to middleware, but also support in Controllers, views, and model as well. There are two type of service container provided by the ASP.net core: Framework Services and Application Services. The framework services are service that are provided by the ASP.net core such as ILoggerFactory etc. The application services are the custom services created base on our requirement.

Dependency injection into controllers

The dependency required by the ASP.net MVC controller requested explicitly via their constructors (Constructor injection type) and this dependency are available for the controller. Some of the dependency are injected to only the controller action as a parameter. ASP.net core has built-in support for constructor-based dependency. The dependency required by the controller are simply adding a service type to the controller in the constructor. The ASP.net core will identify the service type and try to resolve the type. It would be the good design if service defined using interfaces but it is not always true.
Example In the following example, I have created HelloWorld service. This service has method called "SaysHello” that simply returns "Hello " string. I have also implement this service using interface.
  1. namespace DepedencyInjectionExample.Service
  2. {
  3. public interface IHelloWorldService
  4. {
  5. string SaysHello();
  6. }
  7.  
  8. public class HelloWorldService : IHelloWorldService
  9. {
  10. public string SaysHello()
  11. {
  12. return "Hello ";
  13. }
  14. }
  15. }
The next step is to add this service to the service container, so that when controller is requested for service, it is available to use. We can add the service to the service container in ConfigureServices method of startup class. There are three different life option available: Transient, Scoped, and Singleton. We will discuss this later part in the article.
  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. ….
  4. services.AddTransient<IHelloWorldService, HelloWorldService>();
  5. }
If we not register the service to the ASP.net core service container, it will throw the exception as following.


Now this “HelloWorld” service is available to use in the controller. We can inject this service as a dependency in constructor.
  1. using DepedencyInjectionExample.Models;
  2. using Microsoft.AspNetCore.Mvc;
  3. using DepedencyInjectionExample.Service;
  4.  
  5. namespace DepedencyInjectionExample.Controllers
  6. {
  7. public class HomeController : Controller
  8. {
  9. IHelloWorldService _helloWorldService;
  10. public HomeController(IHelloWorldService helloWorldService)
  11. {
  12. _helloWorldService = helloWorldService;
  13. }
  14. }
  15. }
Once the service has been configured correctly and injected in to the controller, it should display Hello message as expected.


The constructor dependency injection behavior resolved the service by either IServiceProvider or ActivatorUtilities. The ActivatorUtilities allows to creation of the object without service registration in the DI. The model binder, tag helper and controller service are used ActivatorUtilities. The service required always public constructor. ASP.net core is only support the single constructor for the controller class which requesting the service. If we have more than one constructor, ASP.net core MVC raised the error.

Inject the dependency in controller action

Some time, we required dependency to the particular controller action method not to throughout controller. ASP.net core MVC allows us to inject the dependency to particular action using "FromServices" attribute. This attribute tell the ASP.net core framework that parameter should be retrieve from the service container.
  1. using DepedencyInjectionExample.Service;
  2. using Microsoft.AspNetCore.Mvc;
  3.  
  4. namespace DepedencyInjectionExample.Controllers
  5. {
  6. public class DemoController : Controller
  7. {
  8. public IActionResult Index([FromServices] IHelloWorldService helloWorldService)
  9. {
  10. ViewData["MyText"] = helloWorldService.SaysHello() + "Jignesh!";
  11. return View();
  12. }
  13. }
  14. }
The property injection is not supported by the ASP.net core but we call the service instance manually and called service methods.

Get the service instance manually

There is another way to get dependency services from the service container. In this method, service is not injected in controller constructor or in action method as parameter. Using method "GetService" of "HttpContext.RequestServices" property, we can get dependent services configured with Service container. This is also known as property injection. Following is the example.
  1. public IActionResult Index1()
  2. {
  3. var helloWorldService = (IHelloWorldService)this.HttpContext.RequestServices.GetService(typeof(IHelloWorldService));
  4. ViewData["MyText"] = helloWorldService.SaysHello() + "Jignesh Trivedi!";
  5. return View("index");
  6. }

Service Lifetime

ASP.net core allow us to specify the lifetime for registered services. The service instance gets disposed automatically based on specified life-time. So we do not care about the cleaning these dependency, it will take care by ASP.net core framework. There are three type of life-times.

Singleton

ASP.net core will create and share a single instance of the service through the application life. The service can be added as singleton using AddSingleton method of IServiceCollection. ASP.net core create service instance at the time of registration and subsequence request use this service instance. Here, we do not required to implement singleton design pattern and single instance maintained by the ASP.net core itself.
  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. ….
  4. services.AddSingleton<IHelloWorldService, HelloWorldService>();
  5. ….
  6. }

Transient

ASP.net core will create and share an instance of the service every time to the application when we ask for it. The service can be added as Transient using AddTransient method of IServiceCollection. This life-time can be used in stateless service. It is way to add lightweight service.
  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. ….
  4. services.AddTransient<IHelloWorldService, HelloWorldService>();
  5. ….
  6. }

Scoped

ASP.net core will create and share an instance of the service per request to the application. It means that single instance of service available per request. It will create a new instance in new request. The service can be added as scoped using AddScoped method of IServiceCollection. We need to take care while, service registered via Scoped in middleware and inject the service in the Invoke or InvokeAsync methods. If we inject dependency via constructor, it behave like singleton object.
  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. ….
  4. services.AddScoped<IHelloWorldService, HelloWorldService>();
  5. ….
  6. }

Dependency injection into Views

ASP.net core can also able to inject the dependency to View. This is very useful to inject service related view such as localization. This method will bypass the controller call and fetch data directly from the service. We can inject the service dependency into the view using @inject directive. The syntax is as following to use this directive. Here we need to pass the service type that need to inject and service instance name that used to access the service method.
  1. @inject <type> <instance name>
Example In the following example, I have used same service that created in preceding section and injected in the view using @inject directive and using the service instance, we can call the service method in to the view.
  1.  
  2. @{
  3. ViewData["Title"] = "DIToView";
  4. }
  5. @inject DepedencyInjectionExample.Service.IHelloWorldService helloWorldService
  6.  
  7. <h4>DI To View</h4>
  8.  
  9. <h5>
  10. @helloWorldService.SaysHello() Reader!!!
  11. </h5>

View injection can be used to populate the UI element such as dropdown. The common dropdown such city/state dropdown can be populate from the service. Rendering such things from the service is standard approach in ASp.net core MVC. Alternatively, we can use viewbag and Viewdata to populate dropdown. The directive @inject is also be used to override the injected service. For example, we are using Html helper service for the rendering the Html tags such as dropdown, textbox, etc. We can replace this service with our own service using @inject directive.
Summary
Dependency injection is the design pattern that allow us to inject the dependency to the class from outer world rather than creating with in class. This will help us to create loosely coupled application so that it has provided greater maintainability, testability and also reusability. There is a built-in support of dependency injection in ASP.net Core. This supports is not limited to middleware, but also support in Controllers, views, and model as well. There are three easy step to use Dependency injection into ASP.net core MVC application.
  • Create the service
  • Register the service into ConfigureService method of the startup class, so that it available to use
  • Inject the service where you want to use
    ASP.net core allow us to specify the lifetime for registered services based on our requirement to use the service. The service can either register as Singleton, Transient or Scoped.

Dependency Injection in ASP.NET MVC using Unity IoC Container

In the previous articles, I have explained about the Understanding IoC, DI and Service Locator Pattern and IoC or DI Containers. Before proceeding with this article, please go through my last articles. In this article, you will learn how to use Unity DI Container in your ASP.NET MVC application to make the service layer and Presentation layer loosely coupled.

Step 1 - Create a new ASP.NET MVC Application

First step is to create a new ASP.NET MVC Application using Visual Studio 2012 or higher as shown below:

Step 2- Install Unity Container

Now install Unity container using Unity.Mvc4 (for MVC4) or Unity.Mvc5 (for MVC5) nuget package as per your ASP.NET MVC versions, using the NuGet Package Manager console tool as shown below:


Note

Make sure you are connected with internet.
When it will be installed successfully, you will be find the following two references add to your project and a Bootstrapper.cs class file in MVC4 and UnityConfig.cs file in MVC5 at project level, as shown below:


  1. //mvc4
  2. using System.Web.Mvc;
  3. using Microsoft.Practices.Unity;
  4. using Unity.Mvc4;
  5.  
  6. namespace MvcNUnit
  7. {
  8. public static class Bootstrapper
  9. {
  10. public static IUnityContainer Initialise()
  11. {
  12. var container = BuildUnityContainer();
  13. DependencyResolver.SetResolver(new UnityDependencyResolver(container));
  14. return container;
  15. }
  16. private static IUnityContainer BuildUnityContainer()
  17. {
  18. var container = new UnityContainer();
  19. // register all your components with the container here
  20. // it is NOT necessary to register your controllers
  21. // e.g. container.RegisterType<ITestService, TestService>();
  22. RegisterTypes(container);
  23. return container;
  24. }
  25. public static void RegisterTypes(IUnityContainer container)
  26. {
  27. }
  28. }
  29. }
  1. //mvc5
  2. using BAL;
  3. using System.Web.Mvc;
  4. using Unity;
  5. using Unity.Mvc5;
  6.  
  7. namespace UI
  8. {
  9. public static class UnityConfig
  10. {
  11. public static void RegisterComponents()
  12. {
  13. var container = new UnityContainer();
  14.  
  15. // register all your components with the container here
  16. // it is NOT necessary to register your controllers
  17.  
  18. // e.g. container.RegisterType<ITestService, TestService>();
  19. DependencyResolver.SetResolver(new UnityDependencyResolver(container));
  20. }
  21. }
  22. }

Step 3- Add a New Service Layer

Add a new Folder in the project of the name Repository and add the following interface and a class in this folder:
  1. //Product.cs
  2. public class Product
  3. {
  4. public int Id { get; set; }
  5. public string Name { get; set; }
  6. public string Category { get; set; }
  7. public decimal Price { get; set; }
  8. }
  9.  
  10. //IProductRepository.cs
  11. public interface IProductRepository
  12. {
  13. IEnumerable<Product> GetAll();
  14. Product Get(int id);
  15. Product Add(Product item);
  16. bool Update(Product item);
  17. bool Delete(int id);
  18. }
  19.  
  20. //ProductRepository.cs
  21. public class ProductRepository : IProductRepository
  22. {
  23. private List<Product> products = new List<Product>();
  24. private int _nextId = 1;
  25.  
  26. public ProductRepository()
  27. {
  28. // Add products for the Demonstration
  29. Add(new Product { Name = "Computer", Category = "Electronics", Price = 23.54M });
  30. Add(new Product { Name = "Laptop", Category = "Electronics", Price = 33.75M });
  31. Add(new Product { Name = "iPhone4", Category = "Phone", Price = 16.99M });
  32. }
  33.  
  34. public IEnumerable GetAll()
  35. {
  36. // TO DO : Code to get the list of all the records in database
  37. return products;
  38. }
  39. public Product Get(int id)
  40. {
  41. // TO DO : Code to find a record in database
  42. return products.Find(p => p.Id == id);
  43. }
  44. public Product Add(Product item)
  45. {
  46. if (item == null)
  47. {
  48. throw new ArgumentNullException("item");
  49. }
  50. // TO DO : Code to save record into database
  51. item.Id = _nextId++;
  52. products.Add(item);
  53. return item;
  54. }
  55. public bool Update(Product item)
  56. {
  57. if (item == null)
  58. {
  59. throw new ArgumentNullException("item");
  60. }
  61. // TO DO : Code to update record into database
  62. int index = products.FindIndex(p => p.Id == item.Id);
  63. if (index == -1)
  64. {
  65. return false;
  66. }
  67. products.RemoveAt(index);
  68. products.Add(item);
  69. return true;
  70. }
  71. public bool Delete(int id)
  72. {
  73. // TO DO : Code to remove the records from database
  74. products.RemoveAll(p => p.Id == id);
  75. return true;
  76. }
  77. }
The above repository acts as a new layer and will be used to decouple the model layer from the controller layer.

Step 4- Register the Dependency in Bootstrapper.cs or UnityConfig.cs file

Replace BuildUnityContainer method's content with the following code that registers the ProductRepository Service. You can also register the Product Controller in which we will inject the dependency, but it is optional.
  1. private static IUnityContainer BuildUnityContainer()
  2. {
  3. var container = new UnityContainer();
  4.  
  5. // register all your components with the container here
  6. // it is NOT necessary to register your
  7. // e.g. container.RegisterType<ITestService, TestService>();
  8.  
  9. //registered dependency here
  10. container.RegisterType<IProductRepository, ProductRepository>();
  11. RegisterTypes(container);
  12.  
  13. return container;
  14. }
  1. //mvc5
  2. using BAL;
  3. using System.Web.Mvc;
  4. using Unity;
  5. using Unity.Mvc5;
  6.  
  7. namespace UI
  8. {
  9. public static class UnityConfig
  10. {
  11. public static void RegisterComponents()
  12. {
  13. var container = new UnityContainer();
  14.  
  15. // register all your components with the container here
  16. // it is NOT necessary to register your controllers
  17.  
  18. // e.g. container.RegisterType<ITestService, TestService>();
  19.  
  20. //registered dependency here
  21. container.RegisterType<IUnitOfWork, UnitOfWork>();
  22.  
  23. DependencyResolver.SetResolver(new UnityDependencyResolver(container));
  24. }
  25. }
  26. }

Step 5- Inject Service to Controller

Now inject the dependency for the IProductRepository interface using the Product Controller's constructor as shown below:
  1. public class ProductController : Controller
  2. {
  3. readonly IProductRepository repository;
  4.  
  5. //inject dependency
  6. public ProductController(IProductRepository repository)
  7. {
  8. this.repository = repository;
  9. }
  10.  
  11. public ActionResult Index()
  12. {
  13. var data = repository.GetAll();
  14. return View(data);
  15. }
  16. //Other Code
  17. }

Step 6 – Setup Dependency Injection with Unity in Global.asax.cs

Now, setup the Bootstrapper or UnityConfig class with in the Application_Start method so that it can initialize all dependencies. This will be done by calling Initialise() method of the Bootstrapper class or RegisterComponents() methods of UnityConfig.cs class as shown below:
  1. //mvc4
  2. protected void Application_Start()
  3. {
  4. AreaRegistration.RegisterAllAreas();
  5.  
  6. WebApiConfig.Register(GlobalConfiguration.Configuration);
  7. FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
  8. RouteConfig.RegisterRoutes(RouteTable.Routes);
  9. BundleConfig.RegisterBundles(BundleTable.Bundles);
  10. AuthConfig.RegisterAuth();
  11. //Setup DI
  12. Bootstrapper.Initialise();
  13. }
  1. //mvc5
  2. protected void Application_Start()
  3. {
  4. AreaRegistration.RegisterAllAreas();
  5. // Setup DI
  6. UnityConfig.RegisterComponents();
  7. RouteConfig.RegisterRoutes(RouteTable.Routes);
  8. }

Step 7- Run the Application and see how it works

What do you think?
I hope you will enjoy the tips while programming with ASP.NET MVC. I would like to have feedback from my blog readers. Your valuable feedback, question, or comments about this article are always welcome.

Implementation of Dependency Injection Pattern in C#

Dependency Injection (DI) is a software design pattern that allows us to develop loosely coupled code. DI is a great way to reduce tight coupling between software components. DI also enables us to better manage future changes and other complexity in our software. The purpose of DI is to make code maintainable.
The Dependency Injection pattern uses a builder object to initialize objects and provide the required dependencies to the object means it allows you to "inject" a dependency from outside the class.
For example, Suppose your Client class needs to use two service classes, then the best you can do is to make your Client class aware of abstraction i.e. IService interface rather than implementation i.e. Service1 and Service2 classes. In this way, you can change the implementation of the IService interface at any time (and for how many times you want) without changing the client class code.

We can modify this code by following the Dependency Injection implementation ways. We have following different ways to implement DI :

Constructor Injection

  1. This is the widely used way to implement DI.
  2. Dependency Injection is done by supplying the DEPENDENCY through the class’s constructor when creating the instance of that class.
  3. Injected component can be used anywhere within the class.
  4. Recommended to use when the injected dependency, you are using across the class methods.
  5. It addresses the most common scenario where a class requires one or more dependencies.
  1. public interface IService {
  2. void Serve();
  3. }
  4. public class Service1 : IService {
  5. public void Serve() { Console.WriteLine("Service1 Called"); }
  6. }
  7. public class Service2 : IService {
  8. public void Serve() { Console.WriteLine("Service2 Called"); }
  9. }
  10. public class Client {
  11. private IService _service;
  12. public Client(IService service) {
  13. this._service = service;
  14. }
  15. public ServeMethod() { this._service.Serve(); }
  16. }
  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. //creating object
  6. Service1 s1 = new Service1();
  7. //passing dependency
  8. Client c1 = new Client(s1);
  9. //TO DO:
  10.  
  11. Service2 s2 = new Service2();
  12. //passing dependency
  13. c1 = new Client(s2);
  14. //TO DO:
  15. }
  16. }
The Injection happens in the constructor, by passing the Service that implements the IService Interface. The dependencies are assembled by a "Builder" and Builder responsibilities are as follows:
  1. Knowing the types of each IService
  2. According to the request, feed the abstract IService to the Client

Property/Setter Injection

  1. Recommeded to use when a class has optional dependencies, or where the implementations may need to be swapped.
  2. Different logger implementations could be used in this way.
  3. Does not required the creation of new object or modifying the existing one. Without chaning the object state, it could work.
  1. public interface IService {
  2. void Serve();
  3. }
  4. public class Service1 : IService {
  5. public void Serve() { Console.WriteLine("Service1 Called"); }
  6. }
  7. public class Service2 : IService {
  8. public void Serve() { Console.WriteLine("Service2 Called"); }
  9. }
  10. public class Client {
  11. private IService _service;
  12. public IService Service {
  13. set { this._service = value; }
  14. }
  15. public ServeMethod() { this._service.Serve(); }
  16. }
  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. //creating object
  6. Service1 s1 = new Service1();
  7. Client client = new Client();
  8. client.Service = s1; //passing dependency
  9. //TO DO:
  10.  
  11. Service2 s2 = new Service2();
  12. client.Service = s2; //passing dependency
  13. //TO DO:
  14. }
  15. }

Method Injection

  1. Inject the dependency into a single method and generally for the use of that method.
  2. It could be useful, where the whole class does not need the dependency, only one method having that dependency.
  3. This is way is rarely used.
  1. public interface IService {
  2. void Serve();
  3. }
  4. public class Service1 : IService {
  5. public void Serve() { Console.WriteLine("Service1 Called"); }
  6. }
  7. public class Service2 : IService {
  8. public void Serve() { Console.WriteLine("Service2 Called"); }
  9. }
  10. public class Client {
  11. private IService _service;
  12. public void Start(IService service) {
  13. service.Serve();
  14. }
  15. }
  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. //creating object
  6. Service1 s1 = new Service1();
  7. Client client = new Client();
  8. client.Start(s1); //passing dependency
  9. //TO DO:
  10. Service2 s2 = new Service2();
  11. client.Start(s2); //passing dependency
  12. }
  13. }

Advantages of Dependency Injection

  1. Reduces class coupling
  2. Increases code reusability
  3. Improves code maintainability
  4. Make unit testing possible

DI Container

The recommended way to implement DI is, you should use DI containers. If you compose an application without a DI CONTAINER, it is like a POOR MAN’S DI. If you want to implemet DI within your ASP.NET MVC application using DI container, please do refer Dependency Injection in ASP.NET MVC using Unity IoC Container.
What do you think?
I hope, you will enjoy the various ways of implementing DI pattern. I would like to have feedback from my blog readers. Your valuable feedback, question, or comments about this article are always welcome.

What is IoC Container or DI Container

The terms Dependency Injection (DI) & Inversion of Control (IoC) are generally used interchangeably to describe the same design pattern. Hence some people say IoC Container and some people says DI container but both terms indicate to the same thing. So don't be confused by the terminology.

What is DI Container

A DI Container is a framework to create dependencies and inject them automatically when required. It automatically creates objects based on the request and injects them when required. DI Container helps us to manage dependencies within the application in a simple and easy way.

We can also manage application dependencies without a DI Container, but it will be like as POOR MAN’S DI and we have to do more work, to make it configured and manageable.

List of popular DI Container for .Net

Today, there are a lot of excellent DI Containers that are available for .NET. Here, I am sharing the list of most useful DI Container for .Net framework.

Castle Windsor

  1. Based on the Castle MicroKernel.
  2. Well documented and used by many.
  3. Understands Decorator
  4. Typed factories
  5. Commercial support available

StructureMap

  1. It has been around since June 2004
  2. It is actively developed and works in many cases

Spring.NET

  1. INTERCEPTION
  2. Comprehensive documentation
  3. Commercial support available

Autofac

  1. Easy to learn API
  2. second-generation DI Container
  3. Commercial support available

Unity

  1. INTERCEPTION
  2. Good documentation
  3. Consistent API

Ninject

  1. Easy to learn API
  2. Second-generation DI Container
What do you think?
I hope you will use one of the IoC containers within your .NET application. I would like to have feedback from my blog readers. Your valuable feedback, question, or comments about this article are always welcome.

Understanding Inversion of Control, Dependency Injection and Service Locator

So many developers are confused about the term Dependency Injection (DI). The confusion is about terminology, purpose, and mechanics. Should it be called Dependency Injection, Inversion of Control, or Service Locator? Over the Internet, there are a lot of articles, presentations, and discussion but, unfortunately, many of them use conflicting terminology.
In this article, you will learn about all these three concepts. Let's start with dependency.

What is dependency?

Dependency can be understood with the help of a simple example. Suppose Class A needs Class B to do its job, Hence, Class B is a dependency of Class A.


Dependency Management

To make sure that class A will have a class B object, Class A use one the following option:


Among all of the above three options, the last one comes into IoC, since here Class A is not doing anything, it's receiving the object of Class B when it's required. So, this IoC since you are changing the normal flow of code execution.

Inversion of Control (IoC)

The term Inversion of Control (IoC) refers to a programming style where the flow of a program has been inverted i.e. changed from the normal way. As you have done in the example of Class A and Class B. Here, dependencies are instantiated by a framework or runtime and supplied to the desired class as needed.
More over IoC is a generic term and it is not limited to DI. Actually, DI and Service Locator patterns are specialized versions of the IoC pattern or you can say DI and Service Locator are the ways of implementing IoC.
For example, Suppose your Client class needs to use a Service class component, then the best you can do is to make your Client class aware of an IService interface rather than a Service class. In this way, you can change the implementation of the Service class at any time (and for how many times you want) without breaking the host code.

IoC Implementation



 

IoC and DI

The terms Dependency Injection (DI) and Inversion of Control (IoC) are generally used as interchangeably to describe the same design pattern. The pattern was originally called IoC, but Martin Fowler (know for designing the enterprise software) proposed the name as DI because all frameworks or runtime invert the control in some way and he wanted to know which aspect of control was being inverted.

Dependency Injection (DI)

DI is a software design pattern that allow us to develop loosely coupled code. DI is a great way to reduce tight coupling between software components. DI also enables us to better manage future changes and other complexity in our software. The purpose of DI is to make code maintainable.
The Dependency Injection pattern uses a builder object to initialize objects and provide the required dependencies to the object means it allows you to "inject" a dependency from outside the class.

Service Locator (SL)

Service Locator is a software design pattern that also allow us to develop loosely coupled code. It implements the DIP principle and easier to use with an existing codebase as it makes the overall design looser without forcing changes to the public interface.
The Service Locator pattern introduces a locator object that objects is used to resolve dependencies means it allows you to "resolve" a dependency within a class.

Dependency Injection and Service Locator with Example

Let's consider the simple dependency between two classes as shown in the fig and it is a simple approach, that you know.

Now have a look at the folllowing code:
  1. public class Service
  2. {
  3. public void Serve()
  4. {
  5. Console.WriteLine("Service Called");
  6.  
  7. //To Do: Some Stuff
  8. }
  9. }
  10. public class Client
  11. {
  12. private Service _service;
  13. public Client()
  14. {
  15. this._service = new Service();
  16. }
  17. public void Start()
  18. {
  19. Console.WriteLine("Service Started");
  20. this._service.Serve();
  21.  
  22. //To Do: Some Stuff
  23. }
  24. }
Clearly, the Client class has a dependency on the Service class. If you want to make it loosely coupled, you have to use IoC to make the more flexible and reusable it.
To implement the IoC, you have the choice of two main patterns: Service Locator and Dependency Injection. The Service Locator allows you to "resolve" a dependency within a class and the Dependency Injection allows you to "inject" a dependency from outside the class.

Using Service Locator


The above code can be re-written as by using Service Locator as follows.
  1. public interface IService
  2. {
  3. void Serve();
  4. }
  5.  
  6. public class Service : IService
  7. {
  8. public void Serve()
  9. {
  10. Console.WriteLine("Service Called");
  11. //To Do: Some Stuff
  12. }
  13. }
  14.  
  15. public static class LocateService
  16. {
  17. public static IService _Service { get; set; }
  18.  
  19. public static IService GetService()
  20. {
  21. if (_Service == null)
  22. _Service = new Service();
  23.  
  24. return _Service;
  25. }
  26. }
  27.  
  28. public class Client
  29. {
  30. private IService _service;
  31.  
  32. public Client()
  33. {
  34. this._service = LocateService.GetService();
  35. }
  36.  
  37. public void Start()
  38. {
  39. Console.WriteLine("Service Started");
  40. this._service.Serve();
  41. //To Do: Some Stuff
  42. }
  43. }
Sample ServiceLocator-Implementation:
  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. var client = new Client();
  6. client.Start();
  7. Console.ReadKey();
  8. }
  9. }
The Inversion happens in the constructor, by locating the Service that implements the IService-Interface. The dependencies are assembled by a "Locator".

Using Dependency Injection

 

The above code can also be re-written as by using Dependency Injection as follows.
  1. public interface IService
  2. {
  3. void Serve();
  4. }
  5.  
  6. public class Service : IService
  7. {
  8. public void Serve()
  9. {
  10. Console.WriteLine("Service Called");
  11.  
  12. //To Do: Some Stuff
  13. }
  14. }
  15.  
  16. public class Client
  17. {
  18. private IService _service;
  19.  
  20. public Client(IService service)
  21. {
  22. this._service = service;
  23. }
  24.  
  25. public void Start()
  26. {
  27. Console.WriteLine("Service Started");
  28. this._service.Serve();
  29.  
  30. //To Do: Some Stuff
  31. }
  32. }
Sample Builder-Implementation:
  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. client = new Client(new Service());
  6. client.Start();
  7.  
  8. Console.ReadKey();
  9. }
  10. }
The Injection happens in the constructor, by passing the Service that implements the IService-Interface. The dependencies are assembled by a "Builder" and Builder responsibilities are as follows:
  1. knowing the types of each IService
  2. according to the request, feed the abstract IService to the Client

What's wrong with the above two approaches?

Above two approaches can be resemble to DI FACTORY. There are some issues with the above two approaches:
  1. It is hardcoded and can't be reused across applications, due to hardcoded factories. This makes the code stringent to particular implementations.
  2. It is Interface dependent since interfaces are used for decoupling the implementation and the object creation procedure.
  3. It's Instantiating instantiations are very much custom to a particular implementation.
  4. Everything is compile time since all the dependent types for the objects in the instantiation process (factory) have to be known at compile time.

What is the Solution ?

IoC containers is the solution to resolve above two approaches issues. Hence, when we compose applications without a DI CONTAINER, it is like a POOR MAN’S DI. Moreover, DI CONTAINER is a useful, but optional tool.
You can also improve above two approaches by doing some more work. You can also combine above two approaches to make code more independent

Dependency Injection vs. Service Locator

  1. When you use a service locator, every class will have a dependency on your service locator. This is not the case with dependency injection. The dependency injector will typically be called only once at startup, to inject dependencies into the main class.
  2. The Service Locator pattern is easier to use in an existing codebase as it makes the overall design looser without forcing changes to the public interface. Code that is based on the Service Locator pattern is less readable than the equivalent code that is based on Dependency Injection.
What do you think?
I hope you will enjoy the IoC, DI and SL patterns while writting the code. I would like to have feedback from my blog readers. Your valuable feedback, question, or comments about this article are always welcome.