-
Notifications
You must be signed in to change notification settings - Fork 545
/
Create.cs
93 lines (80 loc) · 2.89 KB
/
Create.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Conduit.Domain;
using Conduit.Infrastructure;
using FluentValidation;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace Conduit.Features.Articles;
public class Create
{
public class ArticleData
{
public string? Title { get; init; }
public string? Description { get; init; }
public string? Body { get; init; }
public string[]? TagList { get; init; }
}
public class ArticleDataValidator : AbstractValidator<ArticleData>
{
public ArticleDataValidator()
{
RuleFor(x => x.Title).NotNull().NotEmpty();
RuleFor(x => x.Description).NotNull().NotEmpty();
RuleFor(x => x.Body).NotNull().NotEmpty();
}
}
public record Command(ArticleData Article) : IRequest<ArticleEnvelope>;
public class CommandValidator : AbstractValidator<Command>
{
public CommandValidator() =>
RuleFor(x => x.Article).NotNull().SetValidator(new ArticleDataValidator());
}
public class Handler(ConduitContext context, ICurrentUserAccessor currentUserAccessor)
: IRequestHandler<Command, ArticleEnvelope>
{
public async Task<ArticleEnvelope> Handle(
Command message,
CancellationToken cancellationToken
)
{
var author = await context.Persons.FirstAsync(
x => x.Username == currentUserAccessor.GetCurrentUsername(),
cancellationToken
);
var tags = new List<Tag>();
foreach (var tag in (message.Article.TagList ?? Enumerable.Empty<string>()))
{
var t = await context.Tags.FindAsync(tag);
if (t == null)
{
t = new Tag { TagId = tag };
await context.Tags.AddAsync(t, cancellationToken);
//save immediately for reuse
await context.SaveChangesAsync(cancellationToken);
}
tags.Add(t);
}
var article = new Article
{
Author = author,
Body = message.Article.Body,
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow,
Description = message.Article.Description,
Title = message.Article.Title,
Slug = message.Article.Title.GenerateSlug()
};
await context.Articles.AddAsync(article, cancellationToken);
await context.ArticleTags.AddRangeAsync(
tags.Select(x => new ArticleTag { Article = article, Tag = x }),
cancellationToken
);
await context.SaveChangesAsync(cancellationToken);
return new ArticleEnvelope(article);
}
}
}