From 7a9aefbefcb49f69e24bdd5974258f7304ad7969 Mon Sep 17 00:00:00 2001 From: Julien Leicher Date: Thu, 17 Dec 2020 12:01:11 +0100 Subject: [PATCH] tiny-refactors (#27) add UnitWorkBehavior and some files moving add Docker stuff to prepare heroku deployment rename (Up/Down)vote add sample for msbuild tasks --- .dockerignore | 3 +++ .../VoteForCommentCommandHandler.cs | 6 ++--- .../VoteForLink/VoteForLinkCommandHandler.cs | 6 ++--- .../Website/Controllers/AccountsController.cs | 2 +- Apps/Website/Dockerfile | 23 +++++++++++++++++ Apps/Website/HttpExecutingUserProvider.cs | 2 +- Apps/Website/Program.cs | 2 ++ Apps/Website/Startup.cs | 6 ++++- Apps/Website/Website.csproj | 7 ++++++ Domain/ICommentRepository.cs | 1 - Domain/ILinkRepository.cs | 1 - Domain/Votable.cs | 4 +-- .../Behaviors/UnitOfWorkBehavior.cs | 25 +++++++++++++++++++ .../EntityTypes/CommentEntityType.cs | 3 ++- Infrastructure/EntityTypes/LinkEntityType.cs | 1 + Infrastructure/HNDbContext.cs | 1 + Infrastructure/{ => Identity}/Role.cs | 2 +- Infrastructure/{ => Identity}/User.cs | 2 +- .../{ => Repositories}/CommentRepository.cs | 7 +----- .../{ => Repositories}/LinkRepository.cs | 7 +----- .../{ => Repositories}/Repository.cs | 8 +----- README.md | 6 +++++ 22 files changed, 88 insertions(+), 37 deletions(-) create mode 100644 .dockerignore create mode 100644 Apps/Website/Dockerfile create mode 100644 Infrastructure/Behaviors/UnitOfWorkBehavior.cs rename Infrastructure/{ => Identity}/Role.cs (74%) rename Infrastructure/{ => Identity}/User.cs (84%) rename Infrastructure/{ => Repositories}/CommentRepository.cs (79%) rename Infrastructure/{ => Repositories}/LinkRepository.cs (79%) rename Infrastructure/{ => Repositories}/Repository.cs (71%) diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..8b3dd3b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +**/bin +**/obj +**/Dockerfile \ No newline at end of file diff --git a/Application/VoteForComment/VoteForCommentCommandHandler.cs b/Application/VoteForComment/VoteForCommentCommandHandler.cs index 804bc31..ad3bb67 100644 --- a/Application/VoteForComment/VoteForCommentCommandHandler.cs +++ b/Application/VoteForComment/VoteForCommentCommandHandler.cs @@ -24,15 +24,13 @@ namespace HN.Application switch (request.Type) { case VoteType.Up: - comment.Upvote(userId); + comment.UpvoteBy(userId); break; case VoteType.Down: - comment.Downvote(userId); + comment.DownvoteBy(userId); break; } - await _commentRepository.UpdateAsync(comment); - return Unit.Value; } } diff --git a/Application/VoteForLink/VoteForLinkCommandHandler.cs b/Application/VoteForLink/VoteForLinkCommandHandler.cs index 263d861..38332e2 100644 --- a/Application/VoteForLink/VoteForLinkCommandHandler.cs +++ b/Application/VoteForLink/VoteForLinkCommandHandler.cs @@ -24,15 +24,13 @@ namespace HN.Application switch (request.Type) { case VoteType.Up: - link.Upvote(userId); + link.UpvoteBy(userId); break; case VoteType.Down: - link.Downvote(userId); + link.DownvoteBy(userId); break; } - await _linkRepository.UpdateAsync(link); - return Unit.Value; } } diff --git a/Apps/Website/Controllers/AccountsController.cs b/Apps/Website/Controllers/AccountsController.cs index c62e13e..0215466 100644 --- a/Apps/Website/Controllers/AccountsController.cs +++ b/Apps/Website/Controllers/AccountsController.cs @@ -1,6 +1,6 @@ using System.Linq; using System.Threading.Tasks; -using HN.Infrastructure; +using HN.Infrastructure.Identity; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; diff --git a/Apps/Website/Dockerfile b/Apps/Website/Dockerfile new file mode 100644 index 0000000..1a2c383 --- /dev/null +++ b/Apps/Website/Dockerfile @@ -0,0 +1,23 @@ +FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build +WORKDIR /source + +COPY *.sln . +COPY Application/*.csproj ./Application/ +COPY Domain/*.csproj ./Domain/ +COPY Infrastructure/*.csproj ./Infrastructure/ +COPY Apps/Website/*.csproj ./Apps/Website/ +RUN dotnet restore + +COPY Application/. ./Application/ +COPY Domain/. ./Domain/ +COPY Infrastructure/. ./Infrastructure/ +COPY Apps/Website/. ./Apps/Website/ + +WORKDIR /source/Apps/Website +RUN dotnet publish -c release -o /app --no-restore + +FROM mcr.microsoft.com/dotnet/aspnet:5.0 +WORKDIR /app +COPY --from=build /app ./ +EXPOSE 80 +ENTRYPOINT ["dotnet", "Website.dll"] \ No newline at end of file diff --git a/Apps/Website/HttpExecutingUserProvider.cs b/Apps/Website/HttpExecutingUserProvider.cs index e42e9ce..420b668 100644 --- a/Apps/Website/HttpExecutingUserProvider.cs +++ b/Apps/Website/HttpExecutingUserProvider.cs @@ -1,6 +1,6 @@ using System; using HN.Application; -using HN.Infrastructure; +using HN.Infrastructure.Identity; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; diff --git a/Apps/Website/Program.cs b/Apps/Website/Program.cs index 767bdd9..4ead8f4 100644 --- a/Apps/Website/Program.cs +++ b/Apps/Website/Program.cs @@ -1,3 +1,4 @@ +using System; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; @@ -14,6 +15,7 @@ namespace Website Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { + webBuilder.UseUrls($"http://0.0.0.0:{Environment.GetEnvironmentVariable("PORT") ?? "5000"}"); webBuilder.UseStartup(); }); } diff --git a/Apps/Website/Startup.cs b/Apps/Website/Startup.cs index fe73284..5aa2e61 100644 --- a/Apps/Website/Startup.cs +++ b/Apps/Website/Startup.cs @@ -1,6 +1,9 @@ using HN.Application; using HN.Domain; using HN.Infrastructure; +using HN.Infrastructure.Behaviors; +using HN.Infrastructure.Identity; +using HN.Infrastructure.Repositories; using MediatR; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Builder; @@ -32,6 +35,7 @@ namespace Website services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(typeof(IPipelineBehavior<,>), typeof(UnitOfWorkBehavior<,>)); services.AddMediatR(typeof(HN.Application.IHNContext)); // Permet d'avoir des routes en lowercase @@ -78,7 +82,7 @@ namespace Website // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } - app.UseHttpsRedirection(); + // app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); diff --git a/Apps/Website/Website.csproj b/Apps/Website/Website.csproj index 54d5e78..3d54b85 100644 --- a/Apps/Website/Website.csproj +++ b/Apps/Website/Website.csproj @@ -14,4 +14,11 @@ + + + diff --git a/Domain/ICommentRepository.cs b/Domain/ICommentRepository.cs index 77706bc..a11f874 100644 --- a/Domain/ICommentRepository.cs +++ b/Domain/ICommentRepository.cs @@ -6,7 +6,6 @@ namespace HN.Domain public interface ICommentRepository { Task AddAsync(Comment comment); - Task UpdateAsync(Comment comment); Task GetByIdAsync(Guid id); } } \ No newline at end of file diff --git a/Domain/ILinkRepository.cs b/Domain/ILinkRepository.cs index 016ee1f..f7f6607 100644 --- a/Domain/ILinkRepository.cs +++ b/Domain/ILinkRepository.cs @@ -6,7 +6,6 @@ namespace HN.Domain public interface ILinkRepository { Task AddAsync(Link link); - Task UpdateAsync(Link link); Task GetByIdAsync(Guid id); } } \ No newline at end of file diff --git a/Domain/Votable.cs b/Domain/Votable.cs index 074e360..9b4a704 100644 --- a/Domain/Votable.cs +++ b/Domain/Votable.cs @@ -17,12 +17,12 @@ namespace HN.Domain _votes = new List(); } - public void Upvote(Guid userId) + public void UpvoteBy(Guid userId) { UpsertUserVote(userId, VoteType.Up); } - public void Downvote(Guid userId) + public void DownvoteBy(Guid userId) { UpsertUserVote(userId, VoteType.Down); } diff --git a/Infrastructure/Behaviors/UnitOfWorkBehavior.cs b/Infrastructure/Behaviors/UnitOfWorkBehavior.cs new file mode 100644 index 0000000..a320f7f --- /dev/null +++ b/Infrastructure/Behaviors/UnitOfWorkBehavior.cs @@ -0,0 +1,25 @@ +using System.Threading; +using System.Threading.Tasks; +using MediatR; + +namespace HN.Infrastructure.Behaviors +{ + public sealed class UnitOfWorkBehavior : IPipelineBehavior + { + private readonly HNDbContext _context; + + public UnitOfWorkBehavior(HNDbContext context) + { + _context = context; + } + + public async Task Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate next) + { + var response = await next(); + + await _context.SaveChangesAsync(); + + return response; + } + } +} \ No newline at end of file diff --git a/Infrastructure/EntityTypes/CommentEntityType.cs b/Infrastructure/EntityTypes/CommentEntityType.cs index dffdd31..b13d246 100644 --- a/Infrastructure/EntityTypes/CommentEntityType.cs +++ b/Infrastructure/EntityTypes/CommentEntityType.cs @@ -1,8 +1,9 @@ using HN.Domain; +using HN.Infrastructure.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; -namespace HN.Infrastructure +namespace HN.Infrastructure.EntityTypes { public sealed class CommentEntityType : IEntityTypeConfiguration { diff --git a/Infrastructure/EntityTypes/LinkEntityType.cs b/Infrastructure/EntityTypes/LinkEntityType.cs index 5fdaa51..dc91ee7 100644 --- a/Infrastructure/EntityTypes/LinkEntityType.cs +++ b/Infrastructure/EntityTypes/LinkEntityType.cs @@ -1,4 +1,5 @@ using HN.Domain; +using HN.Infrastructure.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; diff --git a/Infrastructure/HNDbContext.cs b/Infrastructure/HNDbContext.cs index ba600f1..38e17b2 100644 --- a/Infrastructure/HNDbContext.cs +++ b/Infrastructure/HNDbContext.cs @@ -2,6 +2,7 @@ using System.Linq; using HN.Application; using HN.Domain; +using HN.Infrastructure.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; diff --git a/Infrastructure/Role.cs b/Infrastructure/Identity/Role.cs similarity index 74% rename from Infrastructure/Role.cs rename to Infrastructure/Identity/Role.cs index 82e6405..d7abed0 100644 --- a/Infrastructure/Role.cs +++ b/Infrastructure/Identity/Role.cs @@ -1,7 +1,7 @@ using System; using Microsoft.AspNetCore.Identity; -namespace HN.Infrastructure +namespace HN.Infrastructure.Identity { public sealed class Role : IdentityRole { diff --git a/Infrastructure/User.cs b/Infrastructure/Identity/User.cs similarity index 84% rename from Infrastructure/User.cs rename to Infrastructure/Identity/User.cs index fb961fa..e106eba 100644 --- a/Infrastructure/User.cs +++ b/Infrastructure/Identity/User.cs @@ -2,7 +2,7 @@ using System; using HN.Application; using Microsoft.AspNetCore.Identity; -namespace HN.Infrastructure +namespace HN.Infrastructure.Identity { public sealed class User : IdentityUser, IUser { diff --git a/Infrastructure/CommentRepository.cs b/Infrastructure/Repositories/CommentRepository.cs similarity index 79% rename from Infrastructure/CommentRepository.cs rename to Infrastructure/Repositories/CommentRepository.cs index 3fbe0f7..2f43828 100644 --- a/Infrastructure/CommentRepository.cs +++ b/Infrastructure/Repositories/CommentRepository.cs @@ -3,7 +3,7 @@ using System.Threading.Tasks; using HN.Domain; using Microsoft.EntityFrameworkCore; -namespace HN.Infrastructure +namespace HN.Infrastructure.Repositories { public sealed class CommentRepository : Repository, ICommentRepository { @@ -20,10 +20,5 @@ namespace HN.Infrastructure { return Entries.SingleOrDefaultAsync(o => o.Id == id); } - - public Task UpdateAsync(Comment comment) - { - return base.UpdateAsync(comment); - } } } \ No newline at end of file diff --git a/Infrastructure/LinkRepository.cs b/Infrastructure/Repositories/LinkRepository.cs similarity index 79% rename from Infrastructure/LinkRepository.cs rename to Infrastructure/Repositories/LinkRepository.cs index 87b8614..b3e7802 100644 --- a/Infrastructure/LinkRepository.cs +++ b/Infrastructure/Repositories/LinkRepository.cs @@ -3,7 +3,7 @@ using System.Threading.Tasks; using HN.Domain; using Microsoft.EntityFrameworkCore; -namespace HN.Infrastructure +namespace HN.Infrastructure.Repositories { public sealed class LinkRepository : Repository, ILinkRepository { @@ -20,10 +20,5 @@ namespace HN.Infrastructure { return Entries.SingleOrDefaultAsync(o => o.Id == id); } - - public Task UpdateAsync(Link link) - { - return base.UpdateAsync(link); - } } } \ No newline at end of file diff --git a/Infrastructure/Repository.cs b/Infrastructure/Repositories/Repository.cs similarity index 71% rename from Infrastructure/Repository.cs rename to Infrastructure/Repositories/Repository.cs index fa85942..d3bcd9d 100644 --- a/Infrastructure/Repository.cs +++ b/Infrastructure/Repositories/Repository.cs @@ -1,7 +1,7 @@ using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; -namespace HN.Infrastructure +namespace HN.Infrastructure.Repositories { public abstract class Repository where TEntity : class { @@ -18,12 +18,6 @@ namespace HN.Infrastructure protected async Task AddAsync(params TEntity[] entities) { await Entries.AddRangeAsync(entities); - await _context.SaveChangesAsync(); - } - - protected async Task UpdateAsync(params TEntity[] entities) - { - await _context.SaveChangesAsync(); } } } \ No newline at end of file diff --git a/README.md b/README.md index 9e91a79..35f9e11 100644 --- a/README.md +++ b/README.md @@ -166,3 +166,9 @@ project.csproj true bin\YourApi.XML + +## Docker + +On build à la racine de la solution avec `docker build -f .\Apps\Website\Dockerfile -t hn .`. + +Et on lance avec `docker run -it --rm -p "8000:80" hn`.