Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

DevDay 2016: Hendrik Lösch - Lose gekoppelt wie nie: DI vs. IoC

6,938 views

Published on

Dependency Injection, Service Locator, Inversion of Control, Dependency Inversion Principle, … Viele Begriffe die irgendwie das Gleiche zu sagen scheinen und sich dann doch wieder unterscheiden. Sicher ist nur, dass es sich um lose Kopplung handelt. Dass wir dank dieser ominösen Begriffe wartbare Software erstellen können, die leichter zu erweitern ist und sich darüber hinaus auch noch gut testen lässt.
Der Vortrag griff die zuvor genannten Begriffe auf und erläuterte ihre Zusammenhänge. Dabei war das Ziel mit altbekannten Vorurteilen aufzuräumen und bei der Entscheidung zu helfen wo Softwarebestandteile wirklich entkoppelt werden sollten und welche Antipatterns sich beim Praxiseinsatz ergeben können. Dabei sahen wir diverse Beispiele des Einsatzes der SOLID Prinzipien und warum Dependency Injection allein eben nicht zu besserer Software führt.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

DevDay 2016: Hendrik Lösch - Lose gekoppelt wie nie: DI vs. IoC

  1. 1. 1. It is hard to change because every change affects too many other parts of the system. (Rigidity - Starr) 2. When you make a change, unexpected parts of the system break. (Fragility - Zerbrechlich) 3. It is hard to reuse in another application because it cannot be disentangled from the current application. (Immobility - Unbeweglich) Quelle: http://www.objectmentor.com/resources/articles/dip.pdf
  2. 2. A B X
  3. 3. • Basistechnologien (.Net, Java, Ruby, …) • Basisdatentypen (int, string, char…) • Datenhaltungsklassen und Transferobjekte • Domänen spezifische Algorithmen und Datenbanken • UI Logik • … beständig unbeständig
  4. 4. User Interface Business Layer Data Access Layer Cross Cutting Concerns
  5. 5. User Interface Business Layer Data Access Layer Cross Cutting Concerns
  6. 6. A B Xb ?
  7. 7. public class A { IB b; public A(IB b) { this.b = b; } }
  8. 8. User Interface Business Layer Data Access Layer Cross Cutting Concerns
  9. 9. Robert C. Martin (Uncle Bob) The SOLID principles are not rules. They are not laws. They are not perfect truths. They are statements on the order of “An apple a day keeps the doctor away.” This is a good principle, it is good advice, but it’s not a pure truth, nor is it a rule. “ ” Quelle: https://sites.google.com/site/unclebobconsultingllc/getting-a-solid-start
  10. 10. ingle Responsibility Principle pen Closed Principle iskov Substitution Principle nterface Segregation Principle ependency Inversion Principle S O L I D
  11. 11. ingle Responsibility Principle pen Closed Principle iskov Substitution Principle nterface Segregation Principle ependency Inversion Principle S O L I D Eine Klasse sollte nur eine Verantwortlichkeit haben. Quelle: http://www.clean-code-developer.de/
  12. 12. ingle Responsibility Principle pen Closed Principle iskov Substitution Principle nterface Segregation Principle ependency Inversion Principle S O L I D Eine Klasse sollte offen für Erweiterungen, jedoch geschlossen für Modifikationen sein. Quelle: http://www.clean-code-developer.de/
  13. 13. ingle Responsibility Principle pen Closed Principle iskov Substitution Principle nterface Segregation Principle ependency Inversion Principle S O L I D Abgeleitete Klassen sollten sich so verhalten wie es von ihren Basistypen erwartet wird. Quelle: http://www.clean-code-developer.de/
  14. 14. ingle Responsibility Principle pen Closed Principle iskov Substitution Principle nterface Segregation Principle ependency Inversion Principle S O L I D Interfaces sollten nur die Funktionalität wiederspiegeln die ihre Klienten erwarten. Quelle: http://www.clean-code-developer.de/
  15. 15. ingle Responsibility Principle pen Closed Principle iskov Substitution Principle nterface Segregation Principle ependency Inversion Principle S O L I D High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Abstraktionen. Abstraktionen sollen nicht von Details abhängig sein, sondern Details von Abstraktionen. Quelle: Wikipedia.org
  16. 16. High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Abstraktionen. Abstraktionen sollen nicht von Details abhängig sein, sondern Details von Interfaces.
  17. 17. High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein… Klient Leistungs- träger High-Level Low-Level
  18. 18. High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein… Klient Leistungs- träger High-Level Low-Level … … …
  19. 19. High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein… Person Bauer High-Level Low-Level Süßer Apfel
  20. 20. Person Boskoop Bauer High-Level Low-Level Süßer Apfel GetBoskoop! High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein…
  21. 21. High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Abstraktionen. Abstraktionen sollen nicht von Details abhängig sein, sondern Details von Interfaces.
  22. 22. High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Abstraktionen. Abstraktionen sollen nicht von Details abhängig sein, sondern Details von Interfaces.
  23. 23. Person Boskoop Bauer High-Level Low-Level Süßer Apfel GetBoskoop High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Abstraktionen… !
  24. 24. Person Obsthändler Pink Lady Bauer Boskoop Bauer Granny Smith Bauer High-Level Low-Level Süßer Apfel High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Abstraktionen…
  25. 25. High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Abstraktionen. Abstraktionen sollen nicht von Details abhängig sein, sondern Details von Abstraktionen.
  26. 26. High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Abstraktionen. Abstraktionen sollen nicht von Details abhängig sein, sondern Details von Abstraktionen.
  27. 27. Person Obsthändler Pink Lady Bauer Boskoop Bauer Granny Smith Bauer High-Level Low-Level Süßer Apfel Abstraktionen sollen nicht von Details abhängig sein, sondern Details von Abstraktionen. GetBoskoop!
  28. 28. Person Obsthändler High-Level Low-Level Süßer Apfel Abstraktionen sollen nicht von Details abhängig sein, sondern Details von Abstraktionen. GetApfel Pink Lady Bauer Boskoop Bauer Granny Smith Bauer
  29. 29. Person IObsthändler Low-Level GetApfel Obsthändler B Obsthändler A Obsthändler C Süßer Apfel Abstraktionen sollen nicht von Details abhängig sein, sondern Details von Abstraktionen. High-Level
  30. 30. Was ist Inversion of Control??? Person IObsthändler Low-Level GetApfel Obsthändler B Obsthändler A Obsthändler C Süßer Apfel
  31. 31. ohne IoC mit IoC
  32. 32. DIP IoC Low-Level Creation Inversion Flow Inversion Interface Inversion
  33. 33. DIP IoC Low-Level Creation Inversion Flow Inversion Interface Inversion
  34. 34. Flow Inversion
  35. 35. Publisher Subscriber Flow Inversion
  36. 36. Subscriber Subscriber Publisher Publisher Publisher Event Aggregator Subscriber Flow Inversion
  37. 37. DIP IoC Low-Level Creation Inversion Flow Inversion Interface Inversion
  38. 38. Request Factory Typdefinition Creation Inversion Request Typdefinition
  39. 39. Subscriber Subscriber Request IoC Container Typdefinitionen Creation Inversion
  40. 40. public class StudentContext : DbContext { public StudentContext() : base() {} public DbSet<StudentEntity> Students { get; set; } } Creation Inversion
  41. 41. public class StudentContext : DbContext, IStudentContext { public StudentContext() : base() {} public DbSet<StudentEntity> Students { get; set; } } public class IStudentContext { DbSet<StudentEntity> Students { get; set; } } Creation Inversion
  42. 42. Creation Inversion public class StudentManagementViewModel { StudentContext context; public StudentEntity Student { get; set; } public StudentManagementViewModel() { this.context = new StudentContext(); } public void ShowStudent(string name) { this.Student = this.context.Students.FirstOrDefault<StudentEntity> (s => s.StudentName == name); } }
  43. 43. Creation Inversion public class StudentManagementViewModel { IStudentContext context; public StudentEntity Student { get; set; } public StudentManagementViewModel() { this.context = ServiceLocator.Create<IStudentContext>(); } public void ShowStudent(string name) { this.Student = this.context.Students.FirstOrDefault<StudentEntity> (s => s.StudentName == name); } }
  44. 44. Creation Inversion public class StudentManagementViewModel { IStudentContext context; public StudentEntity Student { get; set; } public StudentManagementViewModel(IStudentContext context) { this.context = context; } public void ShowStudent(string name) { this.Student = this.context.Students.FirstOrDefault<StudentEntity> (s => s.StudentName == name); } }
  45. 45. DIP IoC Low-Level Creation Inversion Flow Inversion Interface Inversion
  46. 46. public class StudentContext : DbContext, IStudentContext { public StudentContext() : base() {} public DbSet<StudentEntity> Students { get; set; } } public class IStudentContext { DbSet<StudentEntity> Students { get; set; } } Interface Inversion
  47. 47. public class IStudentRepository { IQueryable<StudentEntity> Students { get; set; } } Interface Inversion public class StudentContext : DbContext, IStudentRepository { public StudentContext() : base() { // ... } private DbSet<StudentEntity> students; public IQueryable<StudentEntity> Students { get{ return this.students} } }
  48. 48. [Table("StudentInfo")] public class StudentEntity { public StudentEntity() { } [Key] public int SID { get; set; } [Column("Name", TypeName = "ntext")] [MaxLength(20)] public string StudentName { get; set; } [Column("BDate", TypeName = "datetime")] public DateTime BirthDate { get; set; } [NotMapped] public int? Age { get;} } Interface Inversion
  49. 49. public class Student { public int SID { get; set; } public string Name { get; set; } public DateTime BirthDate { get; set; } public int? Age { get; } } Interface Inversion public class IStudentRepository { IQueryable<Student> Students { get; set; } } [Table("StudentInfo")] public class StudentEntity { [Key] public int SID { get; set; } [Column("Name", TypeName = "ntext")] [MaxLength(20)] public string StudentName { get; set; } [Column("BDate", TypeName = "datetime")] public DateTime BirthDate { get; set; } }
  50. 50. Interface Inversion public class StudentManagementViewModel { IStudentContext context; public StudentEntity Student { get; set; } public StudentManagementViewModel(IStudentContext context) { this.context = context; } public void ShowStudent(string name) { this.Student = this.context.Students.FirstOrDefault<StudentEntity> (s => s.StudentName == name); } }
  51. 51. Interface Inversion public class StudentManagementViewModel { IStudentRepository repository; public Student Student { get; set; } public StudentManagementViewModel(IStudentRepository repository) { this.repository = repository; } public void ShowStudent(string name) { this.Student = this.repository.Students.FirstOrDefault<Student> (s => s.StudentName == name); } }
  52. 52. var student = this.repository.Students.Single(s => s.StudentName == name); Student student = this.repository.Students.Single(s => s.StudentName == name); Student stud = this.repository.Students.Single(s => s.StudentName == name); Interface Inversion
  53. 53. Interface Inversion internal class StudentsFromDatabase : IManageStudents, DbSet {...} public class IStudentRepository { IQueryable<Student> Students { get; set; } } public interface IManageStudents : IQueryable<Student> { Student Create(); void Add(Student student); ... } Siehe auch: cessor.de this.Student = this.students.FirstOrDefault(s => s.StudentName == name);
  54. 54. Header Interfaces public interface IManageStudents : IQueryable<Student> { Student Create(); Student GetStudent(string name) void Add(Student student); ... } public class IStudentContext { DbSet<StudentEntity> Students { get; set; } } Role Interfaces Interface Inversion
  55. 55. DIP IoC Low-Level Creation Inversion Flow Inversion Interface Inversion
  56. 56. User Interface Business Layer Data Access Layer Cross Cutting Concerns
  57. 57. Quelle: http://jeffreypalermo.com/blog/the-onion-architecture-part-1/ Application Services Domain Services Domain Model User Interface File DB Web Service
  58. 58. • • • •
  59. 59. „The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming.“ Quelle: https://en.wikiquote.org/wiki/Donald_Knuth Donald Knuth
  60. 60. Der Code bestimmt die Lösung. Der Konsument bestimmen den Code.

×