18 private readonly ScientificClassificationEngine _classificationEngine;
20 _compatibilityService;
24 new ScientificClassificationEngine(),
30 ScientificClassificationEngine classificationEngine,
33 _classificationEngine =
34 classificationEngine ??
35 throw new ArgumentNullException(nameof(classificationEngine));
37 _compatibilityService =
38 compatibilityService ??
39 throw new ArgumentNullException(nameof(compatibilityService));
43 ScientificClassificationResult classification,
45 string requestedFormulationId =
"",
46 bool allowFallback =
true)
48 ArgumentNullException.ThrowIfNull(classification);
49 ArgumentNullException.ThrowIfNull(registry);
54 requestedFormulationId,
60 LotSizingInstance instance,
62 string requestedFormulationId =
"",
63 bool allowFallback =
true,
64 ScientificClassificationRequest? classificationRequest =
null)
66 ArgumentNullException.ThrowIfNull(instance);
67 ArgumentNullException.ThrowIfNull(registry);
69 ScientificClassificationResult classification =
70 _classificationEngine.Analyze(
72 classificationRequest);
77 requestedFormulationId,
83 ScientificClassificationResult classification,
85 string requestedFormulationId,
87 LotSizingInstance? instance)
90 requestedFormulationId?.Trim() ??
string.Empty;
93 new List<ScientificFormulationDiagnostic>();
101 _compatibilityService.Assess(
103 formulation.FormulationId);
108 : formulation.CanBuild(instance);
110 if (canBuild ==
false)
116 $
"formulation.{formulation.FormulationId}",
117 "Scientific compatibility may be satisfied, " +
118 "but the formulation's technical CanBuild " +
119 "contract rejected the instance."));
122 return new ScientificFormulationSelectionCandidate(
129 candidate.Formulation.FormulationId,
130 StringComparer.OrdinalIgnoreCase)
133 ScientificFormulationSelectionCandidate? selected =
null;
134 bool usedFallback =
false;
136 if (!
string.IsNullOrWhiteSpace(requested))
138 ScientificFormulationSelectionCandidate? requestedCandidate =
139 candidates.FirstOrDefault(
141 candidate.Formulation.FormulationId.Equals(
143 StringComparison.OrdinalIgnoreCase));
145 if (requestedCandidate is
null)
148 new ScientificFormulationDiagnostic(
151 "selection.requestedFormulation",
152 $
"Requested formulation '{requested}' is not registered."));
154 else if (requestedCandidate.IsSelectable)
156 selected = requestedCandidate;
161 new ScientificFormulationDiagnostic(
164 "selection.requestedFormulation",
165 $
"Requested formulation '{requested}' is not " +
166 "scientifically and technically selectable."));
169 if (selected is
null && !allowFallback)
171 return new ScientificFormulationSelectionResult(
174 selectedCandidate:
null,
181 if (selected is
null)
184 candidates.FirstOrDefault(
186 candidate.IsSelectable);
189 selected is not
null &&
190 !
string.IsNullOrWhiteSpace(requested);
193 if (selected is
null)
196 new ScientificFormulationDiagnostic(
200 "No registered formulation has verified scientific " +
201 "compatibility and an acceptable technical build status."));
206 new ScientificFormulationDiagnostic(
210 $
"Selected formulation '{selected.Formulation.FormulationId}'."));
213 return new ScientificFormulationSelectionResult(