Created
February 21, 2018 11:04
-
-
Save noxi515/2beaf8cab633fa49aea06c7eea287363 to your computer and use it in GitHub Desktop.
学生向け適当に書いてみたサンプル
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Net.Http; | |
using System.Threading.Tasks; | |
using Newtonsoft.Json; | |
using Prism.Ioc; | |
using Prism.Services; | |
public class SampleData | |
{ | |
public string Prop0 { get; set; } | |
public string Prop1 { get; set; } | |
public string Prop2 { get; set; } | |
} | |
// 1. とりあえずそのまま書いちゃうパターン | |
// 見通し悪いしクラスの責務が混在するので最もよろしくない | |
// 検証する時とかしか書いちゃいけない | |
public class HogeViewModel_01 | |
{ | |
public async void OnInitialize() | |
{ | |
var http = new HttpClient(); | |
var response = await http.GetAsync("http://localhost/pop/team/epic"); | |
response.EnsureSuccessStatusCode(); | |
var result = JsonConvert.DeserializeObject<List<SampleData>>(await response.Content.ReadAsStringAsync()); | |
// TODO なんかする | |
} | |
} | |
// 2. ちょっとクラス分けてみるパターン | |
public class SampleDataService_02 | |
{ | |
public async Task<List<SampleData>> GetAllAsync() | |
{ | |
var http = new HttpClient(); | |
var response = await http.GetAsync("http://localhost/pop/team/epic"); | |
response.EnsureSuccessStatusCode(); | |
return JsonConvert.DeserializeObject<List<SampleData>>(await response.Content.ReadAsStringAsync()); | |
} | |
} | |
public class HogeViewModel_02 | |
{ | |
public async void OnInitialize() | |
{ | |
var service = new SampleDataService_02(); | |
var result = await service.GetAllAsync(); | |
// TODO なんかする | |
} | |
} | |
// 3. ちょっとキャッシュしちゃうパターン | |
// シングルトンっていいよね | |
public class SampleDataService_03 | |
{ | |
public static SampleDataService_03 Instance { get; } = new SampleDataService_03(); | |
private List<SampleData> Cache { get; set; } | |
private SampleDataService_03() | |
{ | |
} | |
public async Task<List<SampleData>> GetAllAsync() | |
{ | |
if (Cache != null) | |
{ | |
return new List<SampleData>(Cache); | |
} | |
var http = new HttpClient(); | |
var response = await http.GetAsync("http://localhost/pop/team/epic"); | |
response.EnsureSuccessStatusCode(); | |
return Cache = JsonConvert.DeserializeObject<List<SampleData>>(await response.Content.ReadAsStringAsync()); | |
} | |
} | |
public class HogeViewModel_03 | |
{ | |
public async void OnInitialize() | |
{ | |
var service = SampleDataService_03.Instance; | |
var result = await service.GetAllAsync(); | |
// TODO なんかする | |
} | |
} | |
// 4. DIコンテナを利用するパターン | |
// DI = Dependency Injection | |
// 必要なオブジェクトの生成と管理をDIライブラリが受け持ってくれるので楽 | |
// 大体はコンストラクタでオブジェクト生成時に受け取る | |
// 渡したサンプルはUnityというDIライブラリが組み込まれているので、ViewModel生成時にDIに登録されているオブジェクト受け取れる | |
// たとえば INavigationService もDIで受け取っているものの一つ | |
public class App_04 | |
{ | |
public void RegisterTypes(IContainerRegistry registry) | |
{ | |
// オブジェクトの生成管理をして欲しいクラスを、管理方法を指定してDIコンテナに登録する | |
registry.RegisterSingleton<SampleDataService_04>(); | |
} | |
} | |
public class SampleDataService_04 | |
{ | |
private List<SampleData> Cache { get; set; } | |
public async Task<List<SampleData>> GetAllAsync() | |
{ | |
if (Cache != null) | |
{ | |
return new List<SampleData>(Cache); | |
} | |
var http = new HttpClient(); | |
var response = await http.GetAsync("http://localhost/pop/team/epic"); | |
response.EnsureSuccessStatusCode(); | |
return Cache = JsonConvert.DeserializeObject<List<SampleData>>(await response.Content.ReadAsStringAsync()); | |
} | |
} | |
public class HogeViewModel_04 | |
{ | |
private SampleDataService_04 Service { get; } | |
public HogeViewModel_04(SampleDataService_04 service) | |
{ | |
Service = service; | |
} | |
public async void OnInitialize() | |
{ | |
var result = await Service.GetAllAsync(); | |
// TODO なんかする | |
} | |
} | |
// 5. ちょっとエラー処理でもするパターン | |
// どんな方法が最も良いのかは長年の謎である | |
// むしろ俺が教えて欲しい | |
public class App_05 | |
{ | |
public void RegisterTypes(IContainerRegistry registry) | |
{ | |
registry.RegisterSingleton<SampleDataService_05>(); | |
registry.RegisterSingleton<ViewModelExceptionHandler>(); | |
} | |
} | |
public class SampleDataService_05 | |
{ | |
private List<SampleData> Cache { get; set; } | |
public async Task<List<SampleData>> GetAllAsync() | |
{ | |
if (Cache != null) | |
{ | |
return new List<SampleData>(Cache); | |
} | |
var http = new HttpClient(); | |
var response = await http.GetAsync("http://localhost/pop/team/epic"); | |
response.EnsureSuccessStatusCode(); | |
return Cache = JsonConvert.DeserializeObject<List<SampleData>>(await response.Content.ReadAsStringAsync()); | |
} | |
} | |
public class HogeViewModel_05 | |
{ | |
private SampleDataService_05 Service { get; } | |
private ViewModelExceptionHandler ErrorHandler { get; } | |
public HogeViewModel_05(SampleDataService_05 service, ViewModelExceptionHandler errorHandler) | |
{ | |
Service = service; | |
ErrorHandler = errorHandler; | |
} | |
public async void OnInitialize() | |
{ | |
try | |
{ | |
var result = await Service.GetAllAsync(); | |
// TODO なんかする | |
} | |
catch (Exception e) | |
{ | |
if (!await ErrorHandler.HandleHttpErrorAsync(e)) | |
{ | |
throw; | |
} | |
} | |
} | |
} | |
public class ViewModelExceptionHandler | |
{ | |
private IPageDialogService DialogService { get; } | |
public ViewModelExceptionHandler(IPageDialogService dialogService) | |
{ | |
DialogService = dialogService; | |
} | |
public async Task<bool> HandleHttpErrorAsync(Exception e) | |
{ | |
if (e is TaskCanceledException) | |
{ | |
// Timeout | |
await DialogService.DisplayAlertAsync("通信エラー", "サーバーへの接続がタイムアウトしました。クソ回線乙 ^_^", "OK"); | |
return true; | |
} | |
if (e is HttpRequestException) | |
{ | |
// サーバー側のエラー。EnsureSuccessStatusCodeでStatusCodeが200番台じゃ無いとここにくる | |
await DialogService.DisplayAlertAsync("通信エラー", "通信エラーが発生しました。ちょっと待ってリトライしてぴ-ぴーぴー。", "OK"); | |
return true; | |
} | |
// HTTP系のエラーじゃないのでここでは何もしない | |
// NO MORE 握りつぶし | |
return false; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment