internal DbContextScope( Func <TDbContext> dbContextFactory, AmbientScopeOption scopeOption) : base(scopeOption) { // Activate, gaining access to the potential parent scope this.Activate(); try { this.UnitOfWork = this.EffectiveParentScope?.UnitOfWork ?? new UnitOfWork <TDbContext>(dbContextFactory); } catch { // Dispose ourselves on failure, ensuring that we are deactivated this.Dispose(); throw; } }
public virtual TResult ExecuteInDbContextScope <TState, TResult>( AmbientScopeOption scopeOption, TState state, Func <IExecutionScope <TState>, TResult> task) { return(TransactionalStrategyExecutor.ExecuteInDbContextScope(this, scopeOption, state, task)); }
/// <summary> /// Constructs a new instance that defers to the given loggers. /// </summary> /// <param name="scopeOption">Allows joining any existing scope (i.e. adding additional logging mechanisms) or obscuring it (i.e. temporarily replacing the logging mechanisms).</param> /// <param name="loggers">The loggers to defer to.</param> public LogScope(AmbientScopeOption scopeOption, IEnumerable <ILogger> loggers) : this(scopeOption, loggers, isDefaultScope : false) { }
private protected DbContextScope(AmbientScopeOption scopeOption) : base(scopeOption) { }
/// <summary> /// Private constructor. /// Does not activate this instance. /// </summary> private IdGeneratorScope(IIdGenerator idGenerator, AmbientScopeOption ambientScopeOption) : base(ambientScopeOption) { this.IdGenerator = idGenerator ?? throw new ArgumentNullException(nameof(idGenerator)); }
public ManuallyActivatedScope(int index, AmbientScopeOption scopeOption, bool noNestingIgnoresDefaultScope = false) : base(scopeOption) { this.Index = index; this.NoNestingIgnoresDefaultScope = noNestingIgnoresDefaultScope; }
public static TResult ExecuteInDbContextScope <TContext, TState, TResult>(IDbContextProvider <TContext> provider, AmbientScopeOption scopeOption, TState state, Func <IExecutionScope <TState>, TResult> task) { return(ExecuteInDbContextScopeAsync(provider, scopeOption, state, cancellationToken: default, ExecuteSynchronously, async: false, GetUnitOfWorkFromDbContextScope)
/// <summary> /// <para> /// Performs the given <paramref name="task"/>, with access to a new ambient <typeparamref name="TDbContext"/> accessible through <see cref="IDbContextAccessor{TDbContext}"/>. /// </para> /// <para> /// This is the preferred way to perform work in the scope of a <see cref="DbContext"/>. It takes care of many concerns automatically. /// </para> /// <para> /// The task is performed through the <see cref="DbContext"/>'s <see cref="IExecutionStrategy"/>. /// The <see cref="IExecutionStrategy"/> may provide behavior such as retry attempts on transient exceptions. /// Each attempt is provided with a fresh <see cref="DbContext"/>, with no state leakage. /// </para> /// <para> /// If a query is executed that might perform a write operation, a transaction is started automatically. /// (This comes at no additional cost, since otherwise Entity Framework starts its own transaction when saving.) /// The transaction is committed once the scope ends, provided that it has not aborted. /// </para> /// <para> /// Scopes can be nested. When a scope joins an outer scope, its work is simply performed as part of the outer scope's work, with the outer scope taking care of all the above. /// </para> /// <para> /// A scope aborts when an exception bubbles up from its task or when <see cref="IExecutionScope.Abort"/> is called. At the end of an aborted scope, any ongoing transaction is rolled back. /// Further attempts to use that <see cref="DbContext"/>, even by joined parent scopes, result in a <see cref="TransactionAbortedException"/>. /// </para> /// </summary> public static Task <TResult> ExecuteInDbContextScopeAsync <TDbContext, TResult>(this IDbContextProvider <TDbContext> provider, AmbientScopeOption scopeOption, Func <IExecutionScope, Task <TResult> > task) { return(provider.ExecuteInDbContextScopeAsync(scopeOption, state: task, default, (scope, _) => scope.State(scope)));
/// <summary> /// Private constructor. /// Does not activate this instance. /// </summary> private PublicIdentityScope(IPublicIdentityConverter converter, AmbientScopeOption ambientScopeOption) : base(ambientScopeOption) { this.Converter = converter ?? throw new ArgumentNullException(nameof(converter)); }
/// <summary> /// Private constructor. /// Does not activate. /// </summary> private TestDetector(bool isTestRun, AmbientScopeOption ambientScopeOption) : base(ambientScopeOption) { this._isTestRun = isTestRun; }
public override Task <TResult> ExecuteInDbContextScopeAsync <TState, TResult>(AmbientScopeOption scopeOption, TState state, CancellationToken cancellationToken, Func <IExecutionScope <TState>, CancellationToken, Task <TResult> > task) { return(this.WrappedProvider.ExecuteInDbContextScopeAsync(scopeOption, state, cancellationToken, async(scope, ct) => { var shouldThrow = this.ShouldThrow(); var result = await task(scope, ct).ConfigureAwait(false); ThrowConcurrencyException(shouldThrow); return result; })); }
/// <summary> /// <para> /// Performs the given <paramref name="task"/>, with access to a new ambient <typeparamref name="TDbContext"/> accessible through <see cref="IDbContextAccessor{TDbContext}"/>. /// </para> /// <para> /// This is the preferred way to perform work in the scope of a <see cref="DbContext"/>. It takes care of many concerns automatically. /// </para> /// <para> /// The task is performed through the <see cref="DbContext"/>'s <see cref="IExecutionStrategy"/>. /// The <see cref="IExecutionStrategy"/> may provide behavior such as retry attempts on transient exceptions. /// Each attempt is provided with a fresh <see cref="DbContext"/>, with no state leakage. /// </para> /// <para> /// If a query is executed that might perform a write operation, a transaction is started automatically. /// (This comes at no additional cost, since otherwise Entity Framework starts its own transaction when saving.) /// The transaction is committed once the scope ends, provided that it has not aborted. /// </para> /// <para> /// Scopes can be nested. When a scope joins an outer scope, its work is simply performed as part of the outer scope's work, with the outer scope taking care of all the above. /// </para> /// <para> /// A scope aborts when an exception bubbles up from its task or when <see cref="IExecutionScope.Abort"/> is called. At the end of an aborted scope, any ongoing transaction is rolled back. /// Further attempts to use that <see cref="DbContext"/>, even by joined parent scopes, result in a <see cref="TransactionAbortedException"/>. /// </para> /// </summary> public static void ExecuteInDbContextScope <TDbContext>(this IDbContextProvider <TDbContext> provider, AmbientScopeOption scopeOption, Action <IExecutionScope> task) { provider.ExecuteInDbContextScope(scopeOption, state: task, scope => scope.State(scope)); }
/// <summary> /// <para> /// Performs the given <paramref name="task"/>, with access to a new ambient <typeparamref name="TDbContext"/> accessible through <see cref="IDbContextAccessor{TDbContext}"/>. /// </para> /// <para> /// This is the preferred way to perform work in the scope of a <see cref="DbContext"/>. It takes care of many concerns automatically. /// </para> /// <para> /// The task is performed through the <see cref="DbContext"/>'s <see cref="IExecutionStrategy"/>. /// The <see cref="IExecutionStrategy"/> may provide behavior such as retry attempts on transient exceptions. /// Each attempt is provided with a fresh <see cref="DbContext"/>, with no state leakage. /// </para> /// <para> /// If a query is executed that might perform a write operation, a transaction is started automatically. /// (This comes at no additional cost, since otherwise Entity Framework starts its own transaction when saving.) /// The transaction is committed once the scope ends, provided that it has not aborted. /// </para> /// <para> /// Scopes can be nested. When a scope joins an outer scope, its work is simply performed as part of the outer scope's work, with the outer scope taking care of all the above. /// </para> /// <para> /// A scope aborts when an exception bubbles up from its task or when <see cref="IExecutionScope.Abort"/> is called. At the end of an aborted scope, any ongoing transaction is rolled back. /// Further attempts to use that <see cref="DbContext"/>, even by joined parent scopes, result in a <see cref="TransactionAbortedException"/>. /// </para> /// </summary> public static TResult ExecuteInDbContextScope <TDbContext, TResult>(this IDbContextProvider <TDbContext> provider, AmbientScopeOption scopeOption, Func <IExecutionScope, TResult> task) { return(provider.ExecuteInDbContextScope(scopeOption, state: task, scope => scope.State(scope))); }
public virtual Task <TResult> ExecuteInDbContextScopeAsync <TState, TResult>( AmbientScopeOption scopeOption, TState state, CancellationToken cancellationToken, Func <IExecutionScope <TState>, CancellationToken, Task <TResult> > task) { return(TransactionalStrategyExecutor.ExecuteInDbContextScopeAsync(this, scopeOption, state, cancellationToken, task)); }
protected AsyncAmbientScope(AmbientScopeOption scopeOption) : base(scopeOption) { }
/// <summary> /// <para> /// Performs the given <paramref name="task"/>, with access to a new ambient <typeparamref name="TDbContext"/> accessible through <see cref="IDbContextAccessor{TDbContext}"/>. /// </para> /// <para> /// This is the preferred way to perform work in the scope of a <see cref="DbContext"/>. It takes care of many concerns automatically. /// </para> /// <para> /// The task is performed through the <see cref="DbContext"/>'s <see cref="IExecutionStrategy"/>. /// The <see cref="IExecutionStrategy"/> may provide behavior such as retry attempts on transient exceptions. /// Each attempt is provided with a fresh <see cref="DbContext"/>, with no state leakage. /// </para> /// <para> /// If a query is executed that might perform a write operation, a transaction is started automatically. /// (This comes at no additional cost, since otherwise Entity Framework starts its own transaction when saving.) /// The transaction is committed once the scope ends, provided that it has not aborted. /// </para> /// <para> /// Scopes can be nested. When a scope joins an outer scope, its work is simply performed as part of the outer scope's work, with the outer scope taking care of all the above. /// </para> /// <para> /// A scope aborts when an exception bubbles up from its task or when <see cref="IExecutionScope.Abort"/> is called. At the end of an aborted scope, any ongoing transaction is rolled back. /// Further attempts to use that <see cref="DbContext"/>, even by joined parent scopes, result in a <see cref="TransactionAbortedException"/>. /// </para> /// </summary> public static Task ExecuteInDbContextScopeAsync <TDbContext>(this IDbContextProvider <TDbContext> provider, AmbientScopeOption scopeOption, CancellationToken cancellationToken, Func <IExecutionScope, CancellationToken, Task> task) { return(provider.ExecuteInDbContextScopeAsync(scopeOption, state: task, cancellationToken, (scope, ct) => scope.State(scope, ct))); }
private DistributedIdGeneratorScope(IDistributedIdGenerator idGenerator, AmbientScopeOption scopeOption) : base(scopeOption) { this.IdGenerator = idGenerator ?? throw new ArgumentNullException(nameof(idGenerator)); }
/// <summary> /// Private constructor. /// Does not activate this instance. /// </summary> private ClockScope(Func <DateTime> nowSource, AmbientScopeOption ambientScopeOption) : base(ambientScopeOption) { this.NowSource = nowSource ?? throw new ArgumentNullException(nameof(nowSource)); }
/// <summary> /// Executes the requested overload of <see cref="IDbContextProvider{TDbContext}.ExecuteInDbContextScope{TState, TResult}"/> or its async variant. /// </summary> private protected async Task <TResult> Execute <TResult>(Overload overload, IDbContextProvider <TestDbContext> provider, Func <IExecutionScope, CancellationToken, Task <TResult> > task, AmbientScopeOption scopeOption = AmbientScopeOption.JoinExisting, CancellationToken cancellationToken = default) { switch (overload) { case Overload.Async: await provider.ExecuteInDbContextScopeAsync(WithoutResultWithoutCancellation(task)); return(default); case Overload.AsyncResult: return(await provider.ExecuteInDbContextScopeAsync(WithoutCancellation(task))); case Overload.Sync: provider.ExecuteInDbContextScope(SyncWithoutResult(task)); return(default); case Overload.SyncResult: return(provider.ExecuteInDbContextScope(Sync(task))); case Overload.AsyncWithScopeOption: await provider.ExecuteInDbContextScopeAsync(scopeOption, WithoutResultWithoutCancellation(task)); return(default); case Overload.AsyncResultWithScopeOption: return(await provider.ExecuteInDbContextScopeAsync(scopeOption, WithoutCancellation(task))); case Overload.SyncWithScopeOption: provider.ExecuteInDbContextScope(scopeOption, SyncWithoutResult(task)); return(default); case Overload.SyncResultWithScopeOption: return(provider.ExecuteInDbContextScope(scopeOption, Sync(task))); case Overload.AsyncWithCancellation: await provider.ExecuteInDbContextScopeAsync(cancellationToken, WithoutResult(task)); return(default); case Overload.AsyncResultWithCancellation: return(await provider.ExecuteInDbContextScopeAsync(cancellationToken, task)); case Overload.AsyncWithScopeOptionWithCancellation: await provider.ExecuteInDbContextScopeAsync(scopeOption, cancellationToken, WithoutResult(task)); return(default); case Overload.AsyncResultWithScopeOptionWithCancellation: return(await provider.ExecuteInDbContextScopeAsync(scopeOption, cancellationToken, task)); case Overload.AsyncWithState: await provider.ExecuteInDbContextScopeAsync(true, cancellationToken, WithoutResult(task)); return(default); case Overload.AsyncResultWithState: return(await provider.ExecuteInDbContextScopeAsync(true, cancellationToken, task)); case Overload.SyncWithState: provider.ExecuteInDbContextScope(true, SyncWithoutResult(task)); return(default); case Overload.SyncResultWithState: return(provider.ExecuteInDbContextScope(true, Sync(task))); case Overload.AsyncWithScopeOptionWithState: await provider.ExecuteInDbContextScopeAsync(scopeOption, true, cancellationToken, WithoutResult(task)); return(default); case Overload.AsyncResultWithScopeOptionWithState: return(await provider.ExecuteInDbContextScopeAsync(scopeOption, true, cancellationToken, task)); case Overload.SyncWithScopeOptionWithState: provider.ExecuteInDbContextScope(scopeOption, true, SyncWithoutResult(task)); return(default); case Overload.SyncResultWithScopeOptionWithState: return(provider.ExecuteInDbContextScope(scopeOption, true, Sync(task))); default: throw new NotImplementedException(); } }
public static Options <TDbContext> DefaultScopeOption <TDbContext>(this Options <TDbContext> options, AmbientScopeOption defaultScopeOption) where TDbContext : DbContext { if (!Enum.IsDefined(typeof(AmbientScopeOption), defaultScopeOption)) { throw new ArgumentException($"Undefined {nameof(AmbientScopeOption)}: {defaultScopeOption}."); } options.OptionsBuilder.DefaultScopeOption = defaultScopeOption; return(options); }
public StaticTestScope(AmbientScopeOption option) : base(option) { this.Index = -1; }