Esempio n. 1
0
        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);
            })));
        }
Esempio n. 2
0
        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);
        }