/// <summary> /// Builds a valid <see cref="ArtifactsConfiguration"/> based on a <see cref="BoundedContextTopology"/> /// </summary> /// <param name="boundedContextTopology"></param> /// <returns></returns> public ArtifactsConfiguration Build(BoundedContextTopology boundedContextTopology) { var newArtifacts = 0; var artifactsDictionary = new MutableAritfactsDictionary(); foreach (var(feature, featureArtifactsByType) in _currentArtifactsConfiguration) { var featureArtifacts = artifactsDictionary[feature] = new Dictionary <PropertyInfo, Dictionary <ArtifactId, ArtifactDefinition> >(); foreach (var artifactType in featureArtifactsByType.GetType().GetProperties()) { var existingArtifactsForFeatureType = artifactType.GetValue(featureArtifactsByType) as IReadOnlyDictionary <ArtifactId, ArtifactDefinition>; featureArtifacts[artifactType] = new Dictionary <ArtifactId, ArtifactDefinition>(existingArtifactsForFeatureType); } } var nonMatchingArtifacts = new List <string>(); foreach (var artifactType in _artifactTypes.ArtifactTypes) { newArtifacts += HandleArtifactOfType( artifactType, boundedContextTopology, artifactsDictionary, nonMatchingArtifacts ); } if (nonMatchingArtifacts.Any()) { foreach (var artifactNamespace in nonMatchingArtifacts) { _logger.Warning($"An artifact with namespace: '{artifactNamespace}' could not be matched with any feature in the Bounded Context's topology"); } throw new NonMatchingArtifact(); } //new Dictionary<Feature, ArtifactsByTypeDefinition>() var artifactsByTypeDefinitionConstructor = typeof(ArtifactsByTypeDefinition).GetConstructors().Single(_ => _.GetParameters().All(p => p.ParameterType.Equals(typeof(IDictionary <ArtifactId, ArtifactDefinition>)))); var updatedArtifactsConfiguration = new ArtifactsConfiguration(new Dictionary <Feature, ArtifactsByTypeDefinition>( artifactsDictionary.Select(_ => { var feature = _.Key; var arguments = artifactsByTypeDefinitionConstructor.GetParameters().Select(arg => { return(_.Value.SingleOrDefault(prop => arg.Name.ToLower().Equals(prop.Key.Name.ToLower())).Value ?? new Dictionary <ArtifactId, ArtifactDefinition>()); }).ToArray(); var artifacts = artifactsByTypeDefinitionConstructor.Invoke(arguments) as ArtifactsByTypeDefinition; return(new KeyValuePair <Feature, ArtifactsByTypeDefinition>(feature, artifacts)); }) )); updatedArtifactsConfiguration.ValidateArtifacts(boundedContextTopology, _artifacts, _logger); if (newArtifacts > 0) { _logger.Information($"Added {newArtifacts} new artifacts to the map."); } else { _logger.Information($"No new artifacts added to the map."); } return(updatedArtifactsConfiguration); }
int HandleArtifactOfType(ArtifactType artifactType, BoundedContextTopology boundedContextConfiguration, MutableAritfactsDictionary artifactsDictionary, List <string> nonMatchingArtifacts) { var targetProperty = artifactType.TargetPropertyExpression.GetPropertyInfo(); var newArtifacts = 0; var artifacts = _artifacts.Where(_ => artifactType.Type.IsAssignableFrom(_)); foreach (var artifact in artifacts) { var feature = boundedContextConfiguration.FindMatchingFeature(artifact.Namespace, nonMatchingArtifacts); if (feature.Value != null) { MutableArtifactsByTypeDictionary artifactsByType; if (!artifactsDictionary.TryGetValue(feature.Key, out artifactsByType)) { artifactsByType = artifactsDictionary[feature.Key] = new Dictionary <PropertyInfo, Dictionary <ArtifactId, ArtifactDefinition> >(); } Dictionary <ArtifactId, ArtifactDefinition> mutableArtifacts; if (!artifactsByType.TryGetValue(targetProperty, out mutableArtifacts)) { mutableArtifacts = artifactsByType[targetProperty] = new Dictionary <ArtifactId, ArtifactDefinition>(); } if (!mutableArtifacts.Any(_ => _.Value.Type.GetActualType() == artifact)) { var artifactObject = new Dolittle.Artifacts.Artifact(ArtifactId.New(), ArtifactGeneration.First); if (artifact.HasAttribute <ArtifactAttribute>()) { artifactObject = (artifact.GetTypeInfo().GetCustomAttributes(typeof(ArtifactAttribute), false).First() as ArtifactAttribute).Artifact; } AddNewArtifact(artifactObject, artifact, mutableArtifacts, artifactType.TypeName); newArtifacts++; } else { if (artifact.HasAttribute <ArtifactAttribute>()) { var artifactObject = (artifact.GetTypeInfo().GetCustomAttributes(typeof(ArtifactAttribute), false).First() as ArtifactAttribute).Artifact; var existingArtifact = mutableArtifacts.Single(_ => _.Value.Type.GetActualType() == artifact); if (!existingArtifact.Key.Value.Equals(artifactObject.Id.Value)) { mutableArtifacts.Remove(existingArtifact.Key); AddNewArtifact(artifactObject, artifact, mutableArtifacts, artifactType.TypeName); newArtifacts++; } } } } } return(newArtifacts); }