From 5806db2f17376b40418a1b7bb30fe031fe795ff2 Mon Sep 17 00:00:00 2001 From: thangchung Date: Tue, 10 Oct 2017 18:42:56 +0700 Subject: [PATCH] refactor code (cont.) --- .../EfRepositoryExtensions.cs | 12 ------ .../ListOutPostByBlogPresenter.cs | 40 +++++++++++++++++ .../Posts/PostPublicApiController.cs | 43 +++++++++++++++++++ src/Hosts/BlogCore.Api/Startup.cs | 5 +++ .../PostPublicApiController.cs | 28 +----------- .../ListOutPostByBlogResponse.cs | 6 +++ src/Web/public/index.html | 1 - .../App => components/Layout}/AdminLayout.js | 29 +++++++------ .../App => components/Layout}/PublicLayout.js | 15 ++++--- .../css => src/components/Layout}/blog.css | 0 .../src/{auth => components}/Restricted.js | 0 src/Web/src/index.js | 4 +- 12 files changed, 123 insertions(+), 60 deletions(-) create mode 100644 src/Hosts/BlogCore.Api/Posts/ListOutPostByBlog/ListOutPostByBlogPresenter.cs create mode 100644 src/Hosts/BlogCore.Api/Posts/PostPublicApiController.cs rename src/Web/src/{containers/App => components/Layout}/AdminLayout.js (62%) rename src/Web/src/{containers/App => components/Layout}/PublicLayout.js (79%) rename src/Web/{public/css => src/components/Layout}/blog.css (100%) rename src/Web/src/{auth => components}/Restricted.js (100%) diff --git a/src/Framework/BlogCore.Infrastructure.EfCore/EfRepositoryExtensions.cs b/src/Framework/BlogCore.Infrastructure.EfCore/EfRepositoryExtensions.cs index 6420a4f..2387255 100644 --- a/src/Framework/BlogCore.Infrastructure.EfCore/EfRepositoryExtensions.cs +++ b/src/Framework/BlogCore.Infrastructure.EfCore/EfRepositoryExtensions.cs @@ -1,7 +1,6 @@ using BlogCore.Core; using Microsoft.EntityFrameworkCore; using System; -using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reactive.Linq; @@ -96,16 +95,5 @@ private static async Task> GetDataAsync(totalRecord, totalPages, results); } - - public static IEnumerable GetPagingDataWithConditionStream( - this IReadOnlyList source, - Criterion criterion, - Func selector) - where TEntity : EntityBase - { - return source.Skip(criterion.CurrentPage * criterion.PageSize) - .Take(criterion.PageSize) - .Select(selector); - } } } \ No newline at end of file diff --git a/src/Hosts/BlogCore.Api/Posts/ListOutPostByBlog/ListOutPostByBlogPresenter.cs b/src/Hosts/BlogCore.Api/Posts/ListOutPostByBlog/ListOutPostByBlogPresenter.cs new file mode 100644 index 0000000..006acf0 --- /dev/null +++ b/src/Hosts/BlogCore.Api/Posts/ListOutPostByBlog/ListOutPostByBlogPresenter.cs @@ -0,0 +1,40 @@ +using BlogCore.AccessControlContext.Domain; +using BlogCore.Core; +using BlogCore.PostContext.UseCases.ListOutPostByBlog; +using System.Collections.Generic; +using System.Linq; + +namespace BlogCore.Api.Posts.ListOutPostByBlog +{ + public class ListOutPostByBlogPresenter + { + private readonly IUserRepository _userRepository; + + public ListOutPostByBlogPresenter(IUserRepository userRepository) + { + _userRepository = userRepository; + } + + public PaginatedItem Transform(PaginatedItem input) + { + var authors = input.Items + .Select(x => x.Author.Id) + .Distinct() + .Select(x => _userRepository.GetByIdAsync(x).Result) + .ToList(); + + var posts = input.Items + .Select(x => + { + var author = authors.FirstOrDefault(y => y.Id == x.Author.Id.ToString()); + return x.SetAuthor(new ListOutPostByBlogUserResponse(author.Id, author.FamilyName, author.GivenName)); + }) + .ToList(); + + return new PaginatedItem( + input.TotalItems, + (int)input.TotalPages, + posts); + } + } +} diff --git a/src/Hosts/BlogCore.Api/Posts/PostPublicApiController.cs b/src/Hosts/BlogCore.Api/Posts/PostPublicApiController.cs new file mode 100644 index 0000000..9749580 --- /dev/null +++ b/src/Hosts/BlogCore.Api/Posts/PostPublicApiController.cs @@ -0,0 +1,43 @@ +using BlogCore.Api.Posts.ListOutPostByBlog; +using BlogCore.Core; +using BlogCore.Core.Helpers; +using BlogCore.PostContext.Domain; +using BlogCore.PostContext.UseCases.ListOutPostByBlog; +using MediatR; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Threading.Tasks; + +namespace BlogCore.Api.Posts +{ + [Route("api/public/blogs")] + public class PostPublicApiController : Controller + { + private readonly IMediator _eventAggregator; + private readonly ListOutPostByBlogPresenter _listOutPostByBlogPresenter; + + public PostPublicApiController(IMediator eventAggregator, ListOutPostByBlogPresenter listOutPostByBlogPresenter) + { + _eventAggregator = eventAggregator; + _listOutPostByBlogPresenter = listOutPostByBlogPresenter; + } + + [HttpGet("{blogId:guid}/posts")] + public async Task> GetForBlog(Guid blogId, [FromQuery] int page) + { + var postResult = await _eventAggregator.Send(new ListOutPostByBlogRequest(blogId, page <= 0 ? 1 : page)); + return _listOutPostByBlogPresenter.Transform(postResult); + } + + [HttpGet("{blogId:guid}/posts/{postId:guid}")] + public Post Get(Guid blogId, Guid postId) + { + return Post.CreateInstance( + new BlogId(IdHelper.GenerateId("34C96712-2CDF-4E79-9E2F-768CB68DD552")), + "sample title", + "sample excerpt", + "sample body", + new AuthorId(IdHelper.GenerateId("4B5F26CE-DF97-494C-B747-121D215847D8"))); + } + } +} diff --git a/src/Hosts/BlogCore.Api/Startup.cs b/src/Hosts/BlogCore.Api/Startup.cs index 6914b02..538f497 100644 --- a/src/Hosts/BlogCore.Api/Startup.cs +++ b/src/Hosts/BlogCore.Api/Startup.cs @@ -1,6 +1,8 @@ #region libs using BlogCore.AccessControl; +using BlogCore.Api.Posts; +using BlogCore.Api.Posts.ListOutPostByBlog; using BlogCore.BlogContext; using BlogCore.BlogContext.Infrastructure; using BlogCore.Core; @@ -60,6 +62,9 @@ public IServiceProvider ConfigureServices(IServiceCollection services) services.AddIdentityServerForBlog(OnTokenValidated); + // register presenters + services.AddScoped(); + return services.InitServices(RegisteredAssemblies(), Configuration); } diff --git a/src/Modules/BlogCore.PostContext/PostPublicApiController.cs b/src/Modules/BlogCore.PostContext/PostPublicApiController.cs index 942077a..eddd5dc 100644 --- a/src/Modules/BlogCore.PostContext/PostPublicApiController.cs +++ b/src/Modules/BlogCore.PostContext/PostPublicApiController.cs @@ -1,15 +1,9 @@ -using BlogCore.Core; -using BlogCore.Core.Helpers; -using BlogCore.PostContext.Domain; -using BlogCore.PostContext.UseCases.ListOutPostByBlog; -using MediatR; +using MediatR; using Microsoft.AspNetCore.Mvc; -using System; -using System.Threading.Tasks; namespace BlogCore.PostContext { - [Route("api/public/blog")] + [Route("api/public/posts")] public class PostPublicApiController : Controller { private readonly IMediator _eventAggregator; @@ -18,23 +12,5 @@ public PostPublicApiController(IMediator eventAggregator) { _eventAggregator = eventAggregator; } - - [HttpGet("{blogId:guid}/posts")] - public async Task> GetForBlog(Guid blogId, [FromQuery] int page) - { - if (page <= 0) page = 1; - return await _eventAggregator.Send(new ListOutPostByBlogRequest(blogId, page)); - } - - [HttpGet("{blogId:guid}/posts/{postId:guid}")] - public Domain.Post Get(Guid blogId, Guid postId) - { - return Domain.Post.CreateInstance( - new BlogId(IdHelper.GenerateId("34C96712-2CDF-4E79-9E2F-768CB68DD552")), - "sample title", - "sample excerpt", - "sample body", - new AuthorId(IdHelper.GenerateId("4B5F26CE-DF97-494C-B747-121D215847D8"))); - } } } diff --git a/src/Modules/BlogCore.PostContext/UseCases/ListOutPostByBlog/ListOutPostByBlogResponse.cs b/src/Modules/BlogCore.PostContext/UseCases/ListOutPostByBlog/ListOutPostByBlogResponse.cs index 6db305a..47a28a1 100644 --- a/src/Modules/BlogCore.PostContext/UseCases/ListOutPostByBlog/ListOutPostByBlogResponse.cs +++ b/src/Modules/BlogCore.PostContext/UseCases/ListOutPostByBlog/ListOutPostByBlogResponse.cs @@ -31,5 +31,11 @@ public ListOutPostByBlogResponse( public ListOutPostByBlogUserResponse Author { get; private set; } public List Tags { get; private set; } public DateTime CreatedAt { get; private set; } + + public ListOutPostByBlogResponse SetAuthor(ListOutPostByBlogUserResponse author) + { + Author = author; + return this; + } } } \ No newline at end of file diff --git a/src/Web/public/index.html b/src/Web/public/index.html index 7328ab4..bb3f920 100644 --- a/src/Web/public/index.html +++ b/src/Web/public/index.html @@ -21,7 +21,6 @@ -
diff --git a/src/Web/src/containers/App/AdminLayout.js b/src/Web/src/components/Layout/AdminLayout.js similarity index 62% rename from src/Web/src/containers/App/AdminLayout.js rename to src/Web/src/components/Layout/AdminLayout.js index d2c2b5f..9ff7e03 100644 --- a/src/Web/src/containers/App/AdminLayout.js +++ b/src/Web/src/components/Layout/AdminLayout.js @@ -7,10 +7,10 @@ import Header from "../../components/Header"; import Footer from "../../components/Footer"; // our containers -import Restricted from "../../auth/Restricted"; -import DashboardPage from "../Dashboard/Index"; -import PostManagementPage from "../Post/PostManagement"; -import ProfileSettingPage from "../Setting/ProfileSetting"; +import Restricted from "../Restricted"; +import DashboardContainer from "../../containers/Dashboard/Index"; +import PostManagementContainer from "../../containers/Post/PostManagement"; +import ProfileSettingContainer from "../../containers/Setting/ProfileSetting"; export default class AdminLayout extends Component { render() { @@ -26,28 +26,31 @@ export default class AdminLayout extends Component { exact path={`${match.url}/dashboard`} key="dashboard" - render={routeProps => + render={routeProps => ( - {React.createElement(DashboardPage)} - } + {React.createElement(DashboardContainer)} + + )} /> + render={routeProps => ( - {React.createElement(PostManagementPage)} - } + {React.createElement(PostManagementContainer)} + + )} /> + render={routeProps => ( - {React.createElement(ProfileSettingPage)} - } + {React.createElement(ProfileSettingContainer)} + + )} /> diff --git a/src/Web/src/containers/App/PublicLayout.js b/src/Web/src/components/Layout/PublicLayout.js similarity index 79% rename from src/Web/src/containers/App/PublicLayout.js rename to src/Web/src/components/Layout/PublicLayout.js index 22a6974..5ede80e 100644 --- a/src/Web/src/containers/App/PublicLayout.js +++ b/src/Web/src/components/Layout/PublicLayout.js @@ -7,9 +7,12 @@ import Footer from "../../components/Footer"; import About from "../../components/About"; // our containers -import HomePage from "../Home/Index"; -import BlogPage from "../Blog/Index"; -import PostDetailPage from "../Post/PostDetail"; +import HomeContainer from "../../containers/Home/Index"; +import BlogContainer from "../../containers/Blog/Index"; +import PostDetailContainer from "../../containers/Post/PostDetail"; + +// style +import "./blog.css"; export default class PublicLayout extends Component { render() { @@ -25,19 +28,19 @@ export default class PublicLayout extends Component { exact path={`${match.url}`} key="index" - component={HomePage} + component={HomeContainer} /> diff --git a/src/Web/public/css/blog.css b/src/Web/src/components/Layout/blog.css similarity index 100% rename from src/Web/public/css/blog.css rename to src/Web/src/components/Layout/blog.css diff --git a/src/Web/src/auth/Restricted.js b/src/Web/src/components/Restricted.js similarity index 100% rename from src/Web/src/auth/Restricted.js rename to src/Web/src/components/Restricted.js diff --git a/src/Web/src/index.js b/src/Web/src/index.js index 62b3361..eb950df 100644 --- a/src/Web/src/index.js +++ b/src/Web/src/index.js @@ -12,8 +12,8 @@ import { ConnectedRouter } from "react-router-redux"; // import getRoutes from "./routes"; import createStore, { routerHistory } from "./redux/configureStore"; import userManager from "./utils/userManager"; -import PublicLayout from "./containers/App/PublicLayout"; -import AdminLayout from "./containers/App/AdminLayout"; +import PublicLayout from "./components/Layout/PublicLayout"; +import AdminLayout from "./components/Layout/AdminLayout"; import Login from "./containers/Login/Index"; import Callback from "./containers/Login/Callback";