private static async Task PerformPreEvent( SubmitContext context, IEnumerable <ChangeSetEntry> changeSetItems, CancellationToken cancellationToken) { foreach (ChangeSetEntry entry in changeSetItems) { if (entry.ChangeSetEntityState == DynamicChangeSetEntityState.Validated) { entry.ChangeSetEntityState = DynamicChangeSetEntityState.PreEventing; var filter = context.GetApiService <IChangeSetEntryFilter>(); if (filter != null) { await filter.OnExecutingEntryAsync(context, entry, cancellationToken); } if (entry.ChangeSetEntityState == DynamicChangeSetEntityState.PreEventing) { // if the state is still the intermediate state, // the entity was not changed during processing // and can move to the next step entry.ChangeSetEntityState = DynamicChangeSetEntityState.PreEvented; } else if (entry.ChangeSetEntityState == DynamicChangeSetEntityState.Changed /*&& * entity.Details.EntityState == originalEntityState*/) { entry.ChangeSetEntityState = DynamicChangeSetEntityState.ChangedWithinOwnPreEventing; } } } }
/// <inheritdoc/> public Task<bool> AuthorizeAsync( SubmitContext context, ChangeSetEntry entry, CancellationToken cancellationToken) { Ensure.NotNull(context, "context"); bool result = true; Type returnType = typeof(bool); string methodName = ConventionBasedChangeSetAuthorizer.GetAuthorizeMethodName(entry); MethodInfo method = this.targetType.GetQualifiedMethod(methodName); if (method != null && method.IsFamily && method.ReturnType == returnType) { object target = null; if (!method.IsStatic) { target = context.GetApiService<ApiBase>(); if (target == null || !this.targetType.IsAssignableFrom(target.GetType())) { return Task.FromResult(result); } } var parameters = method.GetParameters(); if (parameters.Length == 0) { result = (bool)method.Invoke(target, null); } } return Task.FromResult(result); }
/// <summary> /// Asynchronously executes the submit flow. /// </summary> /// <param name="context"> /// The submit context. /// </param> /// <param name="cancellationToken"> /// A cancellation token. /// </param> /// <returns> /// A task that represents the asynchronous /// operation whose result is a submit result. /// </returns> public static async Task <SubmitResult> SubmitAsync( SubmitContext context, CancellationToken cancellationToken) { Ensure.NotNull(context, "context"); var preparer = context.GetApiService <IChangeSetInitializer>(); if (preparer == null) { throw new NotSupportedException(Resources.ChangeSetPreparerMissing); } await preparer.InitializeAsync(context, cancellationToken); if (context.Result != null) { return(context.Result); } var eventsChangeSet = context.ChangeSet; IEnumerable <ChangeSetItem> currentChangeSetItems = eventsChangeSet.Entries.ToArray(); await PerformValidate(context, currentChangeSetItems, cancellationToken); await PerformPreEvent(context, currentChangeSetItems, cancellationToken); await PerformPersist(context, currentChangeSetItems, cancellationToken); context.ChangeSet.Entries.Clear(); await PerformPostEvent(context, currentChangeSetItems, cancellationToken); return(context.Result); }
private static async Task InvokeValidators( SubmitContext context, IEnumerable <ChangeSetEntry> changeSetItems, CancellationToken cancellationToken) { var validator = context.GetApiService <IChangeSetEntryValidator>(); if (validator == null) { return; } ValidationResults validationResults = new ValidationResults(); foreach (ChangeSetEntry entry in changeSetItems.Where(i => i.HasChanged())) { await validator.ValidateEntityAsync(context, entry, validationResults, cancellationToken); } if (validationResults.HasErrors) { string validationErrorMessage = Resources.ValidationFailsTheOperation; throw new ValidationException(validationErrorMessage) { ValidationResults = validationResults.Errors }; } }
/// <summary> /// Asynchronously executes the submit flow. /// </summary> /// <param name="context"> /// The submit context. /// </param> /// <param name="cancellationToken"> /// A cancellation token. /// </param> /// <returns> /// A task that represents the asynchronous /// operation whose result is a submit result. /// </returns> public static async Task<SubmitResult> SubmitAsync( SubmitContext context, CancellationToken cancellationToken) { Ensure.NotNull(context, "context"); var preparer = context.GetApiService<IChangeSetPreparer>(); if (preparer == null) { throw new NotSupportedException(Resources.ChangeSetPreparerMissing); } await preparer.PrepareAsync(context, cancellationToken); if (context.Result != null) { return context.Result; } var eventsChangeSet = context.ChangeSet; IEnumerable<ChangeSetEntry> currentChangeSetItems = eventsChangeSet.Entries.ToArray(); await PerformValidate(context, currentChangeSetItems, cancellationToken); await PerformPreEvent(context, currentChangeSetItems, cancellationToken); await PerformPersist(context, currentChangeSetItems, cancellationToken); context.ChangeSet.Entries.Clear(); await PerformPostEvent(context, currentChangeSetItems, cancellationToken); return context.Result; }
private static async Task InvokeValidators( SubmitContext context, IEnumerable <ChangeSetItem> changeSetItems, CancellationToken cancellationToken) { var validator = context.GetApiService <IChangeSetItemValidator>(); if (validator == null) { return; } Collection <ChangeSetItemValidationResult> validationResults = new Collection <ChangeSetItemValidationResult>(); foreach (ChangeSetItem entry in changeSetItems.Where(i => i.HasChanged())) { await validator.ValidateChangeSetItemAsync(context, entry, validationResults, cancellationToken); } IEnumerable <ChangeSetItemValidationResult> errors = validationResults.Where(result => result.Severity == EventLevel.Error); if (errors.Any()) { string validationErrorMessage = Resources.ValidationFailsTheOperation; throw new ChangeSetValidationException(validationErrorMessage) { ValidationResults = errors }; } }
private static async Task PerformPreEvent( SubmitContext context, IEnumerable <ChangeSetItem> changeSetItems, CancellationToken cancellationToken) { foreach (ChangeSetItem item in changeSetItems) { if (item.ChangeSetItemProcessingStage == ChangeSetItemProcessingStage.Validated) { item.ChangeSetItemProcessingStage = ChangeSetItemProcessingStage.PreEventing; var processor = context.GetApiService <IChangeSetItemProcessor>(); if (processor != null) { await processor.OnProcessingChangeSetItemAsync(context, item, cancellationToken); } if (item.ChangeSetItemProcessingStage == ChangeSetItemProcessingStage.PreEventing) { // if the state is still the intermediate state, // the entity was not changed during processing // and can move to the next step item.ChangeSetItemProcessingStage = ChangeSetItemProcessingStage.PreEvented; } else if (item.ChangeSetItemProcessingStage == ChangeSetItemProcessingStage.Initialized /*&& * entity.Details.EntityState == originalEntityState*/) { item.ChangeSetItemProcessingStage = ChangeSetItemProcessingStage.ChangedWithinOwnPreEventing; } } } }
/// <summary> /// Asynchronously executes the submission. /// </summary> /// <param name="context">The submit context class used for preparation.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The task object that represents this asynchronous operation.</returns> public async Task<SubmitResult> ExecuteSubmitAsync( SubmitContext context, CancellationToken cancellationToken) { DbContext dbContext = context.GetApiService<DbContext>(); await dbContext.SaveChangesAsync(cancellationToken); return new SubmitResult(context.ChangeSet); }
private static async Task PerformPostEvent( SubmitContext context, IEnumerable <ChangeSetEntry> changeSetItems, CancellationToken cancellationToken) { foreach (ChangeSetEntry entry in changeSetItems) { var filter = context.GetApiService <IChangeSetEntryFilter>(); if (filter != null) { await filter.OnExecutedEntryAsync(context, entry, cancellationToken); } } }
private static async Task PerformPostEvent( SubmitContext context, IEnumerable <ChangeSetItem> changeSetItems, CancellationToken cancellationToken) { foreach (ChangeSetItem item in changeSetItems) { var processor = context.GetApiService <IChangeSetItemProcessor>(); if (processor != null) { await processor.OnProcessedChangeSetItemAsync(context, item, cancellationToken); } } }
private static async Task PerformPersist( SubmitContext context, IEnumerable <ChangeSetItem> changeSetItems, CancellationToken cancellationToken) { var executor = context.GetApiService <ISubmitExecutor>(); if (executor == null) { throw new NotSupportedException(Resources.SubmitExecutorMissing); } context.Result = await executor.ExecuteSubmitAsync(context, cancellationToken); }
private static async Task InvokeAuthorizers( SubmitContext context, IEnumerable <ChangeSetItem> changeSetItems, CancellationToken cancellationToken) { var authorizer = context.GetApiService <IChangeSetItemAuthorizer>(); if (authorizer == null) { return; } foreach (ChangeSetItem item in changeSetItems.Where(i => i.HasChanged())) { if (!await authorizer.AuthorizeAsync(context, item, cancellationToken)) { var message = DefaultSubmitHandler.GetAuthorizeFailedMessage(item); throw new SecurityException(message); } } }
private static async Task PerformPersist( SubmitContext context, IEnumerable <ChangeSetEntry> changeSetItems, CancellationToken cancellationToken) { // Once the change is persisted, the EntityState is lost. // In order to invoke the correct post-CUD event, remember which action was performed on the entity. foreach (ChangeSetEntry item in changeSetItems) { if (item.Type == ChangeSetEntryType.DataModification) { DataModificationEntry dataModification = (DataModificationEntry)item; if (dataModification.IsNew) { dataModification.AddAction = AddAction.Inserting; } else if (dataModification.IsUpdate) { dataModification.AddAction = AddAction.Updating; } else if (dataModification.IsDelete) { dataModification.AddAction = AddAction.Removing; } } } var executor = context.GetApiService <ISubmitExecutor>(); if (executor == null) { throw new NotSupportedException(Resources.SubmitExecutorMissing); } context.Result = await executor.ExecuteSubmitAsync(context, cancellationToken); }
private static async Task InvokeAuthorizers( SubmitContext context, IEnumerable<ChangeSetEntry> changeSetItems, CancellationToken cancellationToken) { var authorizer = context.GetApiService<IChangeSetEntryAuthorizer>(); if (authorizer == null) { return; } foreach (ChangeSetEntry entry in changeSetItems.Where(i => i.HasChanged())) { if (!await authorizer.AuthorizeAsync(context, entry, cancellationToken)) { var message = DefaultSubmitHandler.GetAuthorizeFailedMessage(entry); throw new SecurityException(message); } } }
private static async Task PerformPreEvent( SubmitContext context, IEnumerable<ChangeSetItem> changeSetItems, CancellationToken cancellationToken) { foreach (ChangeSetItem item in changeSetItems) { if (item.ChangeSetItemProcessingStage == ChangeSetItemProcessingStage.Validated) { item.ChangeSetItemProcessingStage = ChangeSetItemProcessingStage.PreEventing; var processor = context.GetApiService<IChangeSetItemFilter>(); if (processor != null) { await processor.OnChangeSetItemProcessingAsync(context, item, cancellationToken); } if (item.ChangeSetItemProcessingStage == ChangeSetItemProcessingStage.PreEventing) { // if the state is still the intermediate state, // the entity was not changed during processing // and can move to the next step item.ChangeSetItemProcessingStage = ChangeSetItemProcessingStage.PreEvented; } else if (item.ChangeSetItemProcessingStage == ChangeSetItemProcessingStage.Initialized /*&& entity.Details.EntityState == originalEntityState*/) { item.ChangeSetItemProcessingStage = ChangeSetItemProcessingStage.ChangedWithinOwnPreEventing; } } } }
private static async Task PerformPersist( SubmitContext context, IEnumerable<ChangeSetItem> changeSetItems, CancellationToken cancellationToken) { var executor = context.GetApiService<ISubmitExecutor>(); if (executor == null) { throw new NotSupportedException(Resources.SubmitExecutorMissing); } context.Result = await executor.ExecuteSubmitAsync(context, cancellationToken); }
private static async Task PerformPostEvent( SubmitContext context, IEnumerable<ChangeSetItem> changeSetItems, CancellationToken cancellationToken) { foreach (ChangeSetItem item in changeSetItems) { var processor = context.GetApiService<IChangeSetItemFilter>(); if (processor != null) { await processor.OnChangeSetItemProcessedAsync(context, item, cancellationToken); } } }
private static async Task PerformPostEvent( SubmitContext context, IEnumerable<ChangeSetEntry> changeSetItems, CancellationToken cancellationToken) { foreach (ChangeSetEntry entry in changeSetItems) { var filter = context.GetApiService<IChangeSetEntryFilter>(); if (filter != null) { await filter.OnExecutedEntryAsync(context, entry, cancellationToken); } } }
private static async Task PerformPersist( SubmitContext context, IEnumerable<ChangeSetEntry> changeSetItems, CancellationToken cancellationToken) { // Once the change is persisted, the EntityState is lost. // In order to invoke the correct post-CUD event, remember which action was performed on the entity. foreach (ChangeSetEntry item in changeSetItems) { if (item.Type == ChangeSetEntryType.DataModification) { DataModificationEntry dataModification = (DataModificationEntry)item; if (dataModification.IsNew) { dataModification.AddAction = AddAction.Inserting; } else if (dataModification.IsUpdate) { dataModification.AddAction = AddAction.Updating; } else if (dataModification.IsDelete) { dataModification.AddAction = AddAction.Removing; } } } var executor = context.GetApiService<ISubmitExecutor>(); if (executor == null) { throw new NotSupportedException(Resources.SubmitExecutorMissing); } context.Result = await executor.ExecuteSubmitAsync(context, cancellationToken); }
private static async Task PerformPreEvent( SubmitContext context, IEnumerable<ChangeSetEntry> changeSetItems, CancellationToken cancellationToken) { foreach (ChangeSetEntry entry in changeSetItems) { if (entry.ChangeSetEntityState == DynamicChangeSetEntityState.Validated) { entry.ChangeSetEntityState = DynamicChangeSetEntityState.PreEventing; var filter = context.GetApiService<IChangeSetEntryFilter>(); if (filter != null) { await filter.OnExecutingEntryAsync(context, entry, cancellationToken); } if (entry.ChangeSetEntityState == DynamicChangeSetEntityState.PreEventing) { // if the state is still the intermediate state, // the entity was not changed during processing // and can move to the next step entry.ChangeSetEntityState = DynamicChangeSetEntityState.PreEvented; } else if (entry.ChangeSetEntityState == DynamicChangeSetEntityState.Changed /*&& entity.Details.EntityState == originalEntityState*/) { entry.ChangeSetEntityState = DynamicChangeSetEntityState.ChangedWithinOwnPreEventing; } } } }
private static async Task InvokeValidators( SubmitContext context, IEnumerable<ChangeSetItem> changeSetItems, CancellationToken cancellationToken) { var validator = context.GetApiService<IChangeSetItemValidator>(); if (validator == null) { return; } Collection<ChangeSetItemValidationResult> validationResults = new Collection<ChangeSetItemValidationResult>(); foreach (ChangeSetItem entry in changeSetItems.Where(i => i.HasChanged())) { await validator.ValidateChangeSetItemAsync(context, entry, validationResults, cancellationToken); } IEnumerable<ChangeSetItemValidationResult> errors = validationResults.Where(result => result.Severity == EventLevel.Error); if (errors.Any()) { string validationErrorMessage = Resources.ValidationFailsTheOperation; throw new ChangeSetValidationException(validationErrorMessage) { ValidationResults = errors }; } }
private Task InvokeProcessorMethodAsync( SubmitContext context, ChangeSetItem item, string methodNameSuffix) { string methodName = GetMethodName(item, methodNameSuffix); object[] parameters = GetParameters(item); MethodInfo method = this.targetType.GetQualifiedMethod(methodName); if (method != null && (method.ReturnType == typeof(void) || typeof(Task).IsAssignableFrom(method.ReturnType))) { object target = null; if (!method.IsStatic) { target = context.GetApiService<ApiBase>(); if (target == null || !this.targetType.IsInstanceOfType(target)) { return Task.WhenAll(); } } ParameterInfo[] methodParameters = method.GetParameters(); if (ParametersMatch(methodParameters, parameters)) { object result = method.Invoke(target, parameters); Task resultTask = result as Task; if (resultTask != null) { return resultTask; } } } return Task.WhenAll(); }
private static async Task InvokeValidators( SubmitContext context, IEnumerable<ChangeSetEntry> changeSetItems, CancellationToken cancellationToken) { var validator = context.GetApiService<IChangeSetEntryValidator>(); if (validator == null) { return; } ValidationResults validationResults = new ValidationResults(); foreach (ChangeSetEntry entry in changeSetItems.Where(i => i.HasChanged())) { await validator.ValidateEntityAsync(context, entry, validationResults, cancellationToken); } if (validationResults.HasErrors) { string validationErrorMessage = Resources.ValidationFailsTheOperation; throw new ValidationException(validationErrorMessage) { ValidationResults = validationResults.Errors }; } }
private Task InvokeFilterMethodAsync( SubmitContext context, ChangeSetEntry entry, string methodNameSuffix) { string methodName = ConventionBasedChangeSetEntryFilter.GetMethodName(entry, methodNameSuffix); object[] parameters = ConventionBasedChangeSetEntryFilter.GetParameters(entry); MethodInfo method = this.targetType.GetQualifiedMethod(methodName); if (method != null && (method.ReturnType == typeof(void) || typeof(Task).IsAssignableFrom(method.ReturnType))) { object target = null; if (!method.IsStatic) { target = context.GetApiService<ApiBase>(); if (target == null || !this.targetType.IsAssignableFrom(target.GetType())) { return Task.WhenAll(); } } ParameterInfo[] methodParameters = method.GetParameters(); if (ConventionBasedChangeSetEntryFilter.ParametersMatch(methodParameters, parameters)) { object result = method.Invoke(target, parameters); Task resultTask = result as Task; if (resultTask != null) { return resultTask; } } } return Task.WhenAll(); }