コード
using InsuranceProductManager2.Data;
using InsuranceProductManager2.Models;
using InsuranceProductManager2.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;
namespace InsuranceProductManager2.Controllers
{
public class AutoInsuranceMvcController : Controller
{
private readonly AppDbContext _context;
private readonly IAutoPremiumCalculator _calculator;
public AutoInsuranceMvcController(AppDbContext context, IAutoPremiumCalculator calculator)
{
_context = context;
_calculator = calculator;
}
[HttpGet]
public async Task<IActionResult> SimulateAutoPremium()
{
ViewBag.Customers = await _context.Customers.ToListAsync();
return View(new AutoInsurancePolicy());
}
[HttpPost]
public async Task<IActionResult> CalculatePremium(AutoInsurancePolicy policy)
{
if (!ModelState.IsValid)
{
ViewBag.Customers = await _context.Customers.ToListAsync();
return View("SimulateAutoPremium", policy);
}
var customer = await _context.Customers.FindAsync(policy.CustomerId);
if (customer == null)
return NotFound();
var result = _calculator.CalculatePremium(customer, policy);
_context.Add(result);
await _context.SaveChangesAsync();
return View("AutoPremiumResult", result);
}
[HttpGet]
public async Task<IActionResult> AutoSimulationHistory()
{
var results = await _context.Set<AutoPremiumCalculationResult>()
.OrderByDescending(r => r.CalculatedAt)
.ToListAsync();
return View(results);
}
}
}
🚗 全体概要
public class AutoInsuranceMvcController : Controller
このクラスは Webアプリのユーザー操作(View)とデータ処理(Model)を仲介する層。
「ユーザーが入力 → サーバーで保険料を計算 → 結果を表示」という流れを制御しています。
🧩 フィールドとコンストラクタ
private readonly AppDbContext _context;
private readonly IAutoPremiumCalculator _calculator;
• _context → データベース操作用(Entity Framework Core)
• _calculator → 保険料計算ロジック(サービス層)
public AutoInsuranceMvcController(AppDbContext context, IAutoPremiumCalculator calculator)
{
_context = context;
_calculator = calculator;
}
• 依存性注入(Dependency Injection) により、データベースとサービスクラスをコントローラに自動で渡します。
• これにより、テストしやすく、保守性も高まります。
🧾 [HttpGet] SimulateAutoPremium()
[HttpGet]
public async Task<IActionResult> SimulateAutoPremium()
{
ViewBag.Customers = await _context.Customers.ToListAsync();
return View(new AutoInsurancePolicy());
}
💡 役割:
• ユーザーが「保険シミュレーション画面」を開いたときに呼ばれる。
• 登録済みの顧客リストをデータベースから取得して ViewBag.Customers に格納。
• AutoInsurancePolicy の空オブジェクトをビューに渡し、入力フォームを表示。
⚙️ [HttpPost] CalculatePremium()
[HttpPost]
public async Task<IActionResult> CalculatePremium(AutoInsurancePolicy policy)
💡 役割:
フォーム送信時(ユーザーが入力して「計算する」ボタンを押したとき)の処理。
🔸 1. 入力バリデーション
if (!ModelState.IsValid)
{
ViewBag.Customers = await _context.Customers.ToListAsync();
return View("SimulateAutoPremium", policy);
}
• ModelState.IsValid:
モデル (AutoInsurancePolicy) の検証属性(必須・範囲など)をチェック。
• エラーがあれば再度フォームを表示し、入力内容を保持。
🔸 2. 顧客情報の取得
var customer = await _context.Customers.FindAsync(policy.CustomerId);
if (customer == null)
return NotFound();
• 入力された CustomerId に該当する顧客が存在しない場合、404 Not Found。
🔸 3. 保険料計算
var result = _calculator.CalculatePremium(customer, policy);
• サービス層 IAutoPremiumCalculator を使って保険料を計算。
• ここで実際に「年齢・車・事故歴」などの補正が反映されます。
🔸 4. 結果をデータベースに保存
_context.Add(result);
await _context.SaveChangesAsync();
• 計算結果を AutoPremiumCalculationResult テーブルに追加。
• 保存して履歴として残します。
🔸 5. 結果画面へ遷移
return View("AutoPremiumResult", result);
• 計算結果をビュー(AutoPremiumResult.cshtml)に渡して表示。
📜 [HttpGet] AutoSimulationHistory()
[HttpGet]
public async Task<IActionResult> AutoSimulationHistory()
{
var results = await _context.Set<AutoPremiumCalculationResult>()
.OrderByDescending(r => r.CalculatedAt)
.ToListAsync();
return View(results);
}
💡 役割:
• 過去に実行した保険料シミュレーション結果の履歴を一覧表示する。
• 新しい順(OrderByDescending)に並べて表示。
🧠 全体の動作イメージ
1️⃣ GET /AutoInsuranceMvc/SimulateAutoPremium
→ 入力フォームを表示
(顧客選択 + 車情報など)
2️⃣ ユーザーが送信(POST)
→ CalculatePremium() 呼び出し
→ 保険料を計算し、結果を保存・表示
3️⃣ GET /AutoInsuranceMvc/AutoSimulationHistory
→ 計算履歴を一覧で表示
🧩 この設計の特徴(実務的ポイント)
| 項目 | 内容 |
|---|---|
| ✅ MVC分離 | Model・View・Controller・Serviceが明確に分離されている |
| ✅ 非同期処理 | async/await によってDB操作がノンブロッキング |
| ✅ 依存性注入 | 計算ロジックを切り替えやすい設計 |
| ✅ 再利用性 | AutoPremiumCalculator を他のAPIやバッチ処理でも再利用可能 |
| ✅ テスト容易 | ロジック層を個別にユニットテストできる |