start working on commenting a link
This commit is contained in:
parent
9650d6dc86
commit
d8e832ba81
15
Application/CommentLink/CommentLinkCommand.cs
Normal file
15
Application/CommentLink/CommentLinkCommand.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using MediatR;
|
||||
|
||||
namespace HN.Application
|
||||
{
|
||||
public sealed class CommentLinkCommand : IRequest<Guid>
|
||||
{
|
||||
[Required]
|
||||
public Guid LinkId { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Content { get; set; }
|
||||
}
|
||||
}
|
||||
30
Application/CommentLink/CommentLinkCommandHandler.cs
Normal file
30
Application/CommentLink/CommentLinkCommandHandler.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using HN.Domain;
|
||||
using MediatR;
|
||||
|
||||
namespace HN.Application
|
||||
{
|
||||
public sealed class CommentLinkCommandHandler : IRequestHandler<CommentLinkCommand, Guid>
|
||||
{
|
||||
private readonly ILinkRepository _linkRepository;
|
||||
private readonly ICommentRepository _commentRepository;
|
||||
|
||||
public CommentLinkCommandHandler(ILinkRepository linkRepository, ICommentRepository commentRepository)
|
||||
{
|
||||
_linkRepository = linkRepository;
|
||||
_commentRepository = commentRepository;
|
||||
}
|
||||
|
||||
public async Task<Guid> Handle(CommentLinkCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var link = await _linkRepository.GetByIdAsync(request.LinkId);
|
||||
var comment = link.AddComment(request.Content);
|
||||
|
||||
await _commentRepository.AddAsync(comment);
|
||||
|
||||
return comment.Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -27,7 +27,8 @@ namespace Website
|
||||
services.AddDbContext<HNDbContext>(options => options.UseSqlite(Configuration.GetConnectionString("Default")));
|
||||
services.AddScoped<IDbContext, HNDbContext>();
|
||||
services.AddScoped<ILinkRepository, LinkRepository>();
|
||||
services.AddMediatR(typeof(HN.Application.AddLinkCommand));
|
||||
services.AddScoped<ICommentRepository, CommentRepository>();
|
||||
services.AddMediatR(typeof(HN.Application.IDbContext));
|
||||
|
||||
services.Configure<RouteOptions>(options =>
|
||||
{
|
||||
|
||||
20
Domain/Comment.cs
Normal file
20
Domain/Comment.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
|
||||
namespace HN.Domain
|
||||
{
|
||||
public sealed class Comment
|
||||
{
|
||||
public Guid Id { get; private set; }
|
||||
public Guid LinkId { get; private set; }
|
||||
public string Content { get; private set; }
|
||||
public DateTime CreatedAt { get; private set; }
|
||||
|
||||
internal Comment(Guid linkId, string content)
|
||||
{
|
||||
Id = Guid.NewGuid();
|
||||
LinkId = linkId;
|
||||
Content = content;
|
||||
CreatedAt = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
}
|
||||
9
Domain/ICommentRepository.cs
Normal file
9
Domain/ICommentRepository.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HN.Domain
|
||||
{
|
||||
public interface ICommentRepository
|
||||
{
|
||||
Task AddAsync(Comment comment);
|
||||
}
|
||||
}
|
||||
@ -33,5 +33,10 @@ namespace HN.Domain
|
||||
{
|
||||
_votes.Add(new Vote(VoteType.Down));
|
||||
}
|
||||
|
||||
public Comment AddComment(string content)
|
||||
{
|
||||
return new Comment(Id, content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
17
Infrastructure/CommentRepository.cs
Normal file
17
Infrastructure/CommentRepository.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System.Threading.Tasks;
|
||||
using HN.Domain;
|
||||
|
||||
namespace HN.Infrastructure
|
||||
{
|
||||
public sealed class CommentRepository : Repository<Comment>, ICommentRepository
|
||||
{
|
||||
public CommentRepository(HNDbContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public Task AddAsync(Comment comment)
|
||||
{
|
||||
return base.AddAsync(comment);
|
||||
}
|
||||
}
|
||||
}
|
||||
22
Infrastructure/EntityTypes/CommentEntityType.cs
Normal file
22
Infrastructure/EntityTypes/CommentEntityType.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using HN.Domain;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace HN.Infrastructure
|
||||
{
|
||||
public sealed class CommentEntityType : IEntityTypeConfiguration<Comment>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Comment> builder)
|
||||
{
|
||||
builder.ToTable("comments");
|
||||
builder.HasKey(o => o.Id);
|
||||
builder.HasOne<Link>()
|
||||
.WithMany()
|
||||
.HasForeignKey(o => o.LinkId)
|
||||
.IsRequired();
|
||||
builder.Property(o => o.Content).IsRequired();
|
||||
builder.Property(o => o.CreatedAt).IsRequired();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -11,19 +11,19 @@ namespace HN.Infrastructure
|
||||
{
|
||||
}
|
||||
|
||||
public async Task AddAsync(Link link)
|
||||
public Task AddAsync(Link link)
|
||||
{
|
||||
await base.AddAsync(link);
|
||||
return base.AddAsync(link);
|
||||
}
|
||||
|
||||
public Task<Link> GetByIdAsync(Guid id)
|
||||
{
|
||||
return Entries.SingleOrDefaultAsync(o => o.Id == id);
|
||||
return Entries.Include(l => l.Votes).SingleOrDefaultAsync(o => o.Id == id);
|
||||
}
|
||||
|
||||
public async Task UpdateAsync(Link link)
|
||||
public Task UpdateAsync(Link link)
|
||||
{
|
||||
await base.UpdateAsync(link);
|
||||
return base.UpdateAsync(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
107
Infrastructure/Migrations/20201210171100_CreateComment.Designer.cs
generated
Normal file
107
Infrastructure/Migrations/20201210171100_CreateComment.Designer.cs
generated
Normal file
@ -0,0 +1,107 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using HN.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
namespace Infrastructure.Migrations
|
||||
{
|
||||
[DbContext(typeof(HNDbContext))]
|
||||
[Migration("20201210171100_CreateComment")]
|
||||
partial class CreateComment
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "5.0.0");
|
||||
|
||||
modelBuilder.Entity("HN.Domain.Comment", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("LinkId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LinkId");
|
||||
|
||||
b.ToTable("comments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("HN.Domain.Link", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.IsRequired()
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Url")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("links");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("HN.Domain.Vote", b =>
|
||||
{
|
||||
b.Property<Guid>("LinkId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("LinkId");
|
||||
|
||||
b.ToTable("link_votes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("HN.Domain.Comment", b =>
|
||||
{
|
||||
b.HasOne("HN.Domain.Link", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("LinkId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("HN.Domain.Vote", b =>
|
||||
{
|
||||
b.HasOne("HN.Domain.Link", null)
|
||||
.WithMany("Votes")
|
||||
.HasForeignKey("LinkId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("HN.Domain.Link", b =>
|
||||
{
|
||||
b.Navigation("Votes");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
42
Infrastructure/Migrations/20201210171100_CreateComment.cs
Normal file
42
Infrastructure/Migrations/20201210171100_CreateComment.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace Infrastructure.Migrations
|
||||
{
|
||||
public partial class CreateComment : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "comments",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
LinkId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
Content = table.Column<string>(type: "TEXT", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_comments", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_comments_links_LinkId",
|
||||
column: x => x.LinkId,
|
||||
principalTable: "links",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_comments_LinkId",
|
||||
table: "comments",
|
||||
column: "LinkId");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "comments");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -16,6 +16,29 @@ namespace Infrastructure.Migrations
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "5.0.0");
|
||||
|
||||
modelBuilder.Entity("HN.Domain.Comment", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("LinkId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LinkId");
|
||||
|
||||
b.ToTable("comments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("HN.Domain.Link", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
@ -54,6 +77,15 @@ namespace Infrastructure.Migrations
|
||||
b.ToTable("link_votes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("HN.Domain.Comment", b =>
|
||||
{
|
||||
b.HasOne("HN.Domain.Link", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("LinkId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("HN.Domain.Vote", b =>
|
||||
{
|
||||
b.HasOne("HN.Domain.Link", null)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user