8

私は使い始めたばかりで、MVC デザイン パターンに夢中になっています。

私の唯一の不満は、それが多くの繰り返しコードを生成するように見えることです。例えば。

あるプロジェクトに DB (モデル) を含む標準の MVC アプリがあり、別のプロジェクトではコントローラー/ビュー/ビューモデルから分離され、別のプロジェクトではテスト メソッドから分離されています。すべてうまくいっています。

モデル: 現在、DB プロジェクトには多数の優れた EF4 クラスがあり、実際のプロジェクトでは ViewModels を使用してデータにアクセスする必要があります。ここでは問題ありません。

コントローラー: ただし、私が持っているすべてのコントローラーは、基本的にまったく同じことを行います。ViewModels からデータを取得および設定するため、各コントローラーは異なるデータのみを取得するという点で異なりますが、基本的にすべて同じ方法でまったく同じジョブを実行しています。(私は現在 9 つ持っていますが、これは簡単に 50 を超える可能性があります)。

例えば:

public class Dummy1Controller : Controller
{
    private MyProj.Data.Entities _entities = new Data.Entities();
    private MyProj.Data.Entities2 _coreEntities = new Data.Entities2();

    //GET: /Customers/
    public ActionResult Index()
    {
        if (_entities.table1.Count() == 0) return View();

        var pastObj = _entities.table1.First();
        return View(new Table1ViewModel()
        {
            Id = pastObj.Id,
            FirstName = pastObj.FirstName,
            LastName = pastObj.LastName,
            .
            .
            .
            .
        });
    }
}

public class Dummy2Controller : Controller
{
    private MyProj.Data.Entities _entities = new Data.Entities();
    private MyProj.Data.Entities2 _coreEntities = new Data.Entities2();

    //GET: /Vehicles/
    public ActionResult Index()
    {
        if (_entities.table2.Count() == 0) return View();

        var pastObj = _entities.table2.First();
        return View(new Table1ViewModel()
        {
            RegNo = pastObj.RegNo,
            Make = pastObj.Make,
            Model = pastObj.Model,
            .
            .
            .
            .
        });
    }
}

public class Dummy3Controller : Controller
{
    private MyProj.Data.Entities _entities = new Data.Entities();
    private MyProj.Data.Entities2 _coreEntities = new Data.Entities2();

    //GET: /Invoices/
    public ActionResult Index()
    {
        if (_entities.table3.Count() == 0) return View();

        var pastObj = _entities.table3.First();
        return View(new Table1ViewModel()
        {
            InvNo = pastObj.InvNo,
            Amount = pastObj.Amount,
            Tax = pastObj.Tax,
            .
            .
            .
            .
        });
    }
}

ビュー: コントローラーから生成されたすべてのビューはうまく機能します。ただし、変更されるのはデータ (ラベルとテキスト ボックスのあるフィールド) だけです。繰り返しますが、それらはすべてまったく同じ仕事をします (ただし、データセットは異なります)。

@model MyProject.Web.ViewModels.Table1ViewModel

@{
    ViewBag.Title = "Index";
}

<link href="@Url.Content("~/Content/CSS/GenericDetailStyles.css")" rel="stylesheet" type="text/css" />

<section id="content">
    <div id="table">
        <div>
            <h2>Customer</h2>
        </div>
        <div class="row">
            <div class="left">@Html.LabelFor(x=>x.Id)</div>
            <div class="right">@Html.TextBoxFor(model => model.Id)</div>
        </div>
        <div class="row">
            <div class="left">@Html.LabelFor(x=>x.FirstName)</div>
            <div class="right">@Html.TextBoxFor(model => model.FirstName)</div>
        </div>
        <div class="row">
            <div class="left">@Html.LabelFor(x=>x.LastName)</div>
            <div class="right">@Html.TextBoxFor(model => model.LastName)</div>
        </div>
        .
        .
        .
        .
    </div>
</section>

@{Html.RenderAction("Index", "FooterPartial");}


--------------------------------------------------------------------------------------


@model MyProject.Web.ViewModels.Table2ViewModel

@{
    ViewBag.Title = "Index";
}

<link href="@Url.Content("~/Content/CSS/GenericDetailStyles.css")" rel="stylesheet" type="text/css" />

<section id="content">
    <div id="table">
        <div>
            <h2>Vehicle</h2>
        </div>
        <div class="row">
            <div class="left">@Html.LabelFor(x=>x.RegNo)</div>
            <div class="right">@Html.TextBoxFor(model => model.RegNo)</div>
        </div>
        <div class="row">
            <div class="left">@Html.LabelFor(x=>x.Make)</div>
            <div class="right">@Html.TextBoxFor(model => model.Make)</div>
        </div>
        <div class="row">
            <div class="left">@Html.LabelFor(x=>x.PatientID)</div>
            <div class="right">@Html.TextBoxFor(model => model.Model)</div>
        </div>
        .
        .
        .
        .
    </div>
</section>

@{Html.RenderAction("Index", "FooterPartial");}


--------------------------------------------------------------------------------------


@model MyProject.Web.ViewModels.Table3ViewModel

@{
    ViewBag.Title = "Index";
}

<link href="@Url.Content("~/Content/CSS/GenericDetailStyles.css")" rel="stylesheet" type="text/css" />

<section id="content">
    <div id="table">
        <div>
            <h2>Invoice</h2>
        </div>
        <div class="row">
            <div class="left">@Html.LabelFor(x=>x.InvNo)</div>
            <div class="right">@Html.TextBoxFor(model => model.InvNo)</div>
        </div>
        <div class="row">
            <div class="left">@Html.LabelFor(x=>x.Amount)</div>
            <div class="right">@Html.TextBoxFor(model => model.Amount)</div>
        </div>
        <div class="row">
            <div class="left">@Html.LabelFor(x=>x.Tax)</div>
            <div class="right">@Html.TextBoxFor(model => model.Tax)</div>
        </div>
        .
        .
        .
        .
    </div>
</section>

@{Html.RenderAction("Index", "FooterPartial");}

問題: 単一のコントローラーを作成し、それを動的にしたいと考えています。さまざまなビュー モデルからデータを読み取ることができるようにします。(本質的に同じ仕事をしているコントローラーが 9 つまたは 50 あるのはなぜですか)

次に、ビューについても同様に行いたいと思います。さまざまなフィールドを動的に生成できるようにします。(なぜ 9 つまたは 50 のビューがすべて同じ仕事をしているのですか)。ビューがコントローラーに基づいている場合、ビューはそのプロパティに基づいて変更できる必要があります。

基本的に私がやりたいことは、ビューモデル X または VM - Y または VM - Z ect から読み取るようにコントローラーに指示する方法を見つけることであり、プロパティを生成し、関連するデータを取得して、それをビューに渡すことができるはずです。受信すると、ラベルとテキスト ボックスを含むフィールドが生成されます。

リフレクションを使用してこれを行う方法があるかどうか知りたいと思います。ビューモデルは単純なプロパティを持つ基本的なクラスであるため。指定されたビューモデル オブジェクトを読み取り、そのプロパティを取得し、関連するテーブルも読み取り、そのテーブルのフィールドをクラスのプロパティと照合するメソッドを持つ基本コントローラー クラスを作成する可能性があります。最後に、テーブルから表示するレコードを渡すことができます。ビューは、ある種のかみそり、C#、または JavaScript を使用して、これに基づいて自動的に生成できます。

これが可能かどうかについて教えていただければ幸いです。

4

4 に答える 4

10

AutoMapperを使用して、モデル/エンティティ間で値をコピーするためのすべてのコードを削除できます。

また、レイアウト、データ注釈属性、およびテンプレート (Html.DisplayFor および Html.EditorFor を使用) を使用してビューを縮小することも検討してください。

http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-1-introduction.html

Model と Entity の型を取り、CRUD 操作の共通ロジックを含む汎用の基本コントローラー クラスを作成する可能性を調査することはできますが、それは一歩先を行きすぎて、後で開発を妨げる可能性があります。

于 2012-05-22T15:14:48.480 に答える
5

1つの動的コントローラーはおそらく一歩遠すぎると思います-すべてを汎用化し、ビューの1つがデータベースへの単純なマップよりも複雑なものを必要とする場合に何が起こるか-「汎用ビューコントローラー」を拡張して処理しますかこれとともに?ここで終わるかもしれません

Automapperを調べて、ビューモデルを処理する際の反復的な性質の一部を削除する必要があります。

http://automapper.codeplex.com/

于 2012-05-22T15:17:22.327 に答える
0

オブジェクトまたは基本クラスの EditFor/Model テンプレートを生成し、モデルとそのメタデータ (mvc metadataproviders の助けを借りて) を受け入れる 1 つのビューを作成し、フィールドを動的に構築することができます。 .
この投稿では、mvc2 で実行できる方法について説明していますが、この手法を mvc 3 にも簡単に適用できます。現在
取り組んでいるプロジェクトでこのようなテンプレートを使用しています。数十の異なるエンティティがあり、すべて同じ外観を共有しています。と感じます。私自身のメタデータプロバイダーの助けを借りて、フィールドの順序を取得し、各ビューでそれらを表示する必要があるかどうかを確認するのにも役立ちます.1つのビューを作成して、すべてのエンティティを正確に表示しました

于 2012-05-22T15:18:14.890 に答える
0

アプリケーション内のすべてのモデルとビューを処理するために 1 つの動的コントローラーを使用するのは行き過ぎであるという点については、ここにいる他の人たちの意見に同意します。コントローラーのコード量を減らす方法は他にもあります。ここでの他の回答では、優れたツールである AutoMapper について言及されています。AutoMapper の発明者である Jimmy Bogard の素晴らしいビデオもここにあります。このビデオには、コントローラーのコード量を削減するためにできるその他の方法が含まれています。

ビューに関しては、EditorTemplates を使用して、すべてのコントローラーを処理する 1 つのビューを既に持つことができます。リフレクションを使用してモデルを調べ、それに応じて入力フィールドをレンダリングする、カスタマイズされた EditorTemplate を作成できます。これはすべて「モデル メタデータ」を使用しており、Brad Wilson による良い投稿がここにあります

于 2012-05-22T21:40:38.757 に答える