protected override Task <DependencyResult <TDependencyInstance> > ResolveNewDependencyInstanceAsync(IDependencyResolutionContext context) { try { var specs = context.EnsureNotNull(nameof(context)).Value.Specs; // var factoryArgs = ReadDA(ref _factoryArgs); if (factoryArgs is null) { // Поскольку в данном обработчике явно не заданы параметры конструктора нового экземпляра, используются те, что указаны в спецификации, если они подходят для использования (см. код ниже). // if ((factoryArgs = specs.NewInstanceFactoryArgs as IArgsTuple <TArg1>) == null || factoryArgs.ArgsCount != __ArgsCount) { return(TaskUtilities.FromResult(DependencyResult <TDependencyInstance> .None)); } } else if (!(specs.NewInstanceFactoryArgs is null)) { // Поскольку спецификацией явно определены параметры конструктора нового экземпляра, а также явно заданны в данном обработчике (factoryArgs != null), то получается конфликт. // return(TaskUtilities.FromResult(DependencyResult <TDependencyInstance> .None)); } return (TaskUtilities .FromResult( result: new DependencyResult <TDependencyInstance>( instance: ReadDA(ref _getDependencyCtor)()(factoryArgs.Arg1), isNewInstance: true))); } catch (Exception exception) { return(Task.FromException <DependencyResult <TDependencyInstance> >(exception)); } }
protected override Task <DependencyResult <TDependencyInstance> > ResolveNewDependencyInstanceAsync(IDependencyResolutionContext context) { try { var specs = context.EnsureNotNull(nameof(context)).Value.Specs; // var factoryArgs = ReadDA(ref _factoryArgs); if (factoryArgs is null) { if ((factoryArgs = specs.NewInstanceFactoryArgs as IArgsTuple <TArg1, TArg2, TArg3, TArg4, TArg5>) == null || factoryArgs.ArgsCount != __ArgsCount) { return(TaskUtilities.FromResult(DependencyResult <TDependencyInstance> .None)); } } else if (specs.NewInstanceFactoryArgs != null) { return(TaskUtilities.FromResult(DependencyResult <TDependencyInstance> .None)); } // return (TaskUtilities .FromResult( result: new DependencyResult <TDependencyInstance>( instance: ReadDA(ref _getDependencyCtor) () (factoryArgs.Arg1, factoryArgs.Arg2, factoryArgs.Arg3, factoryArgs.Arg4, factoryArgs.Arg5), isNewInstance: true))); } catch (Exception exception) { return(Task.FromException <DependencyResult <TDependencyInstance> >(exception)); } }
TEfDbContext P_GetDataChangeEfDbContext() { var result = ReadDA(ref _efCtxGetter, considerDisposeRequest: true)(); EnsureNotDisposeState(considerDisposeRequest: true); return(result); }
protected override Task <DependencyResult <TDependencyInstance> > ResolveNewDependencyInstanceAsync(IDependencyResolutionContext context) { try { var specs = context.EnsureNotNull(nameof(context)).Value.Specs; // if ((specs.NewInstanceFactoryArgs?.ArgsCount ?? 0) != __ArgsCount) { return(TaskUtilities.FromResult(DependencyResult <TDependencyInstance> .None)); } else { return (TaskUtilities .FromResult( result: new DependencyResult <TDependencyInstance>( instance: ReadDA(ref _getDependencyCtor, considerDisposeRequest: true)()(), isNewInstance: true))); } } catch (Exception exception) { return(Task.FromException <DependencyResult <TDependencyInstance> >(exception)); } }
// TODO: Put strings into the resources. // public Task <IRunControlAttemptSuccess> StartAsync(IContext ctx = default) { try { var component = Component; if ((Options & RunControlOptions.ForbidStart) == RunControlOptions.ForbidStart) { throw new EonException(message: $"Опциями элемента управления запуском/остановкой компонента, запрещено выполнение операции запуска.{Environment.NewLine}\tКомпонент:{component.FmtStr().GNLI2()}"); } else { return(TaskUtilities.RunOnDefaultScheduler(factory: doStartAsync)); } } catch (Exception exception) { return(Task.FromException <IRunControlAttemptSuccess>(exception: exception)); } // async Task <IRunControlAttemptSuccess> doStartAsync() { ctx.ThrowIfCancellationRequested(); var ctxCt = ctx.Ct(); var existingStartOp = default(RunControlStartOperationState <TComponent>); var newStartOp = default(RunControlStartOperationState <TComponent>); var component = Component; var begimTimestamp = StopwatchUtilities.GetTimestampAsTimeSpan(); try { UpdDABool( location: ref _existingStartOp, transform: (locCurrent, locPrevious) => { if (locCurrent is null) { return(locPrevious ?? (newStartOp = new RunControlStartOperationState <TComponent>(runControl: this, beginTimestamp: begimTimestamp, ct: ctxCt))); } else { return(locCurrent); } }, current: out existingStartOp); if (ReferenceEquals(newStartOp, existingStartOp)) { // Поток (задача), который непосредственно выполняет запуск. // if (!itrlck.IncrementBool(location: ref _startOpAttemptNumber, maxInclusive: int.MaxValue, result: out var attemptNumber)) { throw new EonException(message: $"Невозможно присвоить операции последовательный номер попытки. Счётчик попыток достиг предельного значения.{Environment.NewLine}\tКомпонент:{component.FmtStr().GNLI2()}"); } // Если выполняется операция остановки, то дождаться её завершения. // var existingStopOp = itrlck.Get(ref _existingStopOp); if (!(existingStopOp is null)) { try { await existingStopOp.Completion.WaitCompletionAsync(ct : ctxCt).ConfigureAwait(false); } catch (Exception exception) { if (exception.HasSingleBaseExceptionOf <OperationCanceledException>(out var operationCancellationException)) { itrlck.SetNullBool(ref _existingStartOp, comparand: newStartOp); newStartOp.TrySetCanceled(ct: operationCancellationException.CancellationToken); } throw; } try { await existingStopOp.Completion.ConfigureAwait(false); } catch (Exception exception) when(exception.HasSingleBaseExceptionOf <OperationCanceledException>()) { throw new EonException( message: $"Невозможно выполнить запуск компонента, так как ранее для компонента была инициирована операция остановки, которая была прервана или отменена.{Environment.NewLine}\tКомпонент:{component.FmtStr().GNLI2()}"); } catch (Exception exception) { throw new EonException( message: $"Невозможно выполнить запуск компонента, так как ранее для компонента была инициирована операция остановки, которая завершилась сбоем. Детали сбоя см. во внутреннем стеке данного исключения.{Environment.NewLine}\tКомпонент:{component.FmtStr().GNLI2()}", innerException: exception); } if ((Options & RunControlOptions.MultipleStart) == RunControlOptions.MultipleStart) { if (existingStopOp.FiniteStop) { newStartOp.TrySetCanceled(); throw new OperationCanceledException( message: $"Запуск компонента отменён, так как ранее поступил запрос остановки компонента без возможности перезапуска.{Environment.NewLine}\tКомпонент:{component.FmtStr().GNLI2()}"); } else if (!itrlck.SetNullBool(ref _existingStopOp, comparand: existingStopOp)) { throw new EonException( message: $"Не удалось привести управляющий элемент запуска/остановки компонента к предстартовому состоянию.{Environment.NewLine}\tКомпонент:{component.FmtStr().GNLI2()}"); } } else { newStartOp.TrySetCanceled(); throw new OperationCanceledException( message: $"Запуск компонента отменён, так как ранее поступил запрос остановки компонента и опциями элемента, управляющего запуском/остановкой компонента, не определена возможность многократного запуска компонента.{Environment.NewLine}\tКомпонент:{component.FmtStr().GNLI2()}"); } } // Запуск. // IContext locCtx = default; try { try { locCtx = P_CreateStartCtx(startOp: newStartOp, outerCtx: ctx); newStartOp.AttemptState = ReadDA(ref _attemptStateFactory) (args: new RunControlAttemptStateFactoryArgs( runControl: this, completion: newStartOp.Completion, context: locCtx, isStart: true, attemptNumber: attemptNumber, succeededAttemptCountBefore: vlt.Read(ref _startOpSucceededCount))); } catch (Exception exception) { if (exception.HasSingleBaseExceptionOf <OperationCanceledException>(baseException: out var operationCancellationException)) { itrlck.SetNullBool(location: ref _existingStartOp, comparand: newStartOp); newStartOp.TrySetCanceled(ct: operationCancellationException.CancellationToken); } throw; } // Процедура предзапуска. // try { locCtx.ThrowIfCancellationRequested(); await P_BeforeStartAsync(state : newStartOp.AttemptState).ConfigureAwait(false); } catch (Exception exception) { itrlck.SetNullBool(ref _existingStartOp, comparand: newStartOp); if (exception.HasSingleBaseExceptionOf <OperationCanceledException>(out var operationCancellationException)) { newStartOp.TrySetCanceled(ct: operationCancellationException.CancellationToken); throw; } else { throw new EonException(message: $"Сбой во время процедуры предзапуска компонента.{Environment.NewLine}\tКомпонент:{component.FmtStr().GNLI2()}", innerException: exception); } } // Процедура запуска. // try { locCtx.ThrowIfCancellationRequested(); var startTask = ReadDA(ref _startTaskFactory)(arg : newStartOp.AttemptState); if (startTask is null) { throw new EonException(message: $"Невозможно выполнить операцию запуска компонента, так как функция создания задачи выполнения запуска возвратила недопустимый результат '{startTask.FmtStr().G()}'.{Environment.NewLine}\tКомпонент:{component.FmtStr().GNLI2()}"); } await startTask.ConfigureAwait(false); } catch (Exception exception) { if (exception.HasSingleBaseExceptionOf <OperationCanceledException>(out var operationCancellationException)) { itrlck.SetNullBool(ref _existingStartOp, comparand: newStartOp); newStartOp.TrySetCanceled(ct: operationCancellationException.CancellationToken); throw; } else { throw new EonException(message: $"Сбой во время запуска компонента.{Environment.NewLine}\tКомпонент:{component.FmtStr().GNLI2()}", innerException: exception); } } itrlck.IncrementBool(location: ref _startOpSucceededCount, maxInclusive: int.MaxValue); var result = newStartOp.SetSucceeded(isMaster: true); P_TryFireAfterStartAsynchronously(result: result); return(result); } finally { locCtx?.Dispose(); } } else { newStartOp?.TrySetCanceled(synchronously: true); // TODO_HIGH: Возможно, нужно обрабатывать такую ситуацию, когда данный вызов получит результат в виде отменённой операции, потому что уже выполняющий другой вызов был отменён. Такая ситуация с точки зрения вызывающий стороны не совсем очевидна и предсказуема. // + нужно реализовать трансляцию хода выполнения из уже выполняющегося вызова в данный. // if (ctxCt == existingStartOp.Ct) { // Один и тот же токен отмены из разных вызовов. // return(new RunControlAttemptSuccess(other: await existingStartOp.Completion.ConfigureAwait(false), isMaster: false)); } else { return(new RunControlAttemptSuccess(other: await existingStartOp.Completion.WaitResultAsync(ct: ctxCt).ConfigureAwait(false), isMaster: false)); } } } catch (Exception exception) { if (ReferenceEquals(existingStartOp, newStartOp) && !(newStartOp is null)) { if (newStartOp.TrySetException(exception: exception, synchronously: true)) { // Здесь будет вызвано исключение. // await newStartOp.Completion; } throw; } else { throw; } } finally { if (!ReferenceEquals(existingStartOp, newStartOp)) { newStartOp?.TrySetCanceled(synchronously: true); } } } }
public IDependencyScope GetOuterScope() => ReadDA(ref _outerScopeGetter)();
public virtual IEnumerable <IVh <IDependencyHandler2> > ExportDependencies() => ReadDA(location: ref _exportDependencies)();
public IEnumerable <IVh <IDependencyHandler2> > ExportDependencies() => ReadDA(ref _export)();