public async Task Update <TModel>(TModel model) { // guard from kunckleheads if (model == null) { throw new ArgumentNullException(nameof(model)); } ThrowIfUnmanaged(model); var patch = BuildPatch(model); // if nothing was updated, no need to continue if (patch == null) { return; } var allModels = ModelRegistry.IncludedModelsCreate(model); foreach (var newModel in allModels) { var newResource = BuildModelResource(newModel); // Update the model instance in the argument var initialize = newModel.GetType().GetInitializeMethod(); initialize.Invoke(newModel, new object[] { newResource, this }); } var includes = allModels.Select(ModelRegistry.GetResource).ToArray(); var originalResource = ModelRegistry.GetResource(model); var root = ResourceRootSingle.FromResource(patch, includes); var request = await HttpRequestBuilder.UpdateResource(originalResource, root); var response = await HttpClient.SendAsync(request).ConfigureAwait(false); HttpResponseListener.UpdateResource(response.StatusCode, originalResource, root); response.CheckStatusCode(); if (response.StatusCode == HttpStatusCode.OK) { var responseRoot = await response.GetContentModel <ResourceRootSingle>(JsonSettings); // Update the model instance in the argument var initialize = typeof(TModel).GetInitializeMethod(); initialize.Invoke(model, new object[] { responseRoot.Data, this }); Cache.Update(responseRoot.Data.Id, model); } else if (response.StatusCode == HttpStatusCode.NoContent) { ModelRegistry.ApplyPatch(model, patch); } // create and cache includes await Task.WhenAll(allModels.Select(x => Task.Run(() => { var resource = ModelRegistry.GetResource(x); Cache.Update(resource.Id, x); }))); }
private async Task <TModel> Create <TModel>(Type rootModelType, object model) { ThrowIfDisposed(); // set Id if unset var modelId = model == null ? Guid.NewGuid() : ModelRegistry.GetOrCreateId(model); if (modelId == Guid.Empty) { modelId = Guid.NewGuid(); ModelRegistry.SetId(model, modelId); } // Create a new model instance if not already existing if (model == null) { model = Activator.CreateInstance <TModel>(); ModelRegistry.SetId(model, modelId); } if (ModelRegistry.IsManagedModel(model)) { throw new ManagedModelCreationException(model.GetType(), modelId); } // all unmanaged models in the object graph, including root var allModels = ModelRegistry.IncludedModelsCreate(model); foreach (var newModel in allModels) { var newResource = BuildModelResource(newModel); // Update the model instance in the argument var initialize = newModel.GetType().GetInitializeMethod(); initialize.Invoke(newModel, new object[] { newResource, this }); } var rootResource = ModelRegistry.GetResource(model); var includes = allModels.Where(x => x != model).Select(ModelRegistry.GetResource).ToArray(); if (Log.IsDebugEnabled()) { Log.Debug(() => $"preparing to POST {rootResource.Type}:{{{rootResource.Id}}}"); foreach (var include in includes) { Log.Debug(() => $"preparing to POST included {include.Type}:{{{include.Id}}}"); } } var root = ResourceRootSingle.FromResource(rootResource, includes); var request = await HttpRequestBuilder.CreateResource(root); var response = await HttpClient.SendAsync(request).ConfigureAwait(false); HttpResponseListener.CreateResource(response.StatusCode, root); response.CheckStatusCode(); if (response.StatusCode == HttpStatusCode.Created) { var responseRoot = await response.GetContentModel <ResourceRootSingle>(JsonSettings); // Update the model instance in the argument var initialize = rootModelType.GetInitializeMethod(); initialize.Invoke(model, new object[] { responseRoot.Data, this }); } // create and cache includes await Task.WhenAll(allModels.Select(x => Task.Run(() => { var resource = ModelRegistry.GetResource(x); Cache.Update(resource.Id, x); }))); return((TModel)model); }