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
This commit is contained in:
Julien Leicher 2020-12-17 12:01:11 +01:00
parent 3cd5133f66
commit 7a9aefbefc
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)
{
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;
}
}

View File

@ -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;
}
}

View File

@ -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;

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 HN.Application;
using HN.Infrastructure;
using HN.Infrastructure.Identity;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;

View File

@ -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<Startup>();
});
}

View File

@ -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<ILinkRepository, LinkRepository>();
services.AddScoped<ICommentRepository, CommentRepository>();
services.AddScoped<IExecutingUserProvider, HttpExecutingUserProvider>();
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();

View File

@ -14,4 +14,11 @@
<ProjectReference Include="..\..\Infrastructure\Infrastructure.csproj" />
</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>

View File

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

View File

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

View File

@ -17,12 +17,12 @@ namespace HN.Domain
_votes = new List<Vote>();
}
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);
}

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.Infrastructure.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HN.Infrastructure
namespace HN.Infrastructure.EntityTypes
{
public sealed class CommentEntityType : IEntityTypeConfiguration<Comment>
{

View File

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

View File

@ -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;

View File

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

View File

@ -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<Guid>, IUser
{

View File

@ -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<Comment>, ICommentRepository
{
@ -20,10 +20,5 @@ namespace HN.Infrastructure
{
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 Microsoft.EntityFrameworkCore;
namespace HN.Infrastructure
namespace HN.Infrastructure.Repositories
{
public sealed class LinkRepository : Repository<Link>, ILinkRepository
{
@ -20,10 +20,5 @@ namespace HN.Infrastructure
{
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 Microsoft.EntityFrameworkCore;
namespace HN.Infrastructure
namespace HN.Infrastructure.Repositories
{
public abstract class Repository<TEntity> 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();
}
}
}

View File

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