/// <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); }
/// <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); }