public ContentVisitor(Content.Content content, Visitor visitor, Ad ad = null)
 {
     Content   = content ?? throw new ArgumentNullException(nameof(content));
     Visitor   = visitor ?? throw new ArgumentNullException(nameof(visitor));
     VisitedAd = DateTime.UtcNow;
     Ad        = ad;
     visitor.AddVisit(this);
     content.AddVisit(this);
 }
        public async Task <ArticleDto> Handle(GetArticle request, CancellationToken cancellationToken)
        {
            var article = await _context.Articles
                          .Include(a => a.Ads)
                          .Include(a => a.Comments)
                          .Include(a => a.Category)
                          .Include(a => a.ContentVisitors)
                          .SingleOrDefaultAsync(a => a.Id == request.ArticleId, cancellationToken);

            var username = await _userAccessor.GetUsername();

            var ipAddress = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress;

            if (string.IsNullOrEmpty(username))
            {
                var visitor = new Visitor(ipAddress.ToString());
                var visit   = new ContentVisitor(article, visitor);
                visitor.AddVisit(visit);
                await _context.Visitors.AddAsync(visitor, cancellationToken);
            }
            else
            {
                var user = await _context.Users.SingleOrDefaultAsync(u => u.Username.ToLower() == username,
                                                                     cancellationToken);

                if (user == null)
                {
                    throw new ApplicationException($"Could not find such user {username}");
                }

                var visit = new ContentVisitor(article, user);
                user.AddVisit(visit);
            }

            await _context.SaveChangesAsync(cancellationToken);

            return(article.AsDto());
        }