1. 程式人生 > >Implementation of Dependency Injection Pattern in C#

Implementation of Dependency Injection Pattern in C#

Dependency Injection (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.

For example, Suppose your Client class needs to use aService class component, then the best you can do is to make yourClient

class aware of an IService interface rather than aService class. In this way, you can change the implementation of theService class at any time (and for how many times you want) without breaking the host code.

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

Constructor Injection

  1. This is the most common DI.

  2. Dependency Injection is done by supplying the DEPENDENCY through the class’s constructor when instantiating that class.

  3. Injected component can be used anywhere within the class.

  4. Should be used when the injected dependency is required for the class to function.

  5. It addresses the most common scenario where a class requires one or more dependencies.

  1. publicinterface IService
  2. {
  3. voidServe();
  4. }
  5. publicclassService:IService
  6. {
  7. publicvoidServe()
  8. {
  9. Console.WriteLine("Service Called");
  10. //To Do: Some Stuff
  11. }
  12. }
  13. publicclassClient
  14. {
  15. privateIService _service;
  16. publicClient(IService service)
  17. {
  18. this._service = service;
  19. }
  20. publicvoidStart()
  21. {
  22. Console.WriteLine("Service Started");
  23. this._service.Serve();
  24. //To Do: Some Stuff
  25. }
  26. }
  27. classProgram
  28. {
  29. staticvoidMain(string[] args)
  30. {
  31. client =newClient(newService());
  32. client.Start();
  33. Console.ReadKey();
  34. }
  35. }

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 injection

  1. Also called Setter injection.

  2. Used when a class has optional dependencies, or where the implementations may need to be swapped. Different logger implementations could be used this way.

  3. May require checking for a provided implementation throughout the class(need to check for null before using it).

  4. Does not require adding or modifying constructors.

  1. publicinterface IService
  2. {
  3. voidServe();
  4. }
  5. publicclassService:IService
  6. {
  7. publicvoidServe()
  8. {
  9. Console.WriteLine("Service Called");
  10. //To Do: Some Stuff
  11. }
  12. }
  13. publicclassClient
  14. {
  15. privateIService _service;
  16. publicIServiceService
  17. {
  18. set
  19. {
  20. this._service = value;
  21. }
  22. }
  23. publicvoidStart()
  24. {
  25. Console.WriteLine("Service Started");
  26. this._service.Serve();
  27. //To Do: Some Stuff
  28. }
  29. }
  30. classProgram
  31. {
  32. staticvoidMain(string[] args)
  33. {
  34. Client client =newClient();
  35. client.Service=newService();
  36. client.Start();
  37. Console.ReadKey();
  38. }
  39. }

Method injection

  1. Inject the dependency into a single method, for use by that method.

  2. Could be useful where the whole class does not need the dependency, just the one method.

  3. Generally uncommon, usually used for edge cases.

  1. publicinterface IService
  2. {
  3. voidServe();
  4. }
  5. publicclassService:IService
  6. {
  7. publicvoidServe()
  8. {
  9. Console.WriteLine("Service Called");
  10. //To Do: Some Stuff
  11. }
  12. }
  13. publicclassClient
  14. {
  15. privateIService _service;
  16. publicvoidStart(IService service)
  17. {
  18. this._service = service;
  19. Console.WriteLine("Service Started");
  20. this._service.Serve();
  21. //To Do: Some Stuff
  22. }
  23. }
  24. classProgram
  25. {
  26. staticvoidMain(string[] args)
  27. {
  28. Client client =newClient();
  29. client.Start(newService());
  30. Console.ReadKey();
  31. }
  32. }

Key points about DI

  1. Reduces class coupling

  2. Increases code reusing

  3. Improves code maintainability

  4. Improves application testing