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:
parent
3cd5133f66
commit
7a9aefbefc
3
.dockerignore
Normal file
3
.dockerignore
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
**/bin
|
||||||
|
**/obj
|
||||||
|
**/Dockerfile
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
23
Apps/Website/Dockerfile
Normal 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"]
|
||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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>();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
25
Infrastructure/Behaviors/UnitOfWorkBehavior.cs
Normal file
25
Infrastructure/Behaviors/UnitOfWorkBehavior.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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>
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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>
|
||||||
{
|
{
|
||||||
@ -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
|
||||||
{
|
{
|
||||||
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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`.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user