From 97bdeb4e3883405ae1a57c025c915a26c9cceced Mon Sep 17 00:00:00 2001 From: Julien Leicher Date: Fri, 4 Dec 2020 16:57:04 +0100 Subject: [PATCH] add list links query and display it in the links homepage (#13) --- .vscode/launch.json | 36 ++++++++++++++++ .vscode/tasks.json | 42 +++++++++++++++++++ Application/Application.csproj | 1 + Application/IDbContext.cs | 13 ++++++ Application/ListLinks/LinkDTO.cs | 11 +++++ Application/ListLinks/ListLinksQuery.cs | 9 ++++ .../ListLinks/ListLinksQueryHandler.cs | 30 +++++++++++++ Apps/Website/Controllers/LinksController.cs | 4 +- Apps/Website/Startup.cs | 2 + Apps/Website/Views/Links/Index.cshtml | 9 +++- Infrastructure/HNDbContext.cs | 5 ++- Infrastructure/Infrastructure.csproj | 2 +- hn-dotnet.sln | 33 +++++++++++++++ 13 files changed, 191 insertions(+), 6 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json create mode 100644 Application/IDbContext.cs create mode 100644 Application/ListLinks/LinkDTO.cs create mode 100644 Application/ListLinks/ListLinksQuery.cs create mode 100644 Application/ListLinks/ListLinksQueryHandler.cs diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..6691e2c --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,36 @@ +{ + // Use IntelliSense to find out which attributes exist for C# debugging + // Use hover for the description of the existing attributes + // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md + "version": "0.2.0", + "configurations": [ + { + "name": ".NET Core Launch (web)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + // If you have changed target frameworks, make sure to update the program path. + "program": "${workspaceFolder}/Apps/Website/bin/Debug/net5.0/Website.dll", + "args": [], + "cwd": "${workspaceFolder}/Apps/Website", + "stopAtEntry": false, + // Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser + "serverReadyAction": { + "action": "openExternally", + "pattern": "\\bNow listening on:\\s+(https?://\\S+)" + }, + "env": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "sourceFileMap": { + "/Views": "${workspaceFolder}/Views" + } + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach", + "processId": "${command:pickProcess}" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..3f1f4ce --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,42 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/Apps/Website/Website.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/Apps/Website/Website.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "${workspaceFolder}/Apps/Website/Website.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/Application/Application.csproj b/Application/Application.csproj index 5c96336..6a1f18f 100644 --- a/Application/Application.csproj +++ b/Application/Application.csproj @@ -6,6 +6,7 @@ + diff --git a/Application/IDbContext.cs b/Application/IDbContext.cs new file mode 100644 index 0000000..f67beff --- /dev/null +++ b/Application/IDbContext.cs @@ -0,0 +1,13 @@ +using HN.Domain; +using Microsoft.EntityFrameworkCore; + +namespace HN.Application +{ + /// + /// Interface permettant l'accès aux DbSet pour toute la partie Query. + /// + public interface IDbContext + { + DbSet Links { get; } + } +} diff --git a/Application/ListLinks/LinkDTO.cs b/Application/ListLinks/LinkDTO.cs new file mode 100644 index 0000000..f1d1745 --- /dev/null +++ b/Application/ListLinks/LinkDTO.cs @@ -0,0 +1,11 @@ +using System; + +namespace HN.Application +{ + public sealed class LinkDTO + { + public Guid Id { get; set; } + public string Url { get; set; } + public DateTime CreatedAt { get; set; } + } +} \ No newline at end of file diff --git a/Application/ListLinks/ListLinksQuery.cs b/Application/ListLinks/ListLinksQuery.cs new file mode 100644 index 0000000..3a15de6 --- /dev/null +++ b/Application/ListLinks/ListLinksQuery.cs @@ -0,0 +1,9 @@ +using MediatR; + +namespace HN.Application +{ + public sealed class ListLinksQuery : IRequest + { + + } +} \ No newline at end of file diff --git a/Application/ListLinks/ListLinksQueryHandler.cs b/Application/ListLinks/ListLinksQueryHandler.cs new file mode 100644 index 0000000..a853eae --- /dev/null +++ b/Application/ListLinks/ListLinksQueryHandler.cs @@ -0,0 +1,30 @@ +using System.Threading; +using System.Linq; +using System.Threading.Tasks; +using MediatR; + +namespace HN.Application +{ + public sealed class ListLinksQueryHandler : IRequestHandler + { + private readonly IDbContext _context; + + public ListLinksQueryHandler(IDbContext context) + { + _context = context; + } + + public Task Handle(ListLinksQuery request, CancellationToken cancellationToken) + { + var links = from link in _context.Links + select new LinkDTO + { + Id = link.Id, + Url = link.Url, + CreatedAt = link.CreatedAt + }; + + return Task.FromResult(links.ToArray()); + } + } +} \ No newline at end of file diff --git a/Apps/Website/Controllers/LinksController.cs b/Apps/Website/Controllers/LinksController.cs index 07ad3ee..0bcb5a8 100644 --- a/Apps/Website/Controllers/LinksController.cs +++ b/Apps/Website/Controllers/LinksController.cs @@ -14,9 +14,9 @@ namespace Website.Controllers _bus = bus; } - public IActionResult Index() + public async Task Index() { - return View(); + return View(await _bus.Send(new ListLinksQuery())); } public IActionResult Create() diff --git a/Apps/Website/Startup.cs b/Apps/Website/Startup.cs index 1078bec..9c75581 100644 --- a/Apps/Website/Startup.cs +++ b/Apps/Website/Startup.cs @@ -1,3 +1,4 @@ +using HN.Application; using HN.Domain; using HN.Infrastructure; using MediatR; @@ -23,6 +24,7 @@ namespace Website public void ConfigureServices(IServiceCollection services) { services.AddDbContext(options => options.UseSqlite(Configuration.GetConnectionString("Default"))); + services.AddScoped(); services.AddScoped(); services.AddMediatR(typeof(HN.Application.AddLinkCommand)); services.AddControllersWithViews(); diff --git a/Apps/Website/Views/Links/Index.cshtml b/Apps/Website/Views/Links/Index.cshtml index fe106d2..9396920 100644 --- a/Apps/Website/Views/Links/Index.cshtml +++ b/Apps/Website/Views/Links/Index.cshtml @@ -1,7 +1,14 @@ +@model HN.Application.LinkDTO[] @{ ViewData["Title"] = "Latest Links"; } Post a new super duber link -

Here are the links

\ No newline at end of file +

Here are the links

+
    + @foreach (var link in Model) + { +
  • @link.Url created at @link.CreatedAt.ToLocalTime()
  • + } +
\ No newline at end of file diff --git a/Infrastructure/HNDbContext.cs b/Infrastructure/HNDbContext.cs index 5414399..df3fc32 100644 --- a/Infrastructure/HNDbContext.cs +++ b/Infrastructure/HNDbContext.cs @@ -1,9 +1,10 @@ -using HN.Domain; +using HN.Application; +using HN.Domain; using Microsoft.EntityFrameworkCore; namespace HN.Infrastructure { - public sealed class HNDbContext : DbContext + public sealed class HNDbContext : DbContext, IDbContext { public DbSet Links { get; set; } diff --git a/Infrastructure/Infrastructure.csproj b/Infrastructure/Infrastructure.csproj index e7df2a7..5856d17 100644 --- a/Infrastructure/Infrastructure.csproj +++ b/Infrastructure/Infrastructure.csproj @@ -1,7 +1,7 @@ - + diff --git a/hn-dotnet.sln b/hn-dotnet.sln index 6126141..ae29231 100644 --- a/hn-dotnet.sln +++ b/hn-dotnet.sln @@ -7,6 +7,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Domain", "Domain\Domain.csp EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Application", "Application\Application.csproj", "{2993DFBE-7A6D-408B-AC94-C8C7B020C685}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Infrastructure", "Infrastructure\Infrastructure.csproj", "{4EBF14D3-A0FF-4F72-92F9-FBEE5474E662}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Apps", "Apps", "{7D23D5C3-15B1-407D-9FE1-E30C3FBBA1A4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Website", "Apps\Website\Website.csproj", "{44842863-BEB0-4718-BBD0-F7640D7AE0D0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -44,5 +50,32 @@ Global {2993DFBE-7A6D-408B-AC94-C8C7B020C685}.Release|x64.Build.0 = Release|Any CPU {2993DFBE-7A6D-408B-AC94-C8C7B020C685}.Release|x86.ActiveCfg = Release|Any CPU {2993DFBE-7A6D-408B-AC94-C8C7B020C685}.Release|x86.Build.0 = Release|Any CPU + {4EBF14D3-A0FF-4F72-92F9-FBEE5474E662}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4EBF14D3-A0FF-4F72-92F9-FBEE5474E662}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4EBF14D3-A0FF-4F72-92F9-FBEE5474E662}.Debug|x64.ActiveCfg = Debug|Any CPU + {4EBF14D3-A0FF-4F72-92F9-FBEE5474E662}.Debug|x64.Build.0 = Debug|Any CPU + {4EBF14D3-A0FF-4F72-92F9-FBEE5474E662}.Debug|x86.ActiveCfg = Debug|Any CPU + {4EBF14D3-A0FF-4F72-92F9-FBEE5474E662}.Debug|x86.Build.0 = Debug|Any CPU + {4EBF14D3-A0FF-4F72-92F9-FBEE5474E662}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4EBF14D3-A0FF-4F72-92F9-FBEE5474E662}.Release|Any CPU.Build.0 = Release|Any CPU + {4EBF14D3-A0FF-4F72-92F9-FBEE5474E662}.Release|x64.ActiveCfg = Release|Any CPU + {4EBF14D3-A0FF-4F72-92F9-FBEE5474E662}.Release|x64.Build.0 = Release|Any CPU + {4EBF14D3-A0FF-4F72-92F9-FBEE5474E662}.Release|x86.ActiveCfg = Release|Any CPU + {4EBF14D3-A0FF-4F72-92F9-FBEE5474E662}.Release|x86.Build.0 = Release|Any CPU + {44842863-BEB0-4718-BBD0-F7640D7AE0D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {44842863-BEB0-4718-BBD0-F7640D7AE0D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {44842863-BEB0-4718-BBD0-F7640D7AE0D0}.Debug|x64.ActiveCfg = Debug|Any CPU + {44842863-BEB0-4718-BBD0-F7640D7AE0D0}.Debug|x64.Build.0 = Debug|Any CPU + {44842863-BEB0-4718-BBD0-F7640D7AE0D0}.Debug|x86.ActiveCfg = Debug|Any CPU + {44842863-BEB0-4718-BBD0-F7640D7AE0D0}.Debug|x86.Build.0 = Debug|Any CPU + {44842863-BEB0-4718-BBD0-F7640D7AE0D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {44842863-BEB0-4718-BBD0-F7640D7AE0D0}.Release|Any CPU.Build.0 = Release|Any CPU + {44842863-BEB0-4718-BBD0-F7640D7AE0D0}.Release|x64.ActiveCfg = Release|Any CPU + {44842863-BEB0-4718-BBD0-F7640D7AE0D0}.Release|x64.Build.0 = Release|Any CPU + {44842863-BEB0-4718-BBD0-F7640D7AE0D0}.Release|x86.ActiveCfg = Release|Any CPU + {44842863-BEB0-4718-BBD0-F7640D7AE0D0}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {44842863-BEB0-4718-BBD0-F7640D7AE0D0} = {7D23D5C3-15B1-407D-9FE1-E30C3FBBA1A4} EndGlobalSection EndGlobal