Esempio n. 1
0
        private IUnitOfWork GetRequiredUnitOfWork(PersistenceOptions persistenceOptions)
        {
            if (!AmbientContextManager.AmbientExists)
            {
                return(GetRequiredNewUnitOfWork(persistenceOptions));
            }

            if (!AmbientContextManager.Ambient.IsTypeOf <CompositeUnitOfWork>())
            {
                throw NContextPersistenceError.CompositeUnitOfWorkWithinDifferentAmbientType(AmbientContextManager.Ambient.UnitOfWork.GetType())
                      .ToException <InvalidOperationException>();
            }

            // TODO: (DG) If ambient is a Composite do we retain or add to it?
            //if ()
            //{
            //    var currentCompositeUnitOfWork = (CompositeUnitOfWork)AmbientContextManager.Ambient.UnitOfWork;
            //    unitOfWork = new CompositeUnitOfWork(AmbientContextManager, currentCompositeUnitOfWork, _PersistenceOptions);
            //    currentCompositeUnitOfWork.AddUnitOfWork(unitOfWork);
            //    AmbientContextManager.AddUnitOfWork(unitOfWork);
            //}

            AmbientContextManager.RetainAmbient();

            return(AmbientContextManager.Ambient.UnitOfWork);
        }
Esempio n. 2
0
        private IUnitOfWork GetRequiredNewUnitOfWork(PersistenceOptions persistenceOptions)
        {
            UnitOfWorkBase unitOfWork = new CompositeUnitOfWork(AmbientContextManager, persistenceOptions);

            AmbientContextManager.AddUnitOfWork(unitOfWork);

            return(unitOfWork);
        }
Esempio n. 3
0
        private IUnitOfWork GetRequiredNewUnitOfWork(TransactionOptions transactionOptions)
        {
            var unitOfWork = new EfUnitOfWork(AmbientContextManager, new DbContextContainer());

            AmbientContextManager.AddUnitOfWork(unitOfWork);

            return(unitOfWork);
        }
Esempio n. 4
0
        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="disposeManagedResources"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
        protected virtual void Dispose(Boolean disposeManagedResources)
        {
            if (IsDisposed)
            {
                return;
            }

            if (disposeManagedResources && AmbientContextManager.CanDisposeUnitOfWork(this))
            {
                DisposeManagedResources();
                IsDisposed = true;
            }
        }
Esempio n. 5
0
        private IServiceResponse <Unit> CommitChildrenParallel()
        {
            if (!AmbientContextManager.IsThreadSafe)
            {
                return(NContextPersistenceError.ConcurrencyUnsupported(AmbientContextManager.GetType()).ToServiceResponse());
            }

            var commitExceptions = new ConcurrentQueue <Error>();

            Parallel.ForEach(
                UnitsOfWork,
                new ParallelOptions
            {
                MaxDegreeOfParallelism = _PersistenceOptions.MaxDegreeOfParallelism
            },
                (unitOfWork, state) =>
            {
                try
                {
                    if (state.IsExceptional || state.ShouldExitCurrentIteration)
                    {
                        return;
                    }

                    unitOfWork.Commit()
                    .Catch(error =>
                    {
                        state.Break();
                        commitExceptions.Enqueue(error);
                    });
                }
                catch (Exception exception)
                {
                    state.Break();
                    commitExceptions.Enqueue(exception.ToError());

                    // TODO: (DG) Logging ...
                }
            });

            return(commitExceptions.Any()
                       ? (IServiceResponse <Unit>) new ErrorResponse <Unit>(new AggregateError((Int32)HttpStatusCode.InternalServerError, GetType().Name, commitExceptions.Select(error => error)))
                       : (IServiceResponse <Unit>) new DataResponse <Unit>(default(Unit)));
        }
Esempio n. 6
0
        private IUnitOfWork GetRequiredUnitOfWork(TransactionOptions transactionOptions)
        {
            if (!AmbientContextManager.AmbientExists || !AmbientContextManager.AmbientUnitOfWorkIsValid)
            {
                return(GetRequiredNewUnitOfWork(transactionOptions));
            }

            /* First check if the ambient is a CompositeUnitOfWork and add to its collection.
             * This must come prior to checking whether it is not an instance of IEfUnitOfWork so we can
             * add it as a leaf to a composite.
             * */
            var ambient = AmbientContextManager.Ambient;

            if (ambient.IsTypeOf <CompositeUnitOfWork>())
            {
                UnitOfWorkBase unitOfWork;
                var            currentCompositeUnitOfWork = (CompositeUnitOfWork)AmbientContextManager.Ambient.UnitOfWork;
                if (currentCompositeUnitOfWork.ContainsType <IEfUnitOfWork>())
                {
                    unitOfWork = currentCompositeUnitOfWork.Single(uow => uow.GetType().Implements <IEfUnitOfWork>());
                }
                else
                {
                    unitOfWork = new EfUnitOfWork(AmbientContextManager, new DbContextContainer(), currentCompositeUnitOfWork);
                    currentCompositeUnitOfWork.Add(unitOfWork);
                }

                AmbientContextManager.AddUnitOfWork(unitOfWork);

                return(unitOfWork);
            }

            // Current ambient is not Entity Framework.
            if (!AmbientContextManager.Ambient.IsTypeOf <IEfUnitOfWork>())
            {
                return(GetRequiredNewUnitOfWork(transactionOptions));
            }

            // Current ambient implements IEfUnitOfWork so let's simply retain it by incrementing the ambient session count.
            AmbientContextManager.RetainAmbient();

            return(AmbientContextManager.Ambient.UnitOfWork);
        }
Esempio n. 7
0
        /// <summary>
        /// Commits the changes to the database.
        /// </summary>
        /// <returns>IServiceResponse{Boolean}.</returns>
        /// <exception cref="System.InvalidOperationException"></exception>
        public IServiceResponse <Unit> Commit()
        {
            if (Status == TransactionStatus.Active)
            {
                throw new InvalidOperationException(String.Format(LocalizedPersistenceError.UnitOfWorkCommitting, Id));
            }

            if (Status == TransactionStatus.Committed)
            {
                throw new InvalidOperationException(String.Format(LocalizedPersistenceError.UnitOfWorkCommitted, Id));
            }

            if (!AmbientContextManager.CanCommitUnitOfWork(this))
            {
                return(NContextPersistenceError.UnitOfWorkNonCommittable(Id).ToServiceResponse());
            }

            if (ScopeTransaction == null)
            {
                return(NContextPersistenceError.ScopeTransactionIsNull().ToServiceResponse());
            }

            TransactionScope transactionScope = null;

            if (Parent == null && ScopeThread == Thread.CurrentThread)
            {
                // Use the existing CurrentTransaction.
                _CurrentTransactionFactory = new Lazy <Transaction>(() => ScopeTransaction);
                transactionScope           = new TransactionScope(CurrentTransaction, TransactionOptions.Timeout);
            }
            else if (ScopeThread != Thread.CurrentThread)
            {
                // UnitOfWork is being committed on a different thread.
                _CurrentTransactionFactory = new Lazy <Transaction>(() => ScopeTransaction.DependentClone(DependentCloneOption.BlockCommitUntilComplete));
                transactionScope           = new TransactionScope(CurrentTransaction, TransactionOptions.Timeout);
            }

            _Status = TransactionStatus.Active;

            return(CommitTransaction(transactionScope)
                   .Catch(_ => { _Status = TransactionStatus.Aborted; })
                   .Bind(_ =>
            {
                _Status = TransactionStatus.Committed;
                if (CurrentTransaction is DependentTransaction)
                {
                    if (transactionScope != null)
                    {
                        transactionScope.Complete();
                        transactionScope.Dispose();
                    }

                    var dependentTransaction = CurrentTransaction as DependentTransaction;
                    dependentTransaction.Complete();
                    dependentTransaction.Dispose();
                }
                else if (CurrentTransaction is CommittableTransaction)
                {
                    try
                    {
                        (CurrentTransaction as CommittableTransaction).Commit();
                    }
                    catch (TransactionAbortedException abortedException)
                    {
                        return NContextPersistenceError.CommitFailed(Id, CurrentTransaction.TransactionInformation.LocalIdentifier, abortedException)
                        .ToServiceResponse();
                    }
                }

                return new DataResponse <Unit>(default(Unit));
            }));
        }