Beispiel #1
0
        public void CreateUser(UserCreationSpec userToCreate)
        {
            if (userToCreate == null)
            {
                throw new ArgumentNullException(nameof(userToCreate));
            }

            userToCreate.Validate();

            /*
             * Typical usage of SessionScope for a read-write business transaction.
             * It's as simple as it looks.
             */
            using (var sessionScope = _sessionScopeFactory.Create())
            {
                //-- Build domain model
                var user = new User()
                {
                    Id               = userToCreate.Id,
                    Name             = userToCreate.Name,
                    Email            = userToCreate.Email,
                    WelcomeEmailSent = false,
                    CreatedOn        = DateTime.UtcNow
                };

                //-- Persist
                _userRepository.Add(user);
                sessionScope.SaveChanges();
            }
        }
        public void UpdateCreditScoreForAllUsers()
        {
            /*
             * Demo of SessionScope + parallel programming.
             */

            using (var sessionScope = _sessionScopeFactory.Create())
            {
                //-- Get all users
                var session = sessionScope.Session;
                var userIds = session.CreateCriteria <User>().List <User>().Select(u => u.Id).ToList();

                Console.WriteLine("Found {0} users in the database. Will calculate and store their credit scores in parallel.", userIds.Count);

                //-- Calculate and store the credit score of each user
                // We're going to imagine that calculating a credit score of a user takes some time.
                // So we'll do it in parallel.

                // You MUST call SuppressAmbientScope() when kicking off a parallel execution flow
                // within a SessionScope. Otherwise, this SessionScope will remain the ambient scope
                // in the parallel flows of execution, potentially leading to multiple threads
                // accessing the same ISession instance.
                using (_sessionScopeFactory.SuppressAmbientScope())
                {
                    Parallel.ForEach(userIds, UpdateCreditScore);
                }

                // Note: SaveChanges() isn't going to do anything in this instance since all the changes
                // were actually made and saved in separate DbScopes created in separate threads.
                sessionScope.SaveChanges();
            }
        }
Beispiel #3
0
        public void Intercept(IInvocation invocation)
        {
            var sessionScopeAttribute = invocation.MethodInvocationTarget
                                        .GetCustomAttributes(typeof(SessionScopeAttribute), true)
                                        .FirstOrDefault() as SessionScopeAttribute;

            if (sessionScopeAttribute != null)
            {
                var returnType = invocation.MethodInvocationTarget.ReturnType;
                if (returnType == typeof(Task) ||
                    returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task <>))
                {
                    var ctArgument = invocation.Arguments.FirstOrDefault(a => a is CancellationToken);

                    var cancellationToken = (CancellationToken?)ctArgument ?? CancellationToken.None;
                    var scope             = _scopeFactory
                                            .Create(sessionScopeAttribute.ReadOnly, sessionScopeAttribute.Option,
                                                    sessionScopeAttribute.IsolationLevel);

                    invocation.Proceed();
                    invocation.ReturnValue = InterceptAsync((dynamic)invocation.ReturnValue, scope, cancellationToken);
                }
                else
                {
                    using (var scope = _scopeFactory
                                       .Create(sessionScopeAttribute.ReadOnly, sessionScopeAttribute.Option,
                                               sessionScopeAttribute.IsolationLevel))
                    {
                        invocation.Proceed();
                        scope.SaveChanges();
                    }
                }
            }
            else
            {
                invocation.Proceed();
            }
        }