/// <summary> /// Gets the builder for the given Id /// </summary> /// <param name="id">The identifier.</param> /// <returns></returns> public IEntityBuilder Get(Id id) { BuilderInfo builder; if (id != Guid.Empty && !Ids.ContainsKey(id)) { Ids.Add(id, id); } if (Builders.TryGetValue(id, out builder)) { return(builder.Builder); } // Add the Entity to the mapper to make sure it can be created in the correct order EntityDependency.Mapper.Add(id); // Get the default Builder, or if no builder is defined, create a Generic Builder var constructor = (BuilderConstructorForEntity.ContainsKey(id) ? BuilderConstructorForEntity[id] : GetGenericConstructor(id)); builder = new BuilderInfo(id, (IEntityBuilder)constructor.Invoke(new object[] { id })); // Apply any Custom Actions ApplyCustomActions(id, builder); // Add the Builder to both Dictionaries (keyed by Id and Logical Name) BuildersByEntityType.AddOrAppend(id, builder); Builders.Add(id, builder); return(builder.Builder); }
/// <summary> /// Creates the specified entities in the correct Dependent Order, returning the entities created. /// </summary> /// <param name="service">The service.</param> /// <returns></returns> public Dictionary <Guid, Entity> Create(IOrganizationService service) { var results = new Dictionary <Guid, Entity>(); foreach (var name in EntityDependency.Mapper.EntityCreationOrder) { List <BuilderInfo> values; if (!BuildersByEntityType.TryGetValue(name, out values)) { // Should this be an exception? continue; } foreach (var entity in values.Select(value => CreateEntity(service, value))) { Id id; results.Add(entity.Id, entity); if (Ids.TryGetValue(entity.Id, out id)) { id.Entity = entity; } } } return(results); }
/// <summary> /// Creates the specified entities in the correct Dependent Order, returning the entities created. /// </summary> /// <param name="service">The service.</param> /// <returns></returns> public Dictionary <Guid, Entity> Create(IOrganizationService service) { var results = new Dictionary <Guid, Entity>(); var builders = new List <Tuple <Guid, BuilderInfo> >(); var postCreateUpdates = new List <Entity>(); foreach (var info in EntityDependency.Mapper.EntityCreationOrder) { if (!BuildersByEntityType.TryGetValue(info.LogicalName, out List <BuilderInfo> values)) { // The Entity Creation Order is a Singleton. // If this continue occurs, most likely another instance of a Crm Environment Builder used a type that wasn't utilized by this instance continue; } foreach (var value in values) { try { var entity = CreateEntity(service, value, info.CyclicAttributes, postCreateUpdates); RecordBuiltEntity(entity, value, results, builders); } catch (Exception ex) { var entityName = value.Id.Entity == null ? info.LogicalName : $"Entity {value.Id.LogicalName}{Environment.NewLine}{value.Id.Entity.ToStringAttributes()}"; if (string.IsNullOrWhiteSpace(entityName)) { entityName = info.LogicalName; } throw new CreationFailureException($"An error occured attempting to create {entityName}.{Environment.NewLine}{ex.Message}", ex); } } } foreach (var entity in postCreateUpdates) { try { service.Update(entity); AddPostCreateAttributesToIdEntity(results, entity); } catch (Exception ex) { var entityName = $"Entity {entity.LogicalName}{Environment.NewLine}{entity.ToStringAttributes()}"; throw new CreationFailureException($"An error occured attempting to update an EntityDependency post create for Entity {entityName}.{Environment.NewLine}{ex.Message}", ex); } } // Process Post Updates foreach (var builder in builders) { builder.Item2.Builder.PostCreate(service, results[builder.Item1]); } return(results); }
/// <summary> /// Removes the Builder specified by the Id /// </summary> /// <param name="id">The identifier.</param> public void Remove(Id id) { if (Ids.ContainsKey(id)) { Ids.Remove(id); } if (BuildersByEntityType.TryGetValue(id, out List <BuilderInfo> builders) && Builders.TryGetValue(id, out BuilderInfo builder)) { Builders.Remove(id); builders.Remove(builder); } }
private BuilderInfo CreateBuilder(Id id, ConstructorInfo constructor) { // Add the Entity to the mapper to make sure it can be created in the correct order EntityDependency.Mapper.Add(id); var builder = new BuilderInfo(id, (IEntityBuilder)constructor.Invoke(new object[] { id })); ApplyCustomActions(id, builder.Builder); Builders.Add(id, builder); BuildersByEntityType.AddOrAppend(id, builder); return(builder); }
/// <summary> /// Applies the custom action to all Builders for the given type. /// </summary> /// <typeparam name="TBuilder">The type of the builder.</typeparam> /// <param name="logicalName">Name of the logical.</param> /// <param name="action">The action.</param> /// <exception cref="System.Exception"></exception> private void ApplyCustomAction <TBuilder>(string logicalName, Action <TBuilder> action) where TBuilder : class, IEntityBuilder { if (!BuildersByEntityType.TryGetValue(logicalName, out List <BuilderInfo> builders)) { return; } foreach (var result in builders.Select(b => b.Builder)) { if (!(result is TBuilder builder)) { throw new Exception($"Unexpected type of builder! Builder for {logicalName}, was not of type {typeof(TBuilder).FullName}, but type {result.GetType().FullName}."); } action(builder); } }
/// <summary> /// Applies the custom action to all Builders for the given type. /// </summary> /// <typeparam name="TBuilder">The type of the builder.</typeparam> /// <param name="logicalName">Name of the logical.</param> /// <param name="action">The action.</param> /// <exception cref="System.Exception"></exception> private void ApplyCustomAction <TBuilder>(string logicalName, Action <TBuilder> action) where TBuilder : class { List <BuilderInfo> builders; if (!BuildersByEntityType.TryGetValue(logicalName, out builders)) { return; } foreach (var result in builders) { var builder = result as TBuilder; if (builder == null) { throw new Exception(String.Format("Unexpected type of builder! Builder for {0}, was not of type {1}, but type {2}.", logicalName, typeof(TBuilder).FullName, result.GetType().FullName)); } action(builder); } }