2012-03-16 8 views
5

asp.netのMVC3でビューモデルを構築する場合、そのビューモデルのオブジェクトをインスタンス化するコードはどこですか?私は主にデータベース内のコードを照会する以外に、今コントローラーでやっています。ここでは、コードの例です:ビューモデルを構築するためのコードはどこにありますか?

ビューモデル:

public class WorkListVM 
{ 
    //list for employees 
    [Display(Name = "Select A Employee")] 
    [Required] 
    public int? EmployeeId { get; set; } 
    public GenericSelectList EmployeeList { get; set; } 
} 

コントローラコード:

 //build view model 
     var vm = new WorkListVM(); 

     //build employee list 
     vm.EmployeeList = new GenericSelectList(0,"-- Select Employee --"); 
     var employees = new List<Employee>(); 
     using (var gr = new GenericRepo<Employee>()) 
     { 
      employees = gr.Get().ToList(); 
     } 
     foreach(var employee in employees) 
     { 
      var gl = new GenericListItem(); 
      gl.Id = employee.EmployeeId; 
      gl.DisplayFields = employee.FirstName + " " + employee.LastName; 
      vm.EmployeeList.Values.Add(gl); 
     } 

ジェネリック選択リストがヘルパーに@html.dropdownfor年代を行くデータを保持する単純なクラスですSelectList。私はこれらの選択リストを作成し、コントローラコード内のビューモデルの同様のデータ構成を構築します。このコードをホストしているコントローラーには合計109行のコードがあるため、膨大ではありません。しかし、私はいつも冗長性を減らそうと努力しており、時には//build employee listのコードがコピー貼り付けされてしまいます(ugh、私はコピー貼り付けが嫌いです)。

このコードを保存するのに適した場所はありますか?おそらく、これらの選択リスト/その他のビュー・データ・オブジェクトのデータを構築するためにファクトリ・パターンを使用する必要がありますか?すべてのあなたの助けを

EDIT

感謝。私がやったことがここにあります。私はリチャードとジェシーによって提案.ToSelectList(...)と非常によく似て、一般的な選択リストクラス内のメソッドを作ることになった:

public class GenericSelectList 
{ 
    public List<GenericListItem> Values { get; set; } 
    public int StartValue { get; set; } 
    public string Message { get; set; } 

    public GenericSelectList(int StartValue = 0, string Message = "select") 
    { 
     Values = new List<GenericListItem>(); 
     this.StartValue = StartValue; 
     this.Message = Message; 
    } 

    public void BuildValues<T>(List<T> items, Func<T, int> value, Func<T, string> text) where T : class 
    { 
     this.Values = items.Select(f => new GenericListItem() 
     { 
      Id = value(f), 
      DisplayFields = text(f) 
     }).ToList(); 
    } 
} 
+0

viewmodelをビューに戻すと、コードがコントローラに入ります。 –

+0

@白ジェームス - はい、このactionresultメソッドの最後に 'return View(vm);'があります。ビューは強い型の '@model WorkListVM'です。このコードの一部は、複数のコントローラで使用されます。冗長性を減らすために、これらのビューモデルオブジェクトの作成をラップするファクトリを持つことは理にかなっていませんか? –

答えて

2

は、私は一般的に、私は独立して、コントローラのテストすることができるヘルパーメソッドにそれを抽出します。

ただし、ビューモデルの作成はそのままでコントローラ内で完璧にうまくいきます。すでに指摘したように、選択リストを生成する方がずっとシンプルになる(再利用性はもちろん)。ここで

は使用例と一緒にIEnumerableをのToSelectList拡張です:

public static List<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, string> value, Func<T, string> text, string defaultOption) 
{ 
    var items = enumerable.Select(f => new SelectListItem() 
              { 
               Text = text(f) , 
               Value = value(f) 
              }).ToList(); 

    if (!string.IsNullOrEmpty(defaultOption)) 
    { 
        items.Insert(0, new SelectListItem() 
         { 
          Text = defaultOption, 
          Value = string.Empty 
         }); 
    } 

    return items; 
} 

あなたのビューモデルの中でそのようにあなたは、プロパティを追加することができます。あなたのコントローラ内の

IEnumerable<SelectListItem> Employees { get; set; } 

(i」はRepoがIEnumberableを返すと仮定して):

var employees = new IEnumerable<Employee>(); 
using (var gr = new GenericRepo<Employee>()) 
{ 
    employees = gr.Get(); 
} 

vm.Employees = employees.ToSelectList(x=>x.FirstName + " " + x.LastName, x=>x.Id, "-- Select Employee --") 

あなたのビューのドロップダウンリストは、次のようになります。

@Html.DropDownListFor(model => model.EmployeeId, Model.employees) 
+0

+1 - 偉大な心は似ています;)そしてあなたは私に翻訳を保存しました! – RichardW1001

+0

非常に書かれた拡張機能です。この件に関する入力をありがとうございます:) –

+0

@Jesse - 拡張機能のアイデアは良かったですが、私はこれをクラス内のメソッドにすることにしました。実装については私の編集を参照してください。再度、感謝します! –

2

あなたの目標は、冗長なコードを避けるためである場合は、共通の抽出すべきですパーツをヘルパーメソッドに変換します。最も単純な形式では、静的メソッドを使用することができます。

コントローラーの建物ビューモデルは、通常、それに対して特別な理由がある場合を除いて、適切なアプローチです。

任意の方法でコードを構造化できます。ヘルパーメソッドや抽象的な抽象化など、複雑さに対処するために標準的な手法を使用します。シンプルで十分なときに複雑にする必要はありません。

2

1 - GenericSelectListを返すIEnumerable<Employee>またはIQueryable<Employee>に拡張方法を追加できます。メリット - 従業員のコレクション(フィルタリングされたリスト)と非常に良い呼び出し構文に対して再利用できます。選択リストの作成方法をカスタマイズすることができます。短所 - それぞれのタイプに対してこれらのメソッドの1つを記述する必要があります。

2 - IEnumerable<T>に対して機能するジェネリックで動作する拡張メソッドを変更し、Expression入力に基づいてGenericSetListを生成することができます。利点 - あなたのメソッドは本当に総称的なものになりました。つまり、一度書き直して再利用します。クラスごとの1関数がジェネリックを使用して重複を節約できるように、これを1と組み合わせる方法でこれを行うことができます。短所 - 表現などを使用する際の快適性を前提としています。

3 - ViewModelsを返すファクトリメソッドを持つことができます。

これらは、組み合わせても機能し、コピー/ペーストコードを削除し、再利用とテスト容易性を促進するのに役立ちます。

編集 - ここでは、 2を実装することができます(VBではC#への変換は簡単です)。次に、入力の有用な並べ替えのためにオーバーロードを追加します。

Imports System.Runtime.CompilerServices 
Imports System.Linq.Expressions 

Module IQueryableExtensions 

    <Extension()> 
    Public Function ToSelectList(Of T)(source As IEnumerable(Of T), nameExpression As Expression(Of Func(Of T, String)), valueExpression As Expression(Of Func(Of T, String)), selectedExpression As Expression(Of Func(Of T, Boolean)), additionalItems As IEnumerable(Of SelectListItem)) As IEnumerable(Of SelectListItem) 
     Return additionalItems.Union(
      source.Select(Function(x) New SelectListItem With { 
           .Text = nameExpression.Compile.Invoke(x), 
           .Value = valueExpression.Compile.Invoke(x), 
           .Selected = selectedExpression.Compile.Invoke(x) 
          } 
        ) 
       ) 
    End Function 

End Module 

使用例:

Dim People As New List(Of Person) From {New Person With {.Name = "Richard", .ID = 1}} 

    Dim sl = People.ToSelectList(Function(p) p.Name, 
           Function(p) p.ID, 
           Function(p) p.ID = 1, 
           {New SelectListItem With {.Value = 0, 
                  .Text = "Please Select A Person"}}) 
+0

私は#2を行うことができます。それは、選択リスト生成のための一般的な応答を追加することです。しかし、それは反映を必要とするでしょう。リポジトリでリフレクションを使用することは賢明ではないでしょうか? –

+0

あなたはクラス名を含めるのでリフレクションをしていますか?それ以外の方法もあります。私には秒を与え、サンプルを投稿します。 – RichardW1001

+0

@TravisJ - そこには、反射がない可能な実装があります。 – RichardW1001

1

これが正しい方法であるかどうかは知りませんが、私はそれを使用し、それは私がすべてのコントロールを保つことができます。

私の目のコントローラは、更新セッション、クッキーのようなことをしてから、ビューを返します。私は決してそれを使用してデータをソートしたり、オブジェクトを作成してビューに送ることはありません。

は(私がカンニングする可能性がある場合、その1つのライナーオフ1:P)

私はヘルパークラスに追加するもののすべてのその種。私がコピーとペーストが来ると感じるたびに、私はヘルパーで新しいメソッドを作成し、代わりにそれを呼び出します。

さらに、3日後にメソッドとそのすべてのメソッドを使用する必要があるときに、うまくいく感覚が得られます。ビューモデルの作成に入るのビジネス・ロジックが非常に複雑である場合にはマーティン

+1

男..私はタップしている間、私はタイプが遅すぎる、答えは2です! – SmithMart

+0

おそらく、これらの選択リストの作成を管理するためにリフレクションを使用してジェネリックヘルパーメソッドを作成する必要があります。 –

関連する問題