1. It is hard to change because every change affects too many other parts
of the system. (Rigidity - Starr)
2. When you ma...
A B X
• Basistechnologien (.Net, Java, Ruby, …)
• Basisdatentypen (int, string, char…)
• Datenhaltungsklassen und Transferobjekt...
User Interface
Business Layer
Data Access Layer
Cross
Cutting
Concerns
User Interface
Business Layer
Data Access Layer
Cross
Cutting
Concerns
A B Xb
?
Robert C. Martin
(Uncle Bob)
The SOLID principles are not rules. They are not laws.
They are not perfect truths. They are ...
ingle Responsibility Principle
pen Closed Principle
iskov Substitution Principle
nterface Segregation Principle
ependency ...
ingle Responsibility Principle
pen Closed Principle
iskov Substitution Principle
nterface Segregation Principle
ependency ...
ingle Responsibility Principle
pen Closed Principle
iskov Substitution Principle
nterface Segregation Principle
ependency ...
ingle Responsibility Principle
pen Closed Principle
iskov Substitution Principle
nterface Segregation Principle
ependency ...
ingle Responsibility Principle
pen Closed Principle
iskov Substitution Principle
nterface Segregation Principle
ependency ...
ingle Responsibility Principle
pen Closed Principle
iskov Substitution Principle
nterface Segregation Principle
ependency ...
High-Level Klassen sollen nicht von Low-Level
Klassen abhängig sein, sondern beide von
Abstraktionen.
Abstraktionen sollen...
High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein…
Klient
Leistungs-
träger
High-Level Low-Level
High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein…
Klient
Leistungs-
träger
High-Level Low-Level
…
…
…
High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein…
Person Bauer
High-Level Low-Level
Süßer
Apfel
Person
Boskoop
Bauer
High-Level Low-Level
Süßer
Apfel
GetBoskoop!
High-Level Klassen sollen nicht von Low-Level Klassen ab...
High-Level Klassen sollen nicht von Low-Level
Klassen abhängig sein, sondern beide von
Abstraktionen.
Abstraktionen sollen...
High-Level Klassen sollen nicht von Low-Level
Klassen abhängig sein, sondern beide von
Abstraktionen.
Abstraktionen sollen...
Person
Boskoop
Bauer
High-Level Low-Level
Süßer
Apfel
GetBoskoop
High-Level Klassen sollen nicht von Low-Level Klassen abh...
Person Obsthändler
Pink Lady
Bauer
Boskoop
Bauer
Granny
Smith Bauer
High-Level Low-Level
Süßer
Apfel
High-Level Klassen so...
High-Level Klassen sollen nicht von Low-Level
Klassen abhängig sein, sondern beide von
Abstraktionen.
Abstraktionen sollen...
High-Level Klassen sollen nicht von Low-Level
Klassen abhängig sein, sondern beide von
Abstraktionen.
Abstraktionen sollen...
Person Obsthändler
Pink Lady
Bauer
Boskoop
Bauer
Granny
Smith Bauer
High-Level Low-Level
Süßer
Apfel
Abstraktionen sollen ...
Person Obsthändler
High-Level Low-Level
Süßer
Apfel
Abstraktionen sollen nicht von Details abhängig sein, sondern Details ...
Person IObsthändler
Low-Level
GetApfel
Obsthändler
B
Obsthändler
A
Obsthändler
C
Süßer
Apfel
Abstraktionen sollen nicht vo...
Was ist Inversion of Control???
Person IObsthändler
Low-Level
GetApfel
Obsthändler
B
Obsthändler
A
Obsthändler
C
Süßer
Apf...
ohne IoC mit IoC
DIP IoC
Low-Level
Creation
Inversion
Flow
Inversion
Interface
Inversion
DIP IoC
Low-Level
Creation
Inversion
Flow
Inversion
Interface
Inversion
Flow
Inversion
Publisher Subscriber
Flow
Inversion
Subscriber
Subscriber
Publisher
Publisher
Publisher Event Aggregator Subscriber
Flow
Inversion
DIP IoC
Low-Level
Creation
Inversion
Flow
Inversion
Interface
Inversion
Request Factory Typdefinition
Creation
Inversion
Request Typdefinition
Subscriber
Subscriber
Request IoC Container Typdefinitionen
Creation
Inversion
public class StudentContext : DbContext
{
public StudentContext() : base()
{}
public DbSet<StudentEntity> Students { get; ...
public class StudentContext : DbContext, IStudentContext
{
public StudentContext() : base()
{}
public DbSet<StudentEntity>...
Creation
Inversion
public class StudentManagementViewModel
{
StudentContext context;
public StudentEntity Student { get; s...
Creation
Inversion
public class StudentManagementViewModel
{
IStudentContext context;
public StudentEntity Student { get; ...
Creation
Inversion
public class StudentManagementViewModel
{
IStudentContext context;
public StudentEntity Student { get; ...
DIP IoC
Low-Level
Creation
Inversion
Flow
Inversion
Interface
Inversion
public class StudentContext : DbContext, IStudentContext
{
public StudentContext() : base()
{}
public DbSet<StudentEntity>...
public class IStudentRepository
{
IQueryable<StudentEntity> Students { get; set; }
}
Interface
Inversion
public class Stud...
[Table("StudentInfo")]
public class StudentEntity
{
public StudentEntity() { }
[Key]
public int SID { get; set; }
[Column(...
public class Student
{
public int SID { get; set; }
public string Name { get; set; }
public DateTime BirthDate { get; set;...
Interface
Inversion
public class StudentManagementViewModel
{
IStudentContext context;
public StudentEntity Student { get;...
Interface
Inversion
public class StudentManagementViewModel
{
IStudentRepository repository;
public Student Student { get;...
var student = this.repository.Students.Single(s => s.StudentName == name);
Student student = this.repository.Students.Sing...
Interface
Inversion
internal class StudentsFromDatabase : IManageStudents, DbSet {...}
public class IStudentRepository
{
I...
Header Interfaces
public interface IManageStudents : IQueryable<Student>
{
Student Create();
Student GetStudent(string nam...
DIP IoC
Low-Level
Creation
Inversion
Flow
Inversion
Interface
Inversion
Test
Implementierung
Refaktorisierung
Test
Implementierung
Refaktorisierung
Systemtest
UI
BL
DA
UI
BL
DA
Quelle: http://jeffreypalermo.com/blog/the-onion-architecture-part-1/
Application
Services
Domain
Services
Domain
Model
Us...
•
•
•
•
„The real problem is that programmers have spent far too
much time worrying about efficiency in the wrong places and
at th...
Der Code bestimmt
die Schnittstellen.
Der Konsument
bestimmt die
Schnittstellen.
Lose gekoppelt wie nie: DI vs. IOC - Hendrik Lösch @ DWX 2016
Lose gekoppelt wie nie: DI vs. IOC - Hendrik Lösch @ DWX 2016
Lose gekoppelt wie nie: DI vs. IOC - Hendrik Lösch @ DWX 2016
Nächste SlideShare
Wird geladen in …5
×

Lose gekoppelt wie nie: DI vs. IOC - Hendrik Lösch @ DWX 2016

21 Aufrufe

Veröffentlicht am

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 greift die zuvor genannten Begriffe auf und erläutert ihre Zusammenhänge. Dabei ist 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 sehen wir diverse Beispiele des Einsatzes der SOLID Prinzipien und warum Dependency Injection allein eben nicht zu besserer Software führt.

Veröffentlicht in: Software
0 Kommentare
0 Gefällt mir
Statistik
Notizen
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

Keine Downloads
Aufrufe
Aufrufe insgesamt
21
Auf SlideShare
0
Aus Einbettungen
0
Anzahl an Einbettungen
1
Aktionen
Geteilt
0
Downloads
0
Kommentare
0
Gefällt mir
0
Einbettungen 0
Keine Einbettungen

Keine Notizen für die Folie
  • https://de.fotolia.com/id/69069066
  • Rigidity – Starrheit
    Fragility – Zerbrechlichkeit
    Immobility - UNbeweglichkeit
  • Auch das Dependency Inversion Principle (DIP) ist ein SOLID Prinzip. Es besagt folgendes: High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Interfaces.
    Interfaces sollen nicht von Details abhängig sein, sondern Details von Interfaces.
    Verwendet eine High-Level Klasse eine Low-Level Klasse unmittelbar, so ergibt sich eine starke Kopplung zwischen beiden. Spätestens beim Versuch, die High-Level Klasse isoliert zu testen, wird man auf Schwierigkeiten stoßen. Aus diesem Grund sollte die High-Level Klasse von einem Interface abhängig sein, das wiederum von der Low-Level Klasse implementiert wird. So kann die Low-Level Klasse im Unit Test durch ein Mockup ersetzt werden. Um zur Laufzeit die invertierte, abstrakte Abhängigkeit mit einem konkreten Objekt aufzulösen, bieten sich im Prinzip drei Möglichkeiten: mittels Konstruktorparameter "per Hand"
    Einsatz eines Inversion of Control Containers (IoC Container) wie etwa Castle Windsor
    Dependency Lookup
  • Auch das Dependency Inversion Principle (DIP) ist ein SOLID Prinzip. Es besagt folgendes: High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Interfaces.
    Interfaces sollen nicht von Details abhängig sein, sondern Details von Interfaces.
    Verwendet eine High-Level Klasse eine Low-Level Klasse unmittelbar, so ergibt sich eine starke Kopplung zwischen beiden. Spätestens beim Versuch, die High-Level Klasse isoliert zu testen, wird man auf Schwierigkeiten stoßen. Aus diesem Grund sollte die High-Level Klasse von einem Interface abhängig sein, das wiederum von der Low-Level Klasse implementiert wird. So kann die Low-Level Klasse im Unit Test durch ein Mockup ersetzt werden. Um zur Laufzeit die invertierte, abstrakte Abhängigkeit mit einem konkreten Objekt aufzulösen, bieten sich im Prinzip drei Möglichkeiten: mittels Konstruktorparameter "per Hand"
    Einsatz eines Inversion of Control Containers (IoC Container) wie etwa Castle Windsor
    Dependency Lookup
  • Auch das Dependency Inversion Principle (DIP) ist ein SOLID Prinzip. Es besagt folgendes: High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Interfaces.
    Interfaces sollen nicht von Details abhängig sein, sondern Details von Interfaces.
    Verwendet eine High-Level Klasse eine Low-Level Klasse unmittelbar, so ergibt sich eine starke Kopplung zwischen beiden. Spätestens beim Versuch, die High-Level Klasse isoliert zu testen, wird man auf Schwierigkeiten stoßen. Aus diesem Grund sollte die High-Level Klasse von einem Interface abhängig sein, das wiederum von der Low-Level Klasse implementiert wird. So kann die Low-Level Klasse im Unit Test durch ein Mockup ersetzt werden. Um zur Laufzeit die invertierte, abstrakte Abhängigkeit mit einem konkreten Objekt aufzulösen, bieten sich im Prinzip drei Möglichkeiten: mittels Konstruktorparameter "per Hand"
    Einsatz eines Inversion of Control Containers (IoC Container) wie etwa Castle Windsor
    Dependency Lookup
  • Auch das Dependency Inversion Principle (DIP) ist ein SOLID Prinzip. Es besagt folgendes: High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Interfaces.
    Interfaces sollen nicht von Details abhängig sein, sondern Details von Interfaces.
    Verwendet eine High-Level Klasse eine Low-Level Klasse unmittelbar, so ergibt sich eine starke Kopplung zwischen beiden. Spätestens beim Versuch, die High-Level Klasse isoliert zu testen, wird man auf Schwierigkeiten stoßen. Aus diesem Grund sollte die High-Level Klasse von einem Interface abhängig sein, das wiederum von der Low-Level Klasse implementiert wird. So kann die Low-Level Klasse im Unit Test durch ein Mockup ersetzt werden. Um zur Laufzeit die invertierte, abstrakte Abhängigkeit mit einem konkreten Objekt aufzulösen, bieten sich im Prinzip drei Möglichkeiten: mittels Konstruktorparameter "per Hand"
    Einsatz eines Inversion of Control Containers (IoC Container) wie etwa Castle Windsor
    Dependency Lookup
  • Auch das Dependency Inversion Principle (DIP) ist ein SOLID Prinzip. Es besagt folgendes: High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Interfaces.
    Interfaces sollen nicht von Details abhängig sein, sondern Details von Interfaces.
    Verwendet eine High-Level Klasse eine Low-Level Klasse unmittelbar, so ergibt sich eine starke Kopplung zwischen beiden. Spätestens beim Versuch, die High-Level Klasse isoliert zu testen, wird man auf Schwierigkeiten stoßen. Aus diesem Grund sollte die High-Level Klasse von einem Interface abhängig sein, das wiederum von der Low-Level Klasse implementiert wird. So kann die Low-Level Klasse im Unit Test durch ein Mockup ersetzt werden. Um zur Laufzeit die invertierte, abstrakte Abhängigkeit mit einem konkreten Objekt aufzulösen, bieten sich im Prinzip drei Möglichkeiten: mittels Konstruktorparameter "per Hand"
    Einsatz eines Inversion of Control Containers (IoC Container) wie etwa Castle Windsor
    Dependency Lookup
  • Auch das Dependency Inversion Principle (DIP) ist ein SOLID Prinzip. Es besagt folgendes: High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Interfaces.
    Interfaces sollen nicht von Details abhängig sein, sondern Details von Interfaces.
    Verwendet eine High-Level Klasse eine Low-Level Klasse unmittelbar, so ergibt sich eine starke Kopplung zwischen beiden. Spätestens beim Versuch, die High-Level Klasse isoliert zu testen, wird man auf Schwierigkeiten stoßen. Aus diesem Grund sollte die High-Level Klasse von einem Interface abhängig sein, das wiederum von der Low-Level Klasse implementiert wird. So kann die Low-Level Klasse im Unit Test durch ein Mockup ersetzt werden. Um zur Laufzeit die invertierte, abstrakte Abhängigkeit mit einem konkreten Objekt aufzulösen, bieten sich im Prinzip drei Möglichkeiten: mittels Konstruktorparameter "per Hand"
    Einsatz eines Inversion of Control Containers (IoC Container) wie etwa Castle Windsor
    Dependency Lookup
  • Rigidity – Starrheit
    Fragility – Zerbrechlichkeit
    Immobility - Unbeweglichkeit
  • Was bringt uns Inversion of Control?

    Entkopplung der Ausführung einer Aktion von ihrer Implementierung.
    Fokussierung von Bestandteilen auf deren eigentliche Aufgabe.
    Grundstrukturen werden durch Verträge festgehalten.
    Zulieferer können einfacher durch andere ersetzt werden.

  • Lose gekoppelt wie nie: DI vs. IOC - Hendrik Lösch @ DWX 2016

    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. 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
    8. 8. ingle Responsibility Principle pen Closed Principle iskov Substitution Principle nterface Segregation Principle ependency Inversion Principle S O L I D
    9. 9. 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/
    10. 10. 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/
    11. 11. 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/
    12. 12. 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/
    13. 13. 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
    14. 14. 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.
    15. 15. High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein… Klient Leistungs- träger High-Level Low-Level
    16. 16. High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein… Klient Leistungs- träger High-Level Low-Level … … …
    17. 17. High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein… Person Bauer High-Level Low-Level Süßer Apfel
    18. 18. Person Boskoop Bauer High-Level Low-Level Süßer Apfel GetBoskoop! High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein…
    19. 19. 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.
    20. 20. 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.
    21. 21. 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… !
    22. 22. 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…
    23. 23. 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.
    24. 24. 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.
    25. 25. 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!
    26. 26. 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
    27. 27. 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
    28. 28. Was ist Inversion of Control??? Person IObsthändler Low-Level GetApfel Obsthändler B Obsthändler A Obsthändler C Süßer Apfel
    29. 29. ohne IoC mit IoC
    30. 30. DIP IoC Low-Level Creation Inversion Flow Inversion Interface Inversion
    31. 31. DIP IoC Low-Level Creation Inversion Flow Inversion Interface Inversion
    32. 32. Flow Inversion
    33. 33. Publisher Subscriber Flow Inversion
    34. 34. Subscriber Subscriber Publisher Publisher Publisher Event Aggregator Subscriber Flow Inversion
    35. 35. DIP IoC Low-Level Creation Inversion Flow Inversion Interface Inversion
    36. 36. Request Factory Typdefinition Creation Inversion Request Typdefinition
    37. 37. Subscriber Subscriber Request IoC Container Typdefinitionen Creation Inversion
    38. 38. public class StudentContext : DbContext { public StudentContext() : base() {} public DbSet<StudentEntity> Students { get; set; } } Creation Inversion
    39. 39. public class StudentContext : DbContext, IStudentContext { public StudentContext() : base() {} public DbSet<StudentEntity> Students { get; set; } } public class IStudentContext { DbSet<StudentEntity> Students { get; set; } } Creation Inversion
    40. 40. 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); } }
    41. 41. 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); } }
    42. 42. 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); } }
    43. 43. DIP IoC Low-Level Creation Inversion Flow Inversion Interface Inversion
    44. 44. public class StudentContext : DbContext, IStudentContext { public StudentContext() : base() {} public DbSet<StudentEntity> Students { get; set; } } public class IStudentContext { DbSet<StudentEntity> Students { get; set; } } Interface Inversion
    45. 45. 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} } }
    46. 46. [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
    47. 47. 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; } }
    48. 48. 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); } }
    49. 49. 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); } }
    50. 50. 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
    51. 51. 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);
    52. 52. 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
    53. 53. DIP IoC Low-Level Creation Inversion Flow Inversion Interface Inversion
    54. 54. Test Implementierung Refaktorisierung
    55. 55. Test Implementierung Refaktorisierung Systemtest
    56. 56. UI BL DA UI BL DA
    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 Schnittstellen. Der Konsument bestimmt die Schnittstellen.

    ×