Recently I was put in front of a scenario where data from two different services had a relation and needed to unite to form a meaningful reply to consumers. The scenario included an enrollment service and a student service, the enrollment contained the id of the student and the consumers needed a list of enrollments with meaningful student details.
By using LINQ?s capability of joining two IEnumerables and the capability of creating projections "on the fly", what I first thought would take some time to build actually turned out to be a short but sweet pleasure.
This is (kind of) what I did:
using (EnrollmentServiceClient client = new EnrollmentServiceClient())
enrollments = client.ListBy(date, testCenterId);
List<string> studentIds = (from item in enrollments
using (StudentServiceClient client = new StudentServiceClient())
students = client.ListFor(studentIds);
List<StudentEnrollment> response = (from enrollment in enrollments
join student in students
on enrollment.StudentId equals student.Id
select new StudentEnrollment ()
FullName = student.FirstName + " " + student.LastName,
Code = enrollment.CertificationCode,
Certification = enrollment.CertificationName,
Status = enrollment.Status.ToString(),
InvoiceStatus = enrollment.InvoiceStatus.ToString()
This is where I went from loving LINQ to worship it, it just solved an enterprise grade challenge for me with very little and very beautiful code.
In SO terms what it just created was an Entity Composition Service (ECS) which often are needed after applying the "decomposition principle" on your enterprise services. Basically what the principle says is that data should be tied to the service which implements the process that the data belongs to. Like in the above scenario where the services of handling student information and that of creating enrollments are logically and physically separated in the enterprise, the data then naturally lives in different corners of the enterprise and when creating lists like this it needs to be united.
This can be kind of hairy to pull off; luckily LINQ saved the day!