ASP.NET MVC実装モード-ModelBuilder

3790 ワード

ViewModelの作成プロセスをControllerからModelBuilderに分離することは、本質的には職責の分離のためであり、Controllerの可読性も向上する.

通常の状況


MVCを使用する場合、Controllerには、View Modelを作成するためのコードが多く含まれます.一つの例から始めましょう.注文書を記入するためのページ(~\Order\FT-BJS-95486)があるとします.対応するアクションは次のとおりです.
public ActionResult Order(string productNo)

{

    var p = ProductService.GetProduct(productNo);

    var model = new OrderModel

    {

        ProductNo = productNo,

        ProductName = p.ProductName,

    };



    return View(model);

}


ここで、OrderModelというViewModelの定義は、
public class OrderModel 

{

    public string ProductNo { get; set; }

    public string ProductName { get; set; }

    public int Count { get; set; }

    public string Address { get; set; }

}


次に、ユーザーが入力した注文情報を受信するために、Actionがある可能性があります.
[HttpPost]

public ActionResult Order(OrderModel model)

{

    var p = ProductService.GetProduct(productNo);



    if(!ModelState.IsVaidate())

    {

        //     :

        // 1. ProductName     hidden input   post  

        // 2. ProductNo           post  

        model.ProductName = p.ProductName;

        return View(model);

    }



    var model2 = new OrderConfirmModel

    {

        ProductNo = model.ProductNo,

        ProductName = p.ProductName,

        Count = model.Count,

        Address = model.Address,

    };

    return View("OrderConfirm", model2);

}


1.質問

  • 一部のViewModelの作成は「複雑」である可能性があります.Controllerを読む観点から、「メイン制御フロー」
  • ではありません.
  • ViewModelは異なるフェーズで作成され、異なるフェーズの作成プロセスでは、コード
  • が繰り返されることが多い.

    2.分析


    上記の例では、OrderModel自体の構造および作成プロセスは非常に簡単ですが、重複する部分を認識することができます.
    var p = ProductService.GetProduct(productNo);
    
    model.ProductName = product.ProductName;
    
    

    これらの重複部分をまとめることができ、2つのViewModel “ ”に属します.
  • Create
  • Rebuild
  • IModelBuilderインタフェースを抽象化しました
    public interface IModelBuilder<TViewModel>
    
    {
    
        TViewModel Create();
    
        TViewModel Rebuild(TViewModel model);
    
    }
    
    

    3.改造


    IModelBuilderインタフェースを実装するOrderModelBuilderを書きます
    public class OrderModelBuilder : IModelBuilder<OrderModel>
    
    {
    
        private string _productNo;
    
        private string _productName;
    
    
    
        public OrderModelBuilder(string productNo, string productName)
    
        {
    
            _productNo = productNo;
    
            _productName = productName;
    
        }
    
    
    
        public OrderModel Create()
    
        {
    
            var model = new OrderModel
    
            {
    
                ProductNo = _productNo,
    
            };
    
            model = this.Rebuild(model);
    
            return model;
    
        }
    
    
    
        public OrderModel Rebuild(OrderModel model)
    
        {
    
            model.ProductName = _productName;
    
            return model;
    
        }
    
    }
    
    

    OrderModelBuilderによるOrderControllerのシンプル化
    private OrderModelBuilder GetBuilder(string productNo)
    
    {
    
        var p = ProductService.GetProduct(productNo);
    
        var builder = new OrderModelBuilder(p);
    
        return builder;
    
    }
    
    
    
    public ActionResult Order(string productNo)
    
    {
    
        var builder = GetBuilder(productNo);
    
        var model = builder.Create();
    
        return View(model);
    
    }
    
    
    
    [HttpPost]
    
    public ActionResult Order(OrderModel model)
    
    {
    
        if(!model.IsVaidate())
    
        {
    
            var builder = GetBuilder(model.ProductNo);
    
            var model = builder.Rebuild(model);
    
            return View(model);
    
        }
    
        //   OrderModel  OrderConfirmModel
    
        var builder2 = new OrderConfirmModelBuilder(model);
    
        var model2 = builder2.Create();
    
        return View("OrderConfirm", model2);
    
    }
    
    

    これにより,第1節で提案した2つの問題を解決した.
    言語やプラットフォームに関係なく、この文書で説明します.