コード例 #1
0
        public void Join(CircleJoinCommand command)
        {
            using (var transaction = new TransactionScope())
            {
                var memberId = new UserId(command.UserId);
                var member   = userRepository.Find(memberId);
                if (member == null)
                {
                    throw new UserNotFoundException(memberId, "사용자를 찾지 못했음");
                }

                var id     = new CircleId(command.CircleId);
                var circle = circleRepository.Find(id);
                if (circle == null)
                {
                    throw new CircleNotFoundException(id, "서클을 찾지 못했음");
                }

                // 서클에 소속된 사용자가 서클장을 포함 30명 이하인지 확인
                if (circle.Members.Count >= 29)
                {
                    throw new CircleFullException(id);
                }

                // 가입 처리
                circle.Members.Add(member);
                circleRepository.Save(circle);
                transaction.Complete();
            }
        }
コード例 #2
0
        public void Join(CircleJoinCommand command)
        {
            using (var transaction = new TransactionScope())
            {
                var memberId = new UserId(command.UserId);
                var member   = userRepository.Find(memberId);
                if (member == null)
                {
                    throw new UserNotFoundException(memberId, "사용자를 찾지 못했음");
                }

                var id     = new CircleId(command.CircleId);
                var circle = circleRepository.Find(id);
                if (circle == null)
                {
                    throw new CircleNotFoundException(id, "서클을 찾지 못했음");
                }

                if (circle.IsFull())
                {
                    throw new CircleFullException(id);
                }

                circle.Join(member);
                circleRepository.Save(circle);
                transaction.Complete();
            }
        }
コード例 #3
0
        public void Join(CircleJoinCommand command)
        {
            using (var transaction = new TransactionScope())
            {
                var memberId = new UserId(command.UserId);
                var member   = userRepository.Find(memberId);
                if (member == null)
                {
                    throw new UserNotFoundException(memberId, "ユーザが見つかりませんでした。");
                }

                var id     = new CircleId(command.CircleId);
                var circle = circleRepository.Find(id);
                if (circle == null)
                {
                    throw new CircleNotFoundException(id, "サークルが見つかりませんでした。");
                }

                // サークルのオーナーを含めて30名か確認
                if (circle.Members.Count >= 29)
                {
                    throw new CircleFullException(id);
                }

                // メンバーを追加する
                circle.Members.Add(member);
                circleRepository.Save(circle);
                transaction.Complete();
            }
        }
コード例 #4
0
        public CircleGetResult Get(CircleGetCommand command)
        {
            var id     = new CircleId(command.Id);
            var circle = circleRepository.Find(id);

            var data = new CircleData(circle);

            return(new CircleGetResult(data));
        }
コード例 #5
0
        public void Join(CircleJoinCommand command)
        {
            var memberId = new UserId(command.UserId);
            var member   = userRepository.Find(memberId);

            if (member == null)
            {
                throw new Exception("ユーザーが見つかりませんでした。");
            }

            var id     = new CircleId(command.CircleId);
            var circle = circleRepository.Find(id);

            if (circle == null)
            {
                throw new Exception("サークルが見つかりませんでした。");
            }

            // FIXME ここの人数制限があとあと面倒になる、例えば Invite という関数をこのクラスに増やしたときには、このコードをコピペすることになり管理が面倒になってしまう。
            if (circle.Members.Count >= 29)
            {
                throw new Exception(id.ToString());
            }

            circle.Members.Add(member);
            circleRepository.Save(circle);
        }
コード例 #6
0
        public CircleUpdateOutputData Handle(CircleUpdateInputData inputData)
        {
            using var transaction = new TransactionScope();

            var id     = new CircleId(inputData.Id);
            var circle = circleRepository.Find(id);

            if (circle == null)
            {
                throw new CircleNotFoundException(id);
            }

            if (inputData.Name != null)
            {
                var name = new CircleName(inputData.Name);
                circle.ChangeName(name);

                if (circleService.Exists(circle))
                {
                    throw new CanNotRegisterCircleException(circle, "이미 등록된 서클임");
                }
            }

            circleRepository.Save(circle);

            transaction.Complete();

            return(new CircleUpdateOutputData());
        }
コード例 #7
0
        public CircleJoinOutputData Handle(CircleJoinInputData inputData)
        {
            using var transaction = new TransactionScope();

            var memberId = new UserId(inputData.MemberId);
            var member   = userRepository.Find(memberId);

            if (member == null)
            {
                throw new UserNotFoundException(memberId, "ユーザが見つかりませんでした。");
            }

            var id     = new CircleId(inputData.CircleId);
            var circle = circleRepository.Find(id);

            if (circle == null)
            {
                throw new CircleNotFoundException(id, "サークルが見つかりませんでした。");
            }

            var fullSpec = new CircleFullSpecification(userRepository);

            if (fullSpec.IsSatisfiedBy(circle))
            {
                throw new CircleFullException(id, "サークルに所属しているメンバーが上限に達しています。");
            }

            circle.Join(member, fullSpec);
            circleRepository.Save(circle);

            transaction.Complete();

            return(new CircleJoinOutputData());
        }
コード例 #8
0
        public void Join(CircleJoinCommand command)
        {
            var circleId = new CircleId(command.CircleId);
            var circle   = circleRepository.Find(circleId);

            var users = userRepository.Find(circle.Members);
            // 서클에 소속된 프리미엄 사용자의 수에 따라 최대 인원이 결정됨
            var premiumUserNumber = users.Count(user => user.IsPremium);
            var circleUpperLimit  = premiumUserNumber < 10 ? 30 : 50;

            if (circle.CountMembers() >= circleUpperLimit)
            {
                throw new CircleFullException(circleId);
            }

            var memberId = new UserId(command.UserId);
            var member   = userRepository.Find(memberId);

            if (member == null)
            {
                throw new UserNotFoundException(memberId, "사용자를 찾지 못했음");
            }

            circle.Join(member);
            circleRepository.Save(circle);
        }
コード例 #9
0
        public void Join(CircleJoinCommand command)
        {
            var circleId = new CircleId(command.CircleId);
            var circle   = circleRepository.Find(circleId);

            var owner          = userRepository.Find(circle.Owner);
            var members        = userRepository.Find(circle.Members);
            var circleMembers  = new CircleMembers(circle.Id, owner, members);
            var circleFullSpec = new CircleMembersFullSpecification();

            if (circleFullSpec.IsSatisfiedBy(circleMembers))
            {
                throw new CircleFullException(circleId);
            }

            var memberId = new UserId(command.UserId);
            var member   = userRepository.Find(memberId);

            if (member == null)
            {
                throw new UserNotFoundException(memberId, "사용자를 찾지 못했음");
            }

            circle.Join(member);
            circleRepository.Save(circle);
        }
コード例 #10
0
        public void Join(CircleJoinCommand command)
        {
            var circleId = new CircleId(command.CircleId);
            var circle   = circleRepository.Find(circleId);

            var users = userRepository.Find(circle.Members);
            // サークルに所属しているプレミアムユーザの人数により上限が変わる
            var premiumUserNumber = users.Count(user => user.IsPremium);
            var circleUpperLimit  = premiumUserNumber < 10 ? 30 : 50;

            if (circle.CountMembers() >= circleUpperLimit)
            {
                throw new CircleFullException(circleId);
            }

            var memberId = new UserId(command.UserId);
            var member   = userRepository.Find(memberId);

            if (member == null)
            {
                throw new UserNotFoundException(memberId, "ユーザが見つかりませんでした。");
            }

            circle.Join(member);
            circleRepository.Save(circle);
        }
コード例 #11
0
        public Task <Unit> Handle(CircleJoinMemberCommand command, CancellationToken cancellationToken)
        {
            using var transaction = new TransactionScope();

            var circle = _circleRepository.Find(new CircleId(command.CircleId));

            if (circle is null)
            {
                throw new CircleNotFoundException("サークルが見つかりませんでした。");
            }

            var user = _userRepository.Find(new UserId(command.UserId));

            if (user is null)
            {
                throw new UserNotFoundException("追加対象のユーザーが見つかりませんでした。");
            }

            circle.Join(user);

            _circleRepository.Save(circle);

            transaction.Complete();

            return(Task.FromResult(Unit.Value));
        }
コード例 #12
0
        public CircleJoinOutputData Handle(CircleJoinInputData inputData)
        {
            using var transaction = new TransactionScope();

            var memberId = new UserId(inputData.MemberId);
            var member   = userRepository.Find(memberId);

            if (member == null)
            {
                throw new UserNotFoundException(memberId, "서클에 가입할 사용자를 찾지 못했음");
            }

            var id     = new CircleId(inputData.CircleId);
            var circle = circleRepository.Find(id);

            if (circle == null)
            {
                throw new CircleNotFoundException(id, "가입할 서클을 찾지 못했음");
            }

            var fullSpec = new CircleFullSpecification(userRepository);

            if (fullSpec.IsSatisfiedBy(circle))
            {
                throw new CircleFullException(id, "서클에 소속 가능한 최대 인원을 초과함");
            }

            circle.Join(member, fullSpec);
            circleRepository.Save(circle);

            transaction.Complete();

            return(new CircleJoinOutputData());
        }
コード例 #13
0
        public CircleGetRecommendResult GetRecommend(CircleGetRecommendRequest request)
        {
            var circleRecommendSpecification = new CircleRecommendSpecification(now);
            // リポジトリに仕様を引き渡して抽出(フィルタリング)
            var recommendCircles = circleRepository.Find(circleRecommendSpecification)
                                   .Take(10)
                                   .ToList();

            return(new CircleGetRecommendResult(recommendCircles));
        }
コード例 #14
0
        public CircleGetRecommendResult GetRecommend(CircleGetRecommendRequest request)
        {
            var circleRecommendSpecification = new CircleRecommendSpecification(now);
            // 리포지토리에 명세를 전달해 추천 서클을 추려냄(필터링)
            var recommendCircles = circleRepository.Find(circleRecommendSpecification)
                                   .Take(10)
                                   .ToList();

            return(new CircleGetRecommendResult(recommendCircles));
        }
コード例 #15
0
        public Task <CircleGetOutputData> Handle(CircleGetCommand command, CancellationToken cancellationToken)
        {
            var data = _circleRepository.Find(new CircleId(command.Id));

            if (data is null)
            {
                throw new CircleNotFoundException($"IDが { command.Id } のサークルが見つかりませんでした");
            }

            var circle = new CircleData(data.Id.Value, data.Name.Value, data.Owner.Value, data.Members.Select(x => x.Value).ToList());

            return(Task.FromResult(new CircleGetOutputData(circle)));
        }
コード例 #16
0
        public CircleGetOutputData Handle(CircleGetInputData inputData)
        {
            var id     = new CircleId(inputData.Id);
            var circle = circleRepository.Find(id);

            var data = new CircleData(
                circle.Id.Value,
                circle.Name.Value,
                circle.Owner?.Value,
                circle.Members.Select(x => x.Value).ToList()
                );

            return(new CircleGetOutputData(data));
        }
コード例 #17
0
        public CircleGetCandidatesOutputData Handle(CircleGetCandidatesInputData inputData)
        {
            var circleId = new CircleId(inputData.CircleId);
            var circle   = circleRepository.Find(circleId);

            var members    = circle.Members.Concat(new[] { circle.Owner }).ToHashSet();
            var candidates = userRepository.FindAll()
                             .Where(x => !members.Contains(x.Id))
                             .Skip((inputData.Page - 1) * inputData.Size)
                             .Take(inputData.Size);

            var candidatesData = candidates.Select(toUserData).ToList();

            return(new CircleGetCandidatesOutputData(candidatesData));
        }
コード例 #18
0
        public CircleGetCandidatesResult GetCandidates(CircleGetCandidatesCommand command)
        {
            var circleId = new CircleId(command.CircleId);
            var circle   = circleRepository.Find(circleId);

            var members    = circle.Members.Concat(new[] { circle.Owner }).ToHashSet();
            var candidates = userRepository.FindAll()
                             .Where(x => !members.Contains(x.Id))
                             .Skip((command.Page - 1) * command.Size)
                             .Take(command.Size);

            var candidatesData = candidates.Select(x => new UserData(x)).ToList();

            return(new CircleGetCandidatesResult(candidatesData));
        }
コード例 #19
0
        public Task <Unit> Handle(CircleDeleteCommand request, CancellationToken cancellationToken)
        {
            using var transaction = new TransactionScope();

            var circle = _circleRepository.Find(new CircleId(request.UserId));

            if (circle != null)
            {
                _circleRepository.Delete(circle);
            }

            transaction.Complete();

            return(Task.FromResult(Unit.Value));
        }
コード例 #20
0
        public void Join(CircleJoinCommand command)
        {
            using var transaction = new TransactionScope();

            var circleId = new CircleId(command.CircleId);
            var circle   = _circleRepository.Find(circleId);

            if (circle == null)
            {
                throw new CircleNotFoundException(circleId, "サークルが見つかりませんでした。");
            }

            // 複雑な仕様:対処方法その1
            // var circleFullSpecification = new CircleFullSpecification(_userRepository);
            // if (circleFullSpecification.IsSatisfiedBy(circle))
            // {
            //     throw new CircleFullException(circle.Id);
            // }

            // 複雑な仕様:対処方法その2
            // ファーストコレクションクラスを利用する場合
            // ドメインオブジェクトで userRepository を使わずに済む(入出力をドメインオブジェクトから排除できた)
            var owner         = _userRepository.Find(circle.Owner);
            var members       = _userRepository.Find(circle.Members);
            var circleMembers = new CircleMembers(circle.Id, owner, members);
            var circleMembersFullSpecification = new CircleMembersFullSpecification();

            if (circleMembersFullSpecification.IsSatisfiedBy(circleMembers))
            {
                throw new CircleFullException(circleId);
            }

            var memberId = new UserId(command.UserId);
            var member   = _userRepository.Find(memberId);

            if (member == null)
            {
                throw new UserNotFoundException(memberId, "ユーザーが見つかりませんでした。");
            }

            circle.Join(member);
            _circleRepository.Save(circle);

            transaction.Complete();
        }
コード例 #21
0
        public CircleDeleteOutputData Handle(CircleDeleteInputData inputData)
        {
            using var transaction = new TransactionScope();

            var id     = new CircleId(inputData.Id);
            var circle = circleRepository.Find(id);

            if (circle == null)
            {
                return(new CircleDeleteOutputData());
            }

            circleRepository.Delete(circle);

            transaction.Complete();

            return(new CircleDeleteOutputData());
        }
コード例 #22
0
        public Task <Unit> Handle(CircleUpdateCommand command, CancellationToken cancellationToken)
        {
            using var transaction = new TransactionScope();

            var circle = _circleRepository.Find(new CircleId(command.Id));

            if (command.Name != null)
            {
                circle.ChangeName(new CircleName(command.Name));
                if (_circleService.Exists(circle))
                {
                    throw new CanNotCircleRegisterException($"{ command.Name } は既に存在します。");
                }
            }

            _circleRepository.Save(circle);

            transaction.Complete();

            return(Task.FromResult(Unit.Value));
        }
コード例 #23
0
        public void JoinUser(string circleId, string userId)
        {
            using (var transaction = new TransactionScope()) {
                var targetCircleId = new CircleId(circleId);
                var targetCircle   = circleRepository.Find(targetCircleId);
                if (targetCircle == null)
                {
                    throw new Exception("circle not found. circleId: " + circleId);
                }

                var joinUserId = new UserId(userId);
                var joinUser   = userRepository.Find(joinUserId);
                if (joinUser == null)
                {
                    throw new Exception("user not found. userId: " + userId);
                }

                targetCircle.Join(joinUser); // targetCircle.Users.Add(joinUser); とは書けなくなりました
                circleRepository.Save(targetCircle);
                transaction.Complete();
            }
        }
コード例 #24
0
        public void Join(CircleJoinCommand command)
        {
            var circleId = new CircleId(command.CircleId);
            var circle   = circleRepository.Find(circleId);

            var circleFullSpecification = new CircleFullSpecification(userRepository);

            if (circleFullSpecification.IsSatisfiedBy(circle))
            {
                throw new CircleFullException(circleId);
            }

            var memberId = new UserId(command.UserId);
            var member   = userRepository.Find(memberId);

            if (member == null)
            {
                throw new UserNotFoundException(memberId, "ユーザが見つかりませんでした。");
            }

            circle.Join(member);
            circleRepository.Save(circle);
        }
コード例 #25
0
        public bool Exists(Circle circle)
        {
            var duplicated = circleRepository.Find(circle.Name);

            return(duplicated != null);
        }
コード例 #26
0
        public CircleGetCandidatesResult GetCandidates(CircleGetCandidatesCommand command)
        {
            var circleId = new CircleId(command.CircleId);
            var circle   = circleRepository.Find(circleId);

            if (circle == null)
            {
                throw new CircleNotFoundException(circleId);
            }

            using (var sqlCommand = provider.Connection.CreateCommand())
            {
                var parameterNames = circle.Members.Select((_, i) => "@member" + i).ToList();

                var selectQuery = new StringBuilder(@" SELECT * FROM users");

                var appendWhere = false;
                if (circle.ExistsOwner())
                {
                    selectQuery.Append(" WHERE id <> @ownerId");
                    appendWhere = true;
                }

                if (parameterNames.Any())
                {
                    var inParameters = string.Join(",", parameterNames);
                    var inPhrase     = new StringBuilder();
                    if (appendWhere)
                    {
                        inPhrase.Append(" AND");
                    }
                    inPhrase.Append($" id NOT IN ({inParameters})");

                    if (!appendWhere)
                    {
                        selectQuery.Append(" WHERE");
                        appendWhere = true;
                    }

                    selectQuery.Append(inPhrase);
                }
                selectQuery.Append(@"
 ORDER BY id
   OFFSET @skip ROWS
   FETCH NEXT @size ROWS ONLY
");

                sqlCommand.CommandText = selectQuery.ToString();

                if (circle.ExistsOwner())
                {
                    sqlCommand.Parameters.Add(new SqlParameter("@ownerId", circle.Owner.Value));
                }

                foreach (var tpl in circle.Members.Zip(parameterNames, (memberId, parameter) => new { memberId, parameter }))
                {
                    sqlCommand.Parameters.Add(new SqlParameter(tpl.parameter, tpl.memberId.Value));
                }

                var page = command.Page;
                var size = command.Size;
                sqlCommand.Parameters.Add(new SqlParameter("@skip", (page - 1) * size));
                sqlCommand.Parameters.Add(new SqlParameter("@size", size));

                using (var reader = sqlCommand.ExecuteReader())
                {
                    var members = new List <UserData>();
                    while (reader.Read())
                    {
                        var id   = (string)reader["id"];
                        var name = (string)reader["name"];
                        var data = new UserData(id, name);

                        members.Add(data);
                    }

                    return(new CircleGetCandidatesResult(members));
                }
            }
        }
コード例 #27
0
        public bool Exists(Circle circle)
        {
            var target = circleRepository.Find(circle.Name);

            return(target != null);
        }