vote-for-link #22
22
Application/VoteForLink/VoteForLinkCommand.cs
Normal file
22
Application/VoteForLink/VoteForLinkCommand.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using HN.Domain;
|
||||||
|
using MediatR;
|
||||||
|
|
||||||
|
namespace HN.Application
|
||||||
|
{
|
||||||
|
public sealed class VoteForLinkCommand : IRequest
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
public Guid LinkId { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public VoteType Type { get; set; }
|
||||||
|
|
||||||
|
public VoteForLinkCommand(Guid linkId, VoteType type)
|
||||||
|
{
|
||||||
|
LinkId = linkId;
|
||||||
|
Type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
36
Application/VoteForLink/VoteForLinkCommandHandler.cs
Normal file
36
Application/VoteForLink/VoteForLinkCommandHandler.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using HN.Domain;
|
||||||
|
using MediatR;
|
||||||
|
|
||||||
|
namespace HN.Application
|
||||||
|
{
|
||||||
|
public sealed class VoteForLinkCommandHandler : IRequestHandler<VoteForLinkCommand>
|
||||||
|
{
|
||||||
|
private readonly ILinkRepository _linkRepository;
|
||||||
|
|
||||||
|
public VoteForLinkCommandHandler(ILinkRepository linkRepository)
|
||||||
|
{
|
||||||
|
_linkRepository = linkRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Unit> Handle(VoteForLinkCommand request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var link = await _linkRepository.GetByIdAsync(request.LinkId);
|
||||||
|
|
||||||
|
switch (request.Type)
|
||||||
|
{
|
||||||
|
case VoteType.Up:
|
||||||
|
link.Upvote();
|
||||||
|
break;
|
||||||
|
case VoteType.Down:
|
||||||
|
link.Downvote();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _linkRepository.UpdateAsync(link);
|
||||||
|
|
||||||
|
return Unit.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@ using HN.Application;
|
|||||||
using MediatR;
|
using MediatR;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System;
|
using System;
|
||||||
|
using HN.Domain;
|
||||||
|
|
||||||
namespace Website.Controllers
|
namespace Website.Controllers
|
||||||
{
|
{
|
||||||
@ -32,6 +33,16 @@ namespace Website.Controllers
|
|||||||
return View(new AddLinkCommand());
|
return View(new AddLinkCommand());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost("{controller}/{id:guid}/vote")]
|
||||||
|
[ValidateAntiForgeryToken]
|
||||||
|
public async Task<IActionResult> Vote(Guid id, string url, VoteType type)
|
||||||
|
{
|
||||||
|
await _bus.Send(new VoteForLinkCommand(id, type));
|
||||||
|
|
||||||
|
SetFlash($"Successfuly {type} for {url}!");
|
||||||
|
return RedirectToAction(nameof(Index));
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[ValidateAntiForgeryToken]
|
[ValidateAntiForgeryToken]
|
||||||
public async Task<IActionResult> Create(AddLinkCommand command)
|
public async Task<IActionResult> Create(AddLinkCommand command)
|
||||||
|
|||||||
@ -1,3 +1,8 @@
|
|||||||
@model HN.Application.LinkDto
|
@model HN.Application.LinkDto
|
||||||
|
|
||||||
<a asp-action="Show" asp-controller="Links" asp-route-id="@Model.Id">@Model.Url - created at @Model.CreatedAt.ToLocalTime() (👍: @Model.UpVotes / 👎: @Model.DownVotes)</a>
|
<a asp-action="Show" asp-controller="Links" asp-route-id="@Model.Id">@Model.Url - created at @Model.CreatedAt.ToLocalTime() (👍: @Model.UpVotes / 👎: @Model.DownVotes)</a>
|
||||||
|
|
||||||
|
<form asp-controller="Links" asp-action="Vote" asp-route-id="@Model.Id" asp-route-url="@Model.Url" method="post">
|
||||||
|
<input type="submit" name="type" value="up">👍</button>
|
||||||
|
<input type="submit" name="type" value="down">👎</button>
|
||||||
|
</form>
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace HN.Domain
|
namespace HN.Domain
|
||||||
@ -5,5 +6,7 @@ namespace HN.Domain
|
|||||||
public interface ILinkRepository
|
public interface ILinkRepository
|
||||||
{
|
{
|
||||||
Task AddAsync(Link link);
|
Task AddAsync(Link link);
|
||||||
|
Task UpdateAsync(Link link);
|
||||||
|
Task<Link> GetByIdAsync(Guid id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -23,5 +23,15 @@ namespace HN.Domain
|
|||||||
{
|
{
|
||||||
return new Link(url);
|
return new Link(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Upvote()
|
||||||
|
{
|
||||||
|
_votes.Add(new Vote(VoteType.Up));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Downvote()
|
||||||
|
{
|
||||||
|
_votes.Add(new Vote(VoteType.Down));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using HN.Domain;
|
using HN.Domain;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace HN.Infrastructure
|
namespace HN.Infrastructure
|
||||||
{
|
{
|
||||||
@ -13,5 +15,15 @@ namespace HN.Infrastructure
|
|||||||
{
|
{
|
||||||
await base.AddAsync(link);
|
await base.AddAsync(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task<Link> GetByIdAsync(Guid id)
|
||||||
|
{
|
||||||
|
return Entries.SingleOrDefaultAsync(o => o.Id == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateAsync(Link link)
|
||||||
|
{
|
||||||
|
await base.UpdateAsync(link);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -20,5 +20,10 @@ namespace HN.Infrastructure
|
|||||||
await Entries.AddRangeAsync(entities);
|
await Entries.AddRangeAsync(entities);
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected async Task UpdateAsync(params TEntity[] entities)
|
||||||
|
{
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user