Beispiel #1
0
        /// <inheritdoc />
        public virtual async Task <TResource> CreateAsync(TResource resource, CancellationToken cancellationToken)
        {
            _traceWriter.LogMethodStart(new
            {
                resource
            });

            ArgumentGuard.NotNull(resource, nameof(resource));

            TResource resourceFromRequest = resource;

            _resourceChangeTracker.SetRequestedAttributeValues(resourceFromRequest);

            _hookExecutor.BeforeCreate(resourceFromRequest);

            TResource resourceForDatabase = await _repositoryAccessor.GetForCreateAsync <TResource, TId>(resource.Id, cancellationToken);

            _resourceChangeTracker.SetInitiallyStoredAttributeValues(resourceForDatabase);

            try
            {
                await _repositoryAccessor.CreateAsync(resourceFromRequest, resourceForDatabase, cancellationToken);
            }
            catch (DataStoreUpdateException)
            {
                if (!Equals(resourceFromRequest.Id, default(TId)))
                {
                    TResource existingResource =
                        await TryGetPrimaryResourceByIdAsync(resourceFromRequest.Id, TopFieldSelection.OnlyIdAttribute, cancellationToken);

                    if (existingResource != null)
                    {
                        throw new ResourceAlreadyExistsException(resourceFromRequest.StringId, _request.PrimaryResource.PublicName);
                    }
                }

                await AssertResourcesToAssignInRelationshipsExistAsync(resourceFromRequest, cancellationToken);

                throw;
            }

            TResource resourceFromDatabase =
                await TryGetPrimaryResourceByIdAsync(resourceForDatabase.Id, TopFieldSelection.WithAllAttributes, cancellationToken);

            AssertPrimaryResourceExists(resourceFromDatabase);

            _hookExecutor.AfterCreate(resourceFromDatabase);

            _resourceChangeTracker.SetFinallyStoredAttributeValues(resourceFromDatabase);

            bool hasImplicitChanges = _resourceChangeTracker.HasImplicitChanges();

            if (!_options.AlwaysReturnResourceOnCreateUpdate && !hasImplicitChanges)
            {
                return(null);
            }

            _hookExecutor.OnReturnSingle(resourceFromDatabase, ResourcePipeline.Post);
            return(resourceFromDatabase);
        }
Beispiel #2
0
        /// <inheritdoc />
        public virtual async Task <TResource> CreateAsync(TResource resource, CancellationToken cancellationToken)
        {
            _traceWriter.LogMethodStart(new { resource });
            if (resource == null)
            {
                throw new ArgumentNullException(nameof(resource));
            }

            _resourceChangeTracker.SetRequestedAttributeValues(resource);

            var defaultResource = _resourceFactory.CreateInstance <TResource>();

            defaultResource.Id = resource.Id;

            _resourceChangeTracker.SetInitiallyStoredAttributeValues(defaultResource);

            _hookExecutor.BeforeCreate(resource);

            try
            {
                await _repositoryAccessor.CreateAsync(resource, cancellationToken);
            }
            catch (DataStoreUpdateException)
            {
                var existingResource = await TryGetPrimaryResourceByIdAsync(resource.Id, TopFieldSelection.OnlyIdAttribute, cancellationToken);

                if (existingResource != null)
                {
                    throw new ResourceAlreadyExistsException(resource.StringId, _request.PrimaryResource.PublicName);
                }

                await AssertResourcesToAssignInRelationshipsExistAsync(resource, cancellationToken);

                throw;
            }

            var resourceFromDatabase = await TryGetPrimaryResourceByIdAsync(resource.Id, TopFieldSelection.WithAllAttributes, cancellationToken);

            AssertPrimaryResourceExists(resourceFromDatabase);

            _hookExecutor.AfterCreate(resourceFromDatabase);

            _resourceChangeTracker.SetFinallyStoredAttributeValues(resourceFromDatabase);

            bool hasImplicitChanges = _resourceChangeTracker.HasImplicitChanges();

            if (!hasImplicitChanges)
            {
                return(null);
            }

            _hookExecutor.OnReturnSingle(resourceFromDatabase, ResourcePipeline.Post);
            return(resourceFromDatabase);
        }
        /// <inheritdoc />
        public virtual async Task <TResource> UpdateAsync(TId id, TResource requestResource)
        {
            _traceWriter.LogMethodStart(new { id, requestResource });
            if (requestResource == null)
            {
                throw new ArgumentNullException(nameof(requestResource));
            }

            TResource databaseResource = await GetPrimaryResourceById(id, false);

            _resourceChangeTracker.SetInitiallyStoredAttributeValues(databaseResource);
            _resourceChangeTracker.SetRequestedAttributeValues(requestResource);

            if (_hookExecutor != null)
            {
                requestResource = _hookExecutor.BeforeUpdate(AsList(requestResource), ResourcePipeline.Patch).Single();
            }

            await _repository.UpdateAsync(requestResource, databaseResource);

            if (_hookExecutor != null)
            {
                _hookExecutor.AfterUpdate(AsList(databaseResource), ResourcePipeline.Patch);
                _hookExecutor.OnReturn(AsList(databaseResource), ResourcePipeline.Patch);
            }

            _repository.FlushFromCache(databaseResource);
            TResource afterResource = await GetPrimaryResourceById(id, false);

            _resourceChangeTracker.SetFinallyStoredAttributeValues(afterResource);

            bool hasImplicitChanges = _resourceChangeTracker.HasImplicitChanges();

            return(hasImplicitChanges ? afterResource : null);
        }
        public virtual async Task <TResource> UpdateAsync(TId id, TResource requestEntity)
        {
            _logger.LogTrace($"Entering {nameof(UpdateAsync)}('{id}', {(requestEntity == null ? "null" : "object")}).");

            TResource databaseEntity = await _repository.Get(id).FirstOrDefaultAsync();

            if (databaseEntity == null)
            {
                string resourceId = TypeHelper.GetResourceStringId <TResource, TId>(id, _resourceFactory);
                throw new ResourceNotFoundException(resourceId, _currentRequestResource.ResourceName);
            }

            _resourceChangeTracker.SetInitiallyStoredAttributeValues(databaseEntity);
            _resourceChangeTracker.SetRequestedAttributeValues(requestEntity);

            requestEntity = IsNull(_hookExecutor) ? requestEntity : _hookExecutor.BeforeUpdate(AsList(requestEntity), ResourcePipeline.Patch).Single();

            await _repository.UpdateAsync(requestEntity, databaseEntity);

            if (!IsNull(_hookExecutor, databaseEntity))
            {
                _hookExecutor.AfterUpdate(AsList(databaseEntity), ResourcePipeline.Patch);
                _hookExecutor.OnReturn(AsList(databaseEntity), ResourcePipeline.Patch);
            }

            _repository.FlushFromCache(databaseEntity);
            TResource afterEntity = await _repository.Get(id).FirstOrDefaultAsync();

            _resourceChangeTracker.SetFinallyStoredAttributeValues(afterEntity);

            bool hasImplicitChanges = _resourceChangeTracker.HasImplicitChanges();

            return(hasImplicitChanges ? afterEntity : null);
        }
        public virtual async Task <TResource> UpdateAsync(TId id, TResource requestResource)
        {
            _logger.LogTrace($"Entering {nameof(UpdateAsync)}('{id}', {(requestResource == null ? "null" : "object")}).");

            TResource databaseResource = await GetPrimaryResourceById(id, false);

            _resourceChangeTracker.SetInitiallyStoredAttributeValues(databaseResource);
            _resourceChangeTracker.SetRequestedAttributeValues(requestResource);

            if (_hookExecutor != null)
            {
                requestResource = _hookExecutor.BeforeUpdate(AsList(requestResource), ResourcePipeline.Patch).Single();
            }

            await _repository.UpdateAsync(requestResource, databaseResource);

            if (_hookExecutor != null)
            {
                _hookExecutor.AfterUpdate(AsList(databaseResource), ResourcePipeline.Patch);
                _hookExecutor.OnReturn(AsList(databaseResource), ResourcePipeline.Patch);
            }

            _repository.FlushFromCache(databaseResource);
            TResource afterResource = await GetPrimaryResourceById(id, false);

            _resourceChangeTracker.SetFinallyStoredAttributeValues(afterResource);

            bool hasImplicitChanges = _resourceChangeTracker.HasImplicitChanges();

            return(hasImplicitChanges ? afterResource : null);
        }