tiny-refactors #27

Merged
jleicher merged 4 commits from tiny-refactors into master 2020-12-17 12:01:12 +01:00
22 changed files with 88 additions and 37 deletions

3
.dockerignore Normal file
View File

@ -0,0 +1,3 @@
**/bin
**/obj
**/Dockerfile

View File

@ -24,15 +24,13 @@ namespace HN.Application
switch (request.Type) switch (request.Type)
{ {
case VoteType.Up: case VoteType.Up:
comment.Upvote(userId); comment.UpvoteBy(userId);
break; break;
case VoteType.Down: case VoteType.Down:
comment.Downvote(userId); comment.DownvoteBy(userId);
break; break;
} }
await _commentRepository.UpdateAsync(comment);
return Unit.Value; return Unit.Value;
} }
} }

View File

@ -24,15 +24,13 @@ namespace HN.Application
switch (request.Type) switch (request.Type)
{ {
case VoteType.Up: case VoteType.Up:
link.Upvote(userId); link.UpvoteBy(userId);
break; break;
case VoteType.Down: case VoteType.Down:
link.Downvote(userId); link.DownvoteBy(userId);
break; break;
} }
await _linkRepository.UpdateAsync(link);
return Unit.Value; return Unit.Value;
} }
} }

View File

@ -1,6 +1,6 @@
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using HN.Infrastructure; using HN.Infrastructure.Identity;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;

23
Apps/Website/Dockerfile Normal file
View File

@ -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"]

View File

@ -1,6 +1,6 @@
using System; using System;
using HN.Application; using HN.Application;
using HN.Infrastructure; using HN.Infrastructure.Identity;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;

View File

@ -1,3 +1,4 @@
using System;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
@ -14,6 +15,7 @@ namespace Website
Host.CreateDefaultBuilder(args) Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => .ConfigureWebHostDefaults(webBuilder =>
{ {
webBuilder.UseUrls($"http://0.0.0.0:{Environment.GetEnvironmentVariable("PORT") ?? "5000"}");
webBuilder.UseStartup<Startup>(); webBuilder.UseStartup<Startup>();
}); });
} }

View File

@ -1,6 +1,9 @@
using HN.Application; using HN.Application;
using HN.Domain; using HN.Domain;
using HN.Infrastructure; using HN.Infrastructure;
using HN.Infrastructure.Behaviors;
using HN.Infrastructure.Identity;
using HN.Infrastructure.Repositories;
using MediatR; using MediatR;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
@ -32,6 +35,7 @@ namespace Website
services.AddScoped<ILinkRepository, LinkRepository>(); services.AddScoped<ILinkRepository, LinkRepository>();
services.AddScoped<ICommentRepository, CommentRepository>(); services.AddScoped<ICommentRepository, CommentRepository>();
services.AddScoped<IExecutingUserProvider, HttpExecutingUserProvider>(); services.AddScoped<IExecutingUserProvider, HttpExecutingUserProvider>();
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(UnitOfWorkBehavior<,>));
services.AddMediatR(typeof(HN.Application.IHNContext)); services.AddMediatR(typeof(HN.Application.IHNContext));
// Permet d'avoir des routes en lowercase // 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. // 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.UseHsts();
} }
app.UseHttpsRedirection(); // app.UseHttpsRedirection();
app.UseStaticFiles(); app.UseStaticFiles();
app.UseRouting(); app.UseRouting();

View File

@ -14,4 +14,11 @@
<ProjectReference Include="..\..\Infrastructure\Infrastructure.csproj" /> <ProjectReference Include="..\..\Infrastructure\Infrastructure.csproj" />
</ItemGroup> </ItemGroup>
<!-- Utilisation de l'incremental build fournit par MSBuild pour exécuter la tâche que quand nécessaire -->
<!-- <Target Name="npm install as needed" BeforeTargets="BeforeBuild" Inputs="package.json" Outputs="package.json.tmp">
<Message Text="Installing npm packages" />
<Exec Command="npm i" />
<Copy SourceFiles="package.json" DestinationFiles="package.json.tmp" />
</Target> -->
</Project> </Project>

View File

@ -6,7 +6,6 @@ namespace HN.Domain
public interface ICommentRepository public interface ICommentRepository
{ {
Task AddAsync(Comment comment); Task AddAsync(Comment comment);
Task UpdateAsync(Comment comment);
Task<Comment> GetByIdAsync(Guid id); Task<Comment> GetByIdAsync(Guid id);
} }
} }

View File

@ -6,7 +6,6 @@ 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); Task<Link> GetByIdAsync(Guid id);
} }
} }

View File

@ -17,12 +17,12 @@ namespace HN.Domain
_votes = new List<Vote>(); _votes = new List<Vote>();
} }
public void Upvote(Guid userId) public void UpvoteBy(Guid userId)
{ {
UpsertUserVote(userId, VoteType.Up); UpsertUserVote(userId, VoteType.Up);
} }
public void Downvote(Guid userId) public void DownvoteBy(Guid userId)
{ {
UpsertUserVote(userId, VoteType.Down); UpsertUserVote(userId, VoteType.Down);
} }

View File

@ -0,0 +1,25 @@
using System.Threading;
using System.Threading.Tasks;
using MediatR;
namespace HN.Infrastructure.Behaviors
{
public sealed class UnitOfWorkBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
private readonly HNDbContext _context;
public UnitOfWorkBehavior(HNDbContext context)
{
_context = context;
}
public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{
var response = await next();
await _context.SaveChangesAsync();
return response;
}
}
}

View File

@ -1,8 +1,9 @@
using HN.Domain; using HN.Domain;
using HN.Infrastructure.Identity;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HN.Infrastructure namespace HN.Infrastructure.EntityTypes
{ {
public sealed class CommentEntityType : IEntityTypeConfiguration<Comment> public sealed class CommentEntityType : IEntityTypeConfiguration<Comment>
{ {

View File

@ -1,4 +1,5 @@
using HN.Domain; using HN.Domain;
using HN.Infrastructure.Identity;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Builders;

View File

@ -2,6 +2,7 @@
using System.Linq; using System.Linq;
using HN.Application; using HN.Application;
using HN.Domain; using HN.Domain;
using HN.Infrastructure.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;

View File

@ -1,7 +1,7 @@
using System; using System;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
namespace HN.Infrastructure namespace HN.Infrastructure.Identity
{ {
public sealed class Role : IdentityRole<Guid> public sealed class Role : IdentityRole<Guid>
{ {

View File

@ -2,7 +2,7 @@ using System;
using HN.Application; using HN.Application;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
namespace HN.Infrastructure namespace HN.Infrastructure.Identity
{ {
public sealed class User : IdentityUser<Guid>, IUser public sealed class User : IdentityUser<Guid>, IUser
{ {

View File

@ -3,7 +3,7 @@ using System.Threading.Tasks;
using HN.Domain; using HN.Domain;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace HN.Infrastructure namespace HN.Infrastructure.Repositories
{ {
public sealed class CommentRepository : Repository<Comment>, ICommentRepository public sealed class CommentRepository : Repository<Comment>, ICommentRepository
{ {
@ -20,10 +20,5 @@ namespace HN.Infrastructure
{ {
return Entries.SingleOrDefaultAsync(o => o.Id == id); return Entries.SingleOrDefaultAsync(o => o.Id == id);
} }
public Task UpdateAsync(Comment comment)
{
return base.UpdateAsync(comment);
}
} }
} }

View File

@ -3,7 +3,7 @@ using System.Threading.Tasks;
using HN.Domain; using HN.Domain;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace HN.Infrastructure namespace HN.Infrastructure.Repositories
{ {
public sealed class LinkRepository : Repository<Link>, ILinkRepository public sealed class LinkRepository : Repository<Link>, ILinkRepository
{ {
@ -20,10 +20,5 @@ namespace HN.Infrastructure
{ {
return Entries.SingleOrDefaultAsync(o => o.Id == id); return Entries.SingleOrDefaultAsync(o => o.Id == id);
} }
public Task UpdateAsync(Link link)
{
return base.UpdateAsync(link);
}
} }
} }

View File

@ -1,7 +1,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace HN.Infrastructure namespace HN.Infrastructure.Repositories
{ {
public abstract class Repository<TEntity> where TEntity : class public abstract class Repository<TEntity> where TEntity : class
{ {
@ -18,12 +18,6 @@ namespace HN.Infrastructure
protected async Task AddAsync(params TEntity[] entities) protected async Task AddAsync(params TEntity[] entities)
{ {
await Entries.AddRangeAsync(entities); await Entries.AddRangeAsync(entities);
await _context.SaveChangesAsync();
}
protected async Task UpdateAsync(params TEntity[] entities)
{
await _context.SaveChangesAsync();
} }
} }
} }

View File

@ -166,3 +166,9 @@ project.csproj
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<DocumentationFile>bin\YourApi.XML</DocumentationFile> <DocumentationFile>bin\YourApi.XML</DocumentationFile>
</PropertyGroup> </PropertyGroup>
## 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`.