예제 #1
0
        public async Task <IActionResult> ClaimTeam([FromBody] int teamId)
        {
            if (_userManager.Users.Any(u => u.TeamId == teamId))
            {
                return(BadRequest("Team is already claimed"));
            }

            var user = await _userManager.GetAppUser(HttpContext.User);

            if (await _userManager.IsInRoleAsync(user, "TeamManager"))
            {
                _dispatcher.Dispatch(new TeamUnClaimedEvent(user.TeamId));
            }
            else
            {
                await _userManager.AddToRoleAsync(user, "TeamManager");

                _timerService.AddTeamManager(user.Id);
            }

            user.TeamId = teamId;
            await _userManager.UpdateAsync(user);

            _dispatcher.Dispatch(new TeamClaimedEvent(teamId));

            return(Ok());
        }
예제 #2
0
        private void SaveChangesWithEvents(IDomainEventDispatcher domainEventDispatcher)
        {
            System.Collections.Generic.IEnumerable <EntityEntry> modified = ChangeTracker.Entries().Where(e => e.State == EntityState.Modified || e.State == EntityState.Added);

            foreach (EntityEntry item in modified)
            {
                if (item.Entity is IDateTracking changedOrAddedItem)
                {
                    if (item.State == EntityState.Added)
                    {
                        changedOrAddedItem.DateCreated = DateTime.Now;
                    }
                    changedOrAddedItem.DateModified = DateTime.Now;
                }
            }
            var entities = ChangeTracker.Entries().Select(e => e.Entity);

            entities
            .Where(e =>
                   !e.GetType().BaseType.IsGenericType&&
                   typeof(AggregateRootBase).IsAssignableFrom(e.GetType()))
            .Select(aggregateRoot =>
            {
                var events = ((IAggregateRoot)aggregateRoot).GetUncommittedEvents();

                foreach (var domainEvent in events)
                {
                    domainEventDispatcher.Dispatch(domainEvent);
                }

                ((IAggregateRoot)aggregateRoot).GetUncommittedEvents().Clear();
                return(aggregateRoot);
            })
            .ToArray();

            entities
            .Where(e =>
                   e.GetType().BaseType.IsGenericType&&
                   typeof(AggregateRootWithIdBase <>).IsAssignableFrom(e.GetType().BaseType.GetGenericTypeDefinition()))
            .Select(aggregateRoot =>
            {
                //todo: need a better code to avoid dynamic
                var events = ((dynamic)aggregateRoot).GetUncommittedEvents();

                foreach (var domainEvent in events)
                {
                    domainEventDispatcher.Dispatch(domainEvent);
                }

                ((dynamic)aggregateRoot).GetUncommittedEvents().Clear();
                return(aggregateRoot);
            })
            .ToArray();
        }
예제 #3
0
        public override async Task <int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
        {
            if (_dispatcher is not null)
            {
                var membersWithAddressUpdatedEvents = ChangeTracker.Entries <Member>()
                                                      .Select(e => e.Entity)
                                                      .Where(e => e.Events.Any(x => x.GetType() == typeof(MemberAddressUpdatedEvent)))
                                                      .ToArray();

                foreach (var member in membersWithAddressUpdatedEvents)
                {
                    var addressUpdatedEvents = member.Events
                                               .Where(e => e.GetType() == typeof(MemberAddressUpdatedEvent))
                                               .ToArray();

                    member.Events
                    .Where(e => e.GetType() == typeof(MemberAddressUpdatedEvent))
                    .ToList()
                    .Clear();

                    foreach (var addressUpdatedEvent in addressUpdatedEvents)
                    {
                        await _dispatcher.Dispatch(addressUpdatedEvent).ConfigureAwait(false);
                    }
                }
            }

            int result = await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false);

            // ignore events if no dispatcher provided
            if (_dispatcher == null)
            {
                return(result);
            }

            // dispatch events only if save was successful
            var entitiesWithEvents = ChangeTracker.Entries <BaseEntity>()
                                     .Select(e => e.Entity)
                                     .Where(e => e.Events.Any())
                                     .ToArray();

            foreach (var entity in entitiesWithEvents)
            {
                var events = entity.Events.ToArray();
                entity.Events.Clear();
                foreach (var domainEvent in events)
                {
                    await _dispatcher.Dispatch(domainEvent).ConfigureAwait(false);
                }
            }

            return(result);
        }
예제 #4
0
 protected async Task DispatchEvents(T aggregateRoot)
 {
     foreach (var domainEvent in aggregateRoot.GetDomainEvents())
     {
         await _domainEventDispatcher.Dispatch(domainEvent);
     }
 }
예제 #5
0
        public override async Task <int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
        {
            int result = await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false);

            // ignore events if no dispatcher provided
            if (_dispatcher == null)
            {
                return(result);
            }

            // dispatch events only if save was successful
            var entitiesWithEvents = ChangeTracker.Entries <BaseEntity>()
                                     .Select(e => e.Entity)
                                     .Where(e => e.Events.Any())
                                     .ToArray();

            foreach (var entity in entitiesWithEvents)
            {
                var events = entity.Events.ToArray();
                entity.Events.Clear();
                foreach (var domainEvent in events)
                {
                    await _dispatcher.Dispatch(domainEvent).ConfigureAwait(false);
                }
            }

            return(result);
        }
예제 #6
0
        public override int SaveChanges()
        {
            UpdateAuditEntities();
            //return base.SaveChanges();

            var result = base.SaveChanges();

            // dispatch events only if save was successful
            var entitiesWithEvents = ChangeTracker.Entries <BaseEntity>()
                                     .Select(e => e.Entity)
                                     .Where(e => e.Events.Any())
                                     .ToArray();

            foreach (var entity in entitiesWithEvents)
            {
                var events = entity.Events.ToArray();
                entity.Events.Clear();
                foreach (var domainEvent in events)
                {
                    _dispatcher.Dispatch(domainEvent);
                }
            }

            return(result);
        }
        public override async Task <int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            //DateTime now = DateTime.UtcNow;
            //foreach (ObjectStateEntry entry in (this as IObjectContextAdapter).ObjectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified))
            //{
            //    if (!entry.IsRelationship)
            //    {
            //        IHasLastModified lastModified = entry.Entity as IHasLastModified;
            //        if (lastModified != null)
            //            lastModified.LastModified = now;
            //    }
            //}

            int result = await base.SaveChangesAsync();

            // dispatch events only if save was successful
            var entitiesWithEvents = ChangeTracker.Entries <BaseEntity>()
                                     .Select(e => e.Entity)
                                     .Where(e => e.Events.Any())
                                     .ToArray();

            foreach (var entity in entitiesWithEvents)
            {
                var events = entity.Events.ToArray();
                entity.Events.Clear();
                foreach (var domainEvent in events)
                {
                    _dispatcher.Dispatch(domainEvent);
                }
            }

            return(result);
        }
예제 #8
0
        public override int SaveChanges()
        {
            int result = base.SaveChanges();

            // ignore events if no dispatcher provided
            if (_dispatcher == null)
            {
                return(result);
            }

            // dispatch events only if save was successful
            var entitiesWithEvents = ChangeTracker.Entries <BaseEntity>()
                                     .Select(e => e.Entity)
                                     .Where(e => e.Events.Any())
                                     .ToArray();

            foreach (var entity in entitiesWithEvents)
            {
                var events = entity.Events.ToArray();
                entity.Events.Clear();
                foreach (var domainEvent in events)
                {
                    _dispatcher.Dispatch(domainEvent);
                }
            }

            return(result);
        }
예제 #9
0
        async Task FlushDomainEvents(CancellationToken token)
        {
            var passCount = 0;

            // Handling of events could Raise more events, so keep going until nothing left
            while (true)
            {
                passCount++;
                var domainEventsThisPass = dbContext.ChangeTracker
                                           .Entries()
                                           .Select(e => e.Entity)
                                           .OfType <IDomainEntity>()
                                           .SelectMany(e => e.DomainEvents.GetAndClear())
                                           .ToArray();
                if (domainEventsThisPass.Length == 0)
                {
                    break;
                }

                foreach (var domainEvent in domainEventsThisPass)
                {
                    await domainEventDispatcher.Dispatch(domainEvent, token);
                }

                log.Information("Flushed domain events; pass {Pass}, {EventCount} events", passCount, domainEventsThisPass.Length);
            }
        }
예제 #10
0
        private void QueueToRanking(Family family)
        {
            var classification = _scoreFamilyServiceManager.CalculateScore(family);
            var @event         = new FamilyScoreCalculatedEvent(family.Id, classification.Score, classification.TotalCriterias);

            _domainEventDispatcher.Dispatch(@event);
        }
예제 #11
0
        private void StartGameWeek()
        {
            var season = _repository.Get(new CurrentSeason());
            var firstGameNotCompleted = _repository.List <Game>()
                                        .OrderBy(g => g.Date)
                                        .FirstOrDefault(g => !g.IsCompleted);

            if (firstGameNotCompleted == null)
            {
                season.CompletePhase();
                _repository.Update(season);
                return;
            }

            season.SetDate(firstGameNotCompleted.Date);

            if (season.CurDate == season.NextPhase.Date)
            {
                season.CompletePhase();
                _repository.Update(season);
                return;
            }
            _repository.Update(season);

            _dispatcher.Dispatch(new GameWeekStartedEvent());
        }
    public async Task <IActionResult> OnPostAsync(string captcha, string inviteCode, string email, string?returnUrl = null)
    {
        returnUrl = returnUrl ?? Url.Content("~/");
        if (!await _captchaValidator.IsCaptchaPassedAsync(captcha))
        {
            ModelState.AddModelError("captcha", "Captcha validation failed");
        }
        if (ModelState.IsValid)
        {
            if (Input is null)
            {
                throw new Exception("Input is null.");
            }
            var user = new ApplicationUser {
                UserName = email, Email = email
            };
            var result = await _userManager.CreateAsync(user, Input.Password);

            if (result.Succeeded)
            {
                _logger.LogInformation("User created a new account with password.");

                var newUserEvent = new NewUserRegisteredEvent(email,
                                                              Request.HttpContext.Connection.RemoteIpAddress !.ToString());

                await _dispatcher.Dispatch(newUserEvent);

                var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);

                var userId = user.Id;

                var emailConfirmationResult = await _userManager.ConfirmEmailAsync(user, code);

                if (!emailConfirmationResult.Succeeded)
                {
                    throw new InvalidOperationException($"Error confirming email for user with ID '{userId}':");
                }

                await _newMemberService.MemberSetupAsync(userId, Input.FirstName !, Input.LastName !, inviteCode !, email);

                _logger.LogInformation($"Adding user {user.Email} to Member Role");
                var roles = await _roleManager.Roles.ToListAsync();

                var memberRole = roles.FirstOrDefault(r => r.Name == "Member");
                if (memberRole != null)
                {
                    await _userRoleMembershipService.AddUserToRoleAsync(userId, memberRole.Id);
                }
                return(RedirectToRoute("/User/MyProfile"));
            }
            foreach (var error in result.Errors)
            {
                ModelState.AddModelError(string.Empty, error.Description);
            }
        }

        // If we got this far, something failed, redisplay form
        return(Page());
    }
예제 #13
0
 public void DispatchAndClearAccumulatedEvents(IDomainEventDispatcher eventDispatcher)
 {
     foreach (var domainEvent in this._events)
     {
         eventDispatcher.Dispatch(domainEvent);
     }
     this._events.Clear();
 }
예제 #14
0
파일: Entity.cs 프로젝트: jalbrzym/ddd
        public void DispatchDomainEvents(IDomainEventDispatcher dispatcher)
        {
            foreach (var domainEvent in _domainEvents)
            {
                dispatcher.Dispatch(domainEvent);
            }

            _domainEvents.Clear();
        }
예제 #15
0
        protected void DispatchEvents(TAggregate entity)
        {
            Guard.ArgNotNull(entity, nameof(entity));

            foreach (IDomainEvent domainEvent in entity.DomainEvents)
            {
                Dispatcher.Dispatch(domainEvent);
            }
        }
예제 #16
0
    public async Task <IActionResult> OnPostAsync(string captcha, string?returnUrl = null)
    {
        returnUrl = returnUrl ?? Url.Content("~/");
        if (!await _captchaValidator.IsCaptchaPassedAsync(captcha))
        {
            ModelState.AddModelError("captcha", "Captcha validation failed");
        }
        if (ModelState.IsValid)
        {
            if (Input is null)
            {
                throw new Exception("Input is null.");
            }
            var user = new ApplicationUser {
                UserName = Input.Email, Email = Input.Email
            };
            var result = await _userManager.CreateAsync(user, Input.Password);

            if (result.Succeeded)
            {
                _logger.LogInformation("User created a new account with password.");

                var newUserEvent = new NewUserRegisteredEvent(Input.Email !,
                                                              Request.HttpContext.Connection.RemoteIpAddress !.ToString());

                await _dispatcher.Dispatch(newUserEvent);

                var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);

                var callbackUrl = Url.Page(
                    "/Account/ConfirmEmail",
                    pageHandler: null,
                    values: new { userId = user.Id, code = code },
                    protocol: Request.Scheme);
                if (string.IsNullOrEmpty(callbackUrl))
                {
                    throw new Exception("Callback URL is null or empty.");
                }

                if (string.IsNullOrEmpty(Input.Email))
                {
                    throw new Exception("Email is required.");
                }
                await _emailService.SendEmailAsync(Input.Email, "Confirm your email",
                                                   $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");

                return(LocalRedirect("~/Identity/Account/EmailVerificationRequired"));
            }
            foreach (var error in result.Errors)
            {
                ModelState.AddModelError(string.Empty, error.Description);
            }
        }

        // If we got this far, something failed, redisplay form
        return(Page());
    }
        public async Task Commit()
        {
            foreach (var item in _items)
            {
                await _domainEventDispatcher.Dispatch(item).ConfigureAwait(false);
            }

            _items.Clear();
        }
예제 #18
0
        /// <summary>
        /// Dispatch an domain event
        /// </summary>
        /// <typeparam name="T">Type of domain event</typeparam>
        /// <param name="domainEvent">Event to dispatch</param>
        /// <remarks>The domain event will either be dispatched synchronusly or async depending on the used implementation.</remarks>
        public static void Publish <T>(T domainEvent) where T : class, IDomainEvent
        {
            if (_domainEventDispatcher == null)
            {
                throw new InvalidOperationException(
                          "A domain event dispatcher has not been specified. Read the class documentation for the DomainEvent class.");
            }

            _domainEventDispatcher.Dispatch(domainEvent);
        }
        private void PostCommit(object entity)
        {
            if (!(entity is Entity domainEntity))
            {
                return;
            }

            eventDispatcher.Dispatch(domainEntity.DomainEvents);
            domainEntity.ClearDomainEvents();
        }
예제 #20
0
        private void DomainDispatcher(TEntity entity)
        {
            var readOnlyCollection = entity.GetUncommittedEvents();

            foreach (var @event in readOnlyCollection)
            {
                _domainEventDispatcher.Dispatch(@event);
            }
            entity.ClearDomainEvents();
        }
    public async Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("StartupNotificationService.StartAsync called");
        //if (!_notificationSent)
        //{
        await _dispatcher.Dispatch(new AppStartedEvent(DateTime.Now));

        //  _notificationSent = true;
        //}
    }
예제 #22
0
    private async void RaiseDailyCheckInitiatedEvent()
    {
        await _dispatcher.Dispatch(new DailyCheckInitiatedEvent());

        _logger.LogInformation("Daily Check Event Raised");

        DailyCheck dailyCheck = new DailyCheck();

        dailyCheck.Date = DateTime.Now;
        await _repository.AddAsync(dailyCheck);
    }
예제 #23
0
        public async Task <InfoDto> Handle(FilmInfoLookupQuery query, CancellationToken cancellationToken = default)
        {
            var dto = await _databaseContext.FilmFiles
                      .Where(ff => ff.Id == query.FileId)
                      .ProjectTo <InfoDto>(_mapper.ConfigurationProvider)
                      .SingleAsync(cancellationToken);

            dto.FilePath = await _eventDispatcher.Dispatch(new StreamUrlQuery(StreamKind.Film, dto.Id));

            return(dto);
        }
예제 #24
0
        /// <summary>
        /// Source: https://github.com/ardalis/CleanArchitecture/blob/master/src/CleanArchitecture.Infrastructure/Data/AppDbContext.cs
        /// </summary>
        private void SaveChangesWithEvents(IDomainEventDispatcher domainEventDispatcher)
        {
            var entities = ChangeTracker.Entries().Select(e => e.Entity);

            entities
            .Where(e =>
                   !e.GetType().BaseType.IsGenericType&&
                   typeof(AggregateRootBase).IsAssignableFrom(e.GetType()))
            .Select(aggregateRoot =>
            {
                var events = ((IAggregateRoot)aggregateRoot).GetUncommittedEvents();

                foreach (var domainEvent in events)
                {
                    domainEventDispatcher.Dispatch(domainEvent);
                }

                ((IAggregateRoot)aggregateRoot).GetUncommittedEvents().Clear();
                return(aggregateRoot);
            })
            .ToArray();

            entities
            .Where(e =>
                   e.GetType().BaseType.IsGenericType&&
                   typeof(AggregateRootWithIdBase <>).IsAssignableFrom(e.GetType().BaseType.GetGenericTypeDefinition()))
            .Select(aggregateRoot =>
            {
                //todo: need a better code to avoid dynamic
                var events = ((dynamic)aggregateRoot).GetUncommittedEvents();

                foreach (var domainEvent in events)
                {
                    domainEventDispatcher.Dispatch(domainEvent);
                }

                ((dynamic)aggregateRoot).GetUncommittedEvents().Clear();
                return(aggregateRoot);
            })
            .ToArray();
        }
예제 #25
0
        public override async Task <int> SaveChangesAsync(CancellationToken token = default)
        {
            var result = await base.SaveChangesAsync(token);

            var entitiesWithEvents = ChangeTracker.Entries <BaseEntity>()
                                     .Select(e => e.Entity)
                                     .Where(e => e.Events.Any())
                                     .ToArray();

            foreach (var entity in entitiesWithEvents)
            {
                var events = entity.Events.ToArray();
                entity.Events.Clear();
                foreach (var domainEvent in events)
                {
                    _dispatcher.Dispatch(domainEvent);
                }
            }
            DetachAllEntities();
            return(result);
        }
        public async Task AddUserToRoleAsync(string userId, string roleId)
        {
            var user = await _userManager.Users.FirstOrDefaultAsync(x => x.Id == userId);

            if (user == null)
            {
                throw new UserNotFoundException(userId);
            }

            var role = await _roleManager.Roles.FirstOrDefaultAsync(x => x.Id == roleId);

            if (role == null)
            {
                throw new RoleNotFoundException(roleId);
            }

            await _userManager.AddToRoleAsync(user, role.Name);

            var userAddedToRoleEvent = new UserAddedToRoleEvent(user.Email, role.Name);
            await _dispatcher.Dispatch(userAddedToRoleEvent);
        }
예제 #27
0
        private async Task PublishDomainEventAsync(TEntity entity)
        {
            var events = entity.GetUncommittedEvents().ToArray();

            if (events.Length > 0)
            {
                foreach (var domainEvent in events)
                {
                    await _domainEventDispatcher.Dispatch(domainEvent);
                }
            }
        }
예제 #28
0
        public IActionResult Error()
        {
            var feature = HttpContext
                          .Features
                          .Get <IExceptionHandlerPathFeature>();

            if (feature != null)
            {
                var exceptionEvent = new SiteErrorOccurredEvent(feature.Error);
                _dispatcher.Dispatch(exceptionEvent);
            }
            return(View());
        }
예제 #29
0
 private void UpdateRecords()
 {
     foreach (Game game in _games)
     {
         if (game.IsTie)
         {
             game.HomeTeam.Record.Ties++;
             game.AwayTeam.Record.Ties++;
         }
         else if (game.Winner == game.HomeTeam)
         {
             game.HomeTeam.Record.Wins++;
             game.AwayTeam.Record.Losses++;
         }
         else if (game.Winner == game.AwayTeam)
         {
             game.HomeTeam.Record.Losses++;
             game.AwayTeam.Record.Wins++;
         }
     }
     _repository.UpdateRange(_teams);
     _dispatcher.Dispatch(new TeamRecordsChangedEvent());
 }
예제 #30
0
        private void DispatchEvents(AggregateRoot aggregateRoot)
        {
            if (aggregateRoot == null)
            {
                return;
            }

            foreach (var domainEvent in aggregateRoot.DomainEvents)
            {
                _domainEventDispatcher.Dispatch(domainEvent);
            }

            aggregateRoot.ClearEvents();
        }