• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ
未設定

よく使われているワード(クリックで追加)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

なろうブックマーク分析用ツールのPrism+WPFサンプル実装


コミットメタ情報

リビジョン237d5d40225eea9561135640d7467d241705092c (tree)
日時2022-08-06 15:31:53
作者yoshy <yoshy.org.bitbucket@gz.j...>
コミッターyoshy

ログメッセージ

[ADD] ブックマーク詳細リストをカテゴリNoごとにキャッシュする機能を追加

変更サマリ

差分

--- a/30Adaptor/AdaptorModule.cs
+++ b/30Adaptor/AdaptorModule.cs
@@ -58,7 +58,7 @@ namespace TestNarou.Adaptor
5858 containerRegistry.RegisterSingleton<IBookmarkViewModel, BookmarkViewModel>();
5959
6060 containerRegistry.RegisterSingleton<IBookmarkCategoryViewModel, BookmarkCategoryViewModel>();
61- containerRegistry.RegisterSingleton<IBookmarkDetailListViewModel, BookmarkDetailListViewModel>();
61+ containerRegistry.Register<IBookmarkDetailListViewModel, BookmarkDetailListViewModel>();
6262
6363 //
6464 // Translators
--- a/30Adaptor/Boundary/Controller/IAppWindowController.cs
+++ b/30Adaptor/Boundary/Controller/IAppWindowController.cs
@@ -1,4 +1,6 @@
11 using CleanAuLait.Adaptor.Boundary.Controller;
2+using TestNarou.Adaptor.Boundary.Gateway.ViewModel;
3+using TestNarou.Domain.Model.Entity;
24
35 namespace TestNarou.Adaptor.Boundary.Controller
46 {
@@ -6,5 +8,10 @@ namespace TestNarou.Adaptor.Boundary.Controller
68 {
79 void NavigateLoginFormView();
810 void NavigateBookmarkView();
11+
12+ bool ContainsCategoryNo(int categoryNo);
13+ void RegisterDetailList(int categoryNo, IBookmarkDetailListViewModel vm);
14+ void NavigateBookmarkListView(int index);
15+ void SynchronizeBookmarkDetailList(int categoryNo, BookmarkDetailList detailList);
916 }
1017 }
--- a/30Adaptor/Boundary/Gateway/ViewModel/IBookmarkDetailListViewModel.cs
+++ b/30Adaptor/Boundary/Gateway/ViewModel/IBookmarkDetailListViewModel.cs
@@ -1,4 +1,5 @@
11 using Reactive.Bindings;
2+using System;
23 using System.ComponentModel;
34 using TestNarou.Adaptor.Boundary.Gateway.ViewModel.Child;
45 using TestNarou.Domain.Model.Entity;
@@ -7,6 +8,10 @@ namespace TestNarou.Adaptor.Boundary.Gateway.ViewModel
78 {
89 public interface IBookmarkDetailListViewModel
910 {
11+ internal const string CATEGORY_NO_KEY = "CATEGORY_NO";
12+
13+ internal static readonly Uri URI = new("BookmarkDetailListView", UriKind.Relative);
14+
1015 ReactiveCommand CommandOpenBookmark { get; }
1116 ICollectionView Rows { get; }
1217 BookmarkDetailList Source { get; }
--- a/30Adaptor/Controller/AppWindowController.cs
+++ b/30Adaptor/Controller/AppWindowController.cs
@@ -1,15 +1,25 @@
11 using CleanAuLait.Adaptor.Boundary.Controller;
22 using CleanAuLait.Adaptor.Controller;
33 using CleanAuLait.Core.DI;
4+using CleanAuLait.Core.Log;
5+using NLog;
46 using Prism.Regions;
7+using System.Collections.Generic;
58 using TestNarou.Adaptor.Boundary.Controller;
69 using TestNarou.Adaptor.Boundary.Gateway.ViewModel;
10+using TestNarou.Domain.Model.Entity;
11+using TestNarou.UseCase.Request;
712
813 namespace TestNarou.Adaptor.Controller
914 {
1015 internal class AppWindowController
1116 : AbstractWindowController, IAppWindowController
1217 {
18+ private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
19+
20+ private IDictionary<int, IBookmarkDetailListViewModel> CategoryNoMap { get; }
21+ = new Dictionary<int, IBookmarkDetailListViewModel>();
22+
1323 private readonly IRegionManager rm;
1424
1525 public AppWindowController(
@@ -23,14 +33,66 @@ namespace TestNarou.Adaptor.Controller
2333
2434 public void NavigateLoginFormView()
2535 {
36+ logger.Trace("NavigateLoginFormView");
37+
2638 this.rm.RequestNavigate(
2739 IMainWindowViewModel.REGION_NAME, ILoginFormViewModel.URI);
2840 }
2941
3042 public void NavigateBookmarkView()
3143 {
44+ logger.Trace("NavigateBookmarkView");
45+
3246 this.rm.RequestNavigate(
3347 IMainWindowViewModel.REGION_NAME, IBookmarkViewModel.URI);
3448 }
49+
50+ public bool ContainsCategoryNo(int categoryNo)
51+ {
52+ return this.CategoryNoMap.ContainsKey(categoryNo);
53+ }
54+
55+ public void RegisterDetailList(int categoryNo, IBookmarkDetailListViewModel vm)
56+ {
57+ logger.Trace("RegisterDetailList: categoryNo {0}, vm {1}", categoryNo, vm.ToHashString());
58+
59+ this.CategoryNoMap.Add(categoryNo, vm);
60+ }
61+
62+ public void NavigateBookmarkListView(int categoryNo)
63+ {
64+ logger.Trace("NavigateBookmarkListView: categoryNo {0}", categoryNo);
65+
66+ bool needsRefresh = !CategoryNoMap.ContainsKey(categoryNo);
67+
68+ NavigationParameters args = new()
69+ {
70+ { IBookmarkDetailListViewModel.CATEGORY_NO_KEY, categoryNo }
71+ };
72+
73+ this.rm.RequestNavigate(
74+ IBookmarkViewModel.DETAIL_LIST_REGION_NAME, IBookmarkDetailListViewModel.URI, args);
75+
76+ if (!needsRefresh)
77+ {
78+ return;
79+ }
80+
81+ NarouRefreshBookmarkDetailListRequest req = new(categoryNo);
82+
83+ _ = Execute(req);
84+ }
85+
86+ public void SynchronizeBookmarkDetailList(int categoryNo, BookmarkDetailList detailList)
87+ {
88+ logger.Trace("SynchronizeBookmarkDetailList: categoryNo {0}", categoryNo);
89+
90+ if (!CategoryNoMap.TryGetValue(categoryNo, out IBookmarkDetailListViewModel vm))
91+ {
92+ return;
93+ }
94+
95+ vm.SynchronizeWith(detailList);
96+ }
3597 }
3698 }
--- a/30Adaptor/Gateway/ViewModel/BookmarkDetailListViewModel.cs
+++ b/30Adaptor/Gateway/ViewModel/BookmarkDetailListViewModel.cs
@@ -1,12 +1,15 @@
11 using NLog;
22 using ObservableCollections;
33 using Prism.Navigation;
4+using Prism.Regions;
45 using Reactive.Bindings;
56 using Reactive.Bindings.Extensions;
7+using System.Collections.Generic;
68 using System.ComponentModel;
79 using System.Diagnostics;
810 using System.Reactive.Disposables;
911 using System.Windows.Data;
12+using TestNarou.Adaptor.Boundary.Controller;
1013 using TestNarou.Adaptor.Boundary.Gateway.ViewModel;
1114 using TestNarou.Adaptor.Boundary.Gateway.ViewModel.Child;
1215 using TestNarou.Adaptor.Translator;
@@ -16,13 +19,11 @@ using TestNarou.Domain.Model.Entity.Child;
1619 namespace TestNarou.Adaptor.Gateway.ViewModel
1720 {
1821 internal class BookmarkDetailListViewModel
19- : IBookmarkDetailListViewModel, INotifyPropertyChanged, IDestructible
22+ : IBookmarkDetailListViewModel, INotifyPropertyChanged, INavigationAware, IDestructible
2023 {
2124 private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
2225
23-#pragma warning disable CS0067
2426 public event PropertyChangedEventHandler PropertyChanged;
25-#pragma warning restore CS0067
2627
2728 public ReactiveCommand CommandOpenBookmark { get; }
2829
@@ -30,16 +31,25 @@ namespace TestNarou.Adaptor.Gateway.ViewModel
3031
3132 public ICollectionView Rows { get; private set; } = null;
3233
34+ private IAppWindowController WindowController { get; }
35+
36+ private int CategoryNo { get; set; } = -1;
37+
3338 private ISynchronizedListView<BookmarkDetailListRow, IBookmarkDetailListRowViewModel> internalRows;
3439 private IBookmarkDetailListRowViewModel selectedRow;
3540
3641 private readonly IBookmarkDetailListRowViewModelTranslator vmTranslator;
3742 private readonly CompositeDisposable disposables = new();
3843
39- public BookmarkDetailListViewModel(IBookmarkDetailListRowViewModelTranslator vmTranslator)
44+ public BookmarkDetailListViewModel(
45+ IAppWindowController wc,
46+ IBookmarkDetailListRowViewModelTranslator vmTranslator)
4047 {
48+ this.WindowController = wc;
4149 this.vmTranslator = vmTranslator;
42- this.CommandOpenBookmark = new ReactiveCommand().WithSubscribe(OpenBookmark).AddTo(disposables);
50+
51+ this.CommandOpenBookmark = new ReactiveCommand()
52+ .WithSubscribe(OpenBookmark).AddTo(disposables);
4353 }
4454
4555 public void NotifySelectedItemChanged(
@@ -90,5 +100,51 @@ namespace TestNarou.Adaptor.Gateway.ViewModel
90100 {
91101 this.disposables.Dispose();
92102 }
103+
104+ #region INavigationAware
105+
106+ public bool IsNavigationTarget(NavigationContext ctx)
107+ {
108+ int categoryNo = GetCategoryNoFromNavigationContext(ctx);
109+
110+ //logger.Trace("IsNavigationTarget: to:{0} <> this:{1}", categoryNo, this.CategoryNo);
111+
112+ if (this.CategoryNo == -1 && !WindowController.ContainsCategoryNo(categoryNo))
113+ {
114+ //logger.Trace("IsNavigationTarget: new Category");
115+ return true;
116+ }
117+
118+ bool isTarget = categoryNo == this.CategoryNo;
119+
120+ //logger.Trace("IsNavigationTarget: isTarget {0}", isTarget);
121+
122+ return isTarget;
123+ }
124+
125+ public void OnNavigatedTo(NavigationContext ctx)
126+ {
127+ int categoryNo = GetCategoryNoFromNavigationContext(ctx);
128+
129+ //logger.Trace("OnNavigatedTo: to:{0} -> this:{1}", categoryNo, this.CategoryNo);
130+
131+ if (this.CategoryNo == -1)
132+ {
133+ this.CategoryNo = categoryNo;
134+ this.WindowController.RegisterDetailList(this.CategoryNo, this);
135+ }
136+ }
137+
138+ public void OnNavigatedFrom(NavigationContext ctx)
139+ {
140+ // NOP
141+ }
142+
143+ private static int GetCategoryNoFromNavigationContext(NavigationContext ctx)
144+ {
145+ return ctx.Parameters.GetValue<int>(IBookmarkDetailListViewModel.CATEGORY_NO_KEY);
146+ }
147+
148+ #endregion
93149 }
94150 }
--- a/30Adaptor/Gateway/ViewModel/BookmarkViewModel.cs
+++ b/30Adaptor/Gateway/ViewModel/BookmarkViewModel.cs
@@ -1,52 +1,24 @@
1-using NLog;
2-using Prism.Navigation;
3-using Prism.Regions;
1+using Prism.Navigation;
42 using System.ComponentModel;
53 using System.Reactive.Disposables;
64 using TestNarou.Adaptor.Boundary.Gateway.ViewModel;
75
86 namespace TestNarou.Adaptor.Gateway.ViewModel
97 {
10- internal class BookmarkViewModel : INavigationAware, IBookmarkViewModel, IDestructible
8+ internal class BookmarkViewModel : IBookmarkViewModel, IDestructible
119 {
12- private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
10+ //private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
1311
1412 #pragma warning disable CS0067
1513 public event PropertyChangedEventHandler PropertyChanged;
1614 #pragma warning restore CS0067
1715
18- private readonly IRegionManager rm;
19-
2016 private readonly CompositeDisposable disposables = new();
2117
22- public BookmarkViewModel(IRegionManager rm)
23- {
24- this.rm = rm;
25- }
26-
2718 public void Destroy()
2819 {
2920 this.disposables.Dispose();
3021 }
3122
32- #region INavigationAware
33-
34- public bool IsNavigationTarget(NavigationContext ctx)
35- {
36- logger.Trace("BookmarkViewModel: IsNavigationTarget {0}", ctx.Uri);
37-
38- return true;
39- }
40-
41- public void OnNavigatedFrom(NavigationContext ctx)
42- {
43- // NOP
44- }
45-
46- public void OnNavigatedTo(NavigationContext ctx)
47- {
48- }
49-
50- #endregion
5123 }
5224 }
--- a/30Adaptor/Gateway/ViewModel/Child/BookmarkCategoryRowViewModel.cs
+++ b/30Adaptor/Gateway/ViewModel/Child/BookmarkCategoryRowViewModel.cs
@@ -41,9 +41,7 @@ namespace TestNarou.Adaptor.Gateway.ViewModel.Child
4141 return;
4242 }
4343
44- NarouRefreshBookmarkDetailListRequest req = new(this.Index);
45-
46- _ = this.Parent.WindowController.Execute(req);
44+ this.Parent.WindowController.NavigateBookmarkListView(this.Index);
4745 }
4846
4947 protected virtual void Dispose(bool disposing)
--- a/30Adaptor/Gateway/ViewModel/LoginFormViewModel.cs
+++ b/30Adaptor/Gateway/ViewModel/LoginFormViewModel.cs
@@ -56,16 +56,8 @@ namespace TestNarou.Adaptor.Gateway.ViewModel
5656 return;
5757 }
5858
59- NarouRefreshBookmarkDetailListRequest req2 = new(1);
60-
61- var res2 = this.wc.Execute(req2);
62-
63- if (res2.IsAborted)
64- {
65- return;
66- }
67-
6859 this.wc.NavigateBookmarkView();
60+ this.wc.NavigateBookmarkListView(1);
6961 }
7062
7163 #endregion
--- a/30Adaptor/Presenter/NarouRefreshBookmarkDetailListPresenter.cs
+++ b/30Adaptor/Presenter/NarouRefreshBookmarkDetailListPresenter.cs
@@ -1,4 +1,5 @@
1-using TestNarou.Adaptor.Boundary.Gateway.ViewModel;
1+using TestNarou.Adaptor.Boundary.Controller;
2+using TestNarou.Adaptor.Boundary.Gateway.ViewModel;
23 using TestNarou.UseCase.Boundary.Presenter;
34 using TestNarou.UseCase.Request;
45 using TestNarou.UseCase.Response;
@@ -8,12 +9,13 @@ namespace TestNarou.Adaptor.Presenter
89 internal class NarouRefreshBookmarkDetailListPresenter
910 : INarouRefreshBookmarkDetailListPresenter
1011 {
11- private readonly IBookmarkDetailListViewModel vm;
12+ private readonly IAppWindowController wc;
1213
1314 public NarouRefreshBookmarkDetailListPresenter(
14- IBookmarkDetailListViewModel vm)
15+ IAppWindowController wc
16+ )
1517 {
16- this.vm = vm;
18+ this.wc = wc;
1719 }
1820
1921 public NarouRefreshBookmarkDetailListResponse Present(
@@ -21,7 +23,7 @@ namespace TestNarou.Adaptor.Presenter
2123 NarouRefreshBookmarkDetailListResponse res
2224 )
2325 {
24- this.vm.SynchronizeWith(res.DetailList);
26+ this.wc.SynchronizeBookmarkDetailList(req.CategoryNo, res.DetailList);
2527
2628 return res;
2729 }
--- a/40OuterEdge/OuterEdgeModule.cs
+++ b/40OuterEdge/OuterEdgeModule.cs
@@ -25,6 +25,8 @@ namespace TestNarou.OuterEdge
2525 containerRegistry.RegisterForNavigation<LoginFormView>();
2626 containerRegistry.RegisterForNavigation<BookmarkView>();
2727
28+ containerRegistry.RegisterForNavigation<BookmarkDetailListView>();
29+
2830 ///
2931 /// Repositories
3032 ///
--- a/40OuterEdge/Repository/API/HttpClientHelper.cs
+++ b/40OuterEdge/Repository/API/HttpClientHelper.cs
@@ -74,8 +74,8 @@ namespace TestNarou.OuterEdge.Repository.API
7474
7575 var response = await httpClient.SendAsync(request).ConfigureAwait(false);
7676
77- ShowResponseHeaders(response);
78- ShowCookies();
77+ //ShowResponseHeaders(response);
78+ //ShowCookies();
7979
8080 logger.Trace("StatusCode: {0}", response.StatusCode);
8181
@@ -99,8 +99,8 @@ namespace TestNarou.OuterEdge.Repository.API
9999
100100 var response = await httpClient.SendAsync(request).ConfigureAwait(false);
101101
102- ShowResponseHeaders(response);
103- ShowCookies();
102+ //ShowResponseHeaders(response);
103+ //ShowCookies();
104104
105105 logger.Trace("StatusCode: {0}", response.StatusCode);
106106