Ich frage mich, wie man korrekte Hierarchie baut und wo man Invarianten abdeckt. Kurs kann ohne die Fakultät nicht existieren. Außerdem kann der Kurs ohne Lehrer nicht existieren. Ein Lehrer kann viele Kurse haben. Ein Schüler kann viele Kurse haben, und ein Kurs kann viele Schüler haben. maximal 10 Kurse.
1 Fakultät kann maximal 20 Kurse haben.
1 Lehrer kann maximal 100 Schüler haben, die über seine Kurse studieren. (Es gibt keine direkte Verbindung zwischen Lehrer und Schülern, da die Schüler an verschiedenen Kursen des Lehrers studieren) < /p>
Ich habe versucht, die Lösung zu folgen. < /P>
public class Faculty : Entity
{
public Guid Id { get; private set; }
public string Name { get; private set; }
private readonly List _courses = new();
public IReadOnlyCollection Courses => _courses.AsReadOnly();
private const int MaxCourses = 20;
public Faculty(string name)
{
Id = Guid.NewGuid();
Name = name;
}
public Course AddCourse(string courseName, Teacher teacher)
{
if (_courses.Count >= MaxCourses)
throw new InvalidOperationException("A Faculty can have a maximum of 20 courses.");
var course = new Course(courseName, this, teacher);
_courses.Add(course);
teacher.AssignCourse(course);
return course;
}
}
< /code>
public class Course : Entity
{
public Guid Id { get; private set; }
public string Name { get; private set; }
public Faculty Faculty { get; private set; }
public Teacher Teacher { get; private set; }
private readonly List _students = new();
public IReadOnlyCollection Students => _students.AsReadOnly();
private const int MaxStudents = 30;
public Course(string name, Faculty faculty, Teacher teacher)
{
Id = Guid.NewGuid();
Name = name;
Faculty = faculty ?? throw new ArgumentNullException(nameof(faculty));
Teacher = teacher ?? throw new ArgumentNullException(nameof(teacher));
}
public void EnrollStudent(Student student)
{
if (_students.Count >= MaxStudents)
throw new InvalidOperationException("Course cannot have more than 30 students.");
_students.Add(student);
Teacher.EnsureStudentLimit();
}
}
< /code>
public class Teacher : Entity
{
public Guid Id { get; private set; }
public string Name { get; private set; }
private readonly List _courses = new();
public IReadOnlyCollection Courses => _courses.AsReadOnly();
private const int MaxStudentsAcrossCourses = 100;
public Teacher(string name)
{
Id = Guid.NewGuid();
Name = name;
}
public void AssignCourse(Course course)
{
_courses.Add(course);
}
public void EnsureStudentLimit()
{
var totalStudents = _courses.SelectMany(c => c.Students).Distinct().Count();
if (totalStudents > MaxStudentsAcrossCourses)
throw new InvalidOperationException("A teacher cannot have more than 100 students across their courses.");
}
}
< /code>
public class Student : Entity
{
public Guid Id { get; private set; }
public string Name { get; private set; }
private readonly List _enrollments = new();
public IReadOnlyCollection Enrollments => _enrollments.AsReadOnly();
private const int MaxCourses = 10;
public Student(string name)
{
Id = Guid.NewGuid();
Name = name;
}
public void EnrollInCourse(Course course)
{
if (_enrollments.Count >= MaxCourses)
throw new InvalidOperationException("A student cannot enroll in more than 10 courses.");
var enrollment = new CourseEnrollment(this, course);
_enrollments.Add(enrollment);
course.EnrollStudent(this);
}
}
< /code>
public class CourseEnrollment : Entity
{
public Guid Id { get; private set; }
public Student Student { get; private set; }
public Course Course { get; private set; }
public CourseEnrollment(Student student, Course course)
{
Id = Guid.NewGuid();
Student = student ?? throw new ArgumentNullException(nameof(student));
Course = course ?? throw new ArgumentNullException(nameof(course));
}
}
< /code>
The problem here is that it breaks DDD rules about aggregates. For example: Teacher shouldn't have links to Courses as they are part of Faculty aggregate. Course shouldn't have collection of Students, as interaction with other aggregation roots should be performed via Ids, not direct links.
What exactly should I do with this to cover all the invariants? OK I could move logic to some domain event handler or service. How would I cover Teacher invariants in that service? DDD says that we can have repositories only for aggregates. Teacher can have a limit amount of students, that study in different courses with the same teacher. But courses are part of Faculty aggregate. So which repository should I use to get this info.
DDD. Richtige Klassenhierarchie und Gewährleistung von Invarianten ⇐ C#
-
- Similar Topics
- Replies
- Views
- Last post