public void AddFakeMessageExecutor<T>(IFakeMessageExecutor executor) where T : OrganizationRequest
 {
     if (!FakeMessageExecutors.ContainsKey(typeof(T)))
         FakeMessageExecutors.Add(typeof(T), executor);
     else
         FakeMessageExecutors[typeof(T)] = executor;
 }
 public void RemoveFakeMessageExecutor <T>() where T : OrganizationRequest
 {
     FakeMessageExecutors.Remove(typeof(T));
 }
        protected internal Guid CreateEntity(Entity e)
        {
            if (e == null)
            {
                throw new InvalidOperationException("The entity must not be null");
            }

            var clone = e.Clone(e.GetType());

            if (clone.Id == Guid.Empty)
            {
                clone.Id = Guid.NewGuid(); // Add default guid if none present
            }

            // Hack for Dynamic Entities where the Id property doesn't populate the "entitynameid" primary key
            var primaryKeyAttribute = $"{e.LogicalName}id";

            if (!clone.Attributes.ContainsKey(primaryKeyAttribute))
            {
                clone[primaryKeyAttribute] = clone.Id;
            }

            ValidateEntity(clone);

            // Create specific validations
            if (clone.Id != Guid.Empty && Data.ContainsKey(clone.LogicalName) &&
                Data[clone.LogicalName].ContainsKey(clone.Id))
            {
                throw new InvalidOperationException($"There is already a record of entity {clone.LogicalName} with id {clone.Id}, can't create with this Id.");
            }

            // Create specific validations
            if (clone.Attributes.ContainsKey("statecode"))
            {
                throw new InvalidOperationException($"When creating an entity with logical name '{clone.LogicalName}', or any other entity, it is not possible to create records with the statecode property. Statecode must be set after creation.");
            }

            AddEntityWithDefaults(clone, false, false);

            if (e.RelatedEntities.Count > 0)
            {
                foreach (var relationshipSet in e.RelatedEntities)
                {
                    var relationship = relationshipSet.Key;

                    var entityReferenceCollection = new EntityReferenceCollection();

                    foreach (var relatedEntity in relationshipSet.Value.Entities)
                    {
                        var relatedId = CreateEntity(relatedEntity);
                        entityReferenceCollection.Add(new EntityReference(relatedEntity.LogicalName, relatedId));
                    }

                    if (FakeMessageExecutors.ContainsKey(typeof(AssociateRequest)))
                    {
                        var request = new AssociateRequest
                        {
                            Target          = clone.ToEntityReference(),
                            Relationship    = relationship,
                            RelatedEntities = entityReferenceCollection
                        };
                        FakeMessageExecutors[typeof(AssociateRequest)].Execute(request, this);
                    }
                    else
                    {
                        throw PullRequestException.NotImplementedOrganizationRequest(typeof(AssociateRequest));
                    }
                }
            }

            return(clone.Id);
        }
        protected internal void CreateEntity(Entity e)
        {
            if (e == null)
            {
                throw new InvalidOperationException("The entity must not be null");
            }

            if (e.Id == Guid.Empty)
            {
                e.Id = Guid.NewGuid(); //Add default guid if none present
            }

            //Hack for Dynamic Entities where the Id property doesn't populate the "entitynameid" primary key
            var primaryKeyAttribute = string.Format("{0}id", e.LogicalName);

            if (!e.Attributes.ContainsKey(primaryKeyAttribute))
            {
                e[primaryKeyAttribute] = e.Id;
            }

            ValidateEntity(e);

            //Create specific validations
            if (e.Id != Guid.Empty && Data.ContainsKey(e.LogicalName) &&
                Data[e.LogicalName].ContainsKey(e.Id))
            {
                throw new InvalidOperationException(string.Format("There is already a record of entity {0} with id {1}, can't create with this Id.", e.LogicalName, e.Id));
            }

            AddEntityWithDefaults(e);

            if (e.RelatedEntities.Count > 0)
            {
                foreach (var relationshipSet in e.RelatedEntities)
                {
                    Relationship relationship = relationshipSet.Key;
                    foreach (var relatedEntity in relationshipSet.Value.Entities)
                    {
                        CreateEntity(relatedEntity);
                    }

                    if (FakeMessageExecutors.ContainsKey(typeof(AssociateRequest)))
                    {
                        var entityReferenceCollection = new EntityReferenceCollection(relationshipSet.Value.Entities.Select(en => en.ToEntityReference()).ToList());
                        var request = new AssociateRequest()
                        {
                            Target = new EntityReference()
                            {
                                Id = e.Id, LogicalName = e.LogicalName
                            },
                            Relationship    = relationship,
                            RelatedEntities = entityReferenceCollection
                        };
                        FakeMessageExecutors[typeof(AssociateRequest)].Execute(request, this);
                    }
                    else
                    {
                        throw PullRequestException.NotImplementedOrganizationRequest(typeof(AssociateRequest));
                    }
                }
            }
        }