Domain services
Overview
Domain services are optional, they typically encapsulate common subdomain logic which is reusable across domain. Domain services are used when domain handlers and repository extensions aren't suitable for shared logic and when such logic doesn't fit to rich entity objects.
See example of qualification domain service encapsulating logic for manipulation with Qualification hierarchical entity available for command and query handlers or other domain services.
Note: All public methods are virtual to be easily overriden, because domain service doesn't implement interface.
//
using System;
using System.Collections.Generic;
using System.Linq;
using ASOL.Core.Domain;
using ASOL.Core.Domain.Contracts;
using ASOLEU.Jobsignum.Domain.Helpers;
using ASOLEU.Jobsignum.Domain.Repositories;
namespace ASOLEU.Jobsignum.Domain.Services
{
public class QualificationService
{
private readonly IQualificationReadOnlyRepository _qualificationRepository;
private readonly IQualificationRelationReadOnlyRepository _qualificationRelationRepository;
public QualificationService(
IQualificationReadOnlyRepository qualificationRepository,
IQualificationRelationReadOnlyRepository qualificationRelationRepository)
{
_qualificationRepository = qualificationRepository;
_qualificationRelationRepository = qualificationRelationRepository;
}
public virtual IList<Qualification> GetQualificationsAndTheirHierarchyRelations(string organizationId, int uptoLevel)
{
if(uptoLevel < 1) throw new ArgumentOutOfRangeException(nameof(uptoLevel), "Value must be greater than zero.");
var query = _qualificationRelationRepository
.GetHierarchyRelationsWithRelatedQualifications(uptoLevel - 1, organizationId)
.ApplyBaseEntityFilter(BaseEntityFilter.Default);
var groupedQR = query.ToLookup(x => x.QualificationId);
var qDict = new Dictionary<string, Qualification>();
var qList = new List<Qualification>();
//basic qualifications
foreach (var qGroup in groupedQR)
{
var q = qGroup.First().Qualification;
q.Relations = qGroup.Select(x => x).ToList();
qDict.Add(qGroup.Key, q);
qList.AddRange(qGroup.Select(x => x.RelatedQualification));
}
//related qualifications
foreach (var qItem in qList.DistinctBy(x => x.Id))
{
if (!qDict.TryGetValue(qItem.Id, out _))
{
qItem.Relations.Clear();
qDict.Add(qItem.Id, qItem);
}
}
return qDict.Values.OrderByDescending(x => x.Level).ToArray();
}
}
}