0

多くの場合、MVC ビューを作成するときは、最初にビューを にバインドExpandoObjectして、厳密に型指定されたビューモデルで実際のプロパティを追加/変更/削除するのに時間を費やすことなく、ビューモデルの形状をすばやく把握できるようにします。

しかし、自分のビューモデルがどのように見えるべきかについてかなり良い感触を得たら、実際のクラスを作成することを好みます。ExpandoObject からビューモデルを自動的に生成できれば素晴らしいと思います。それは可能ですか?

public virtual ActionResult DoStuff(int stuffId)
{
    // eventually this stuff gets moved to a service class
    dynamic vm = new ExpandoObject();
    using (var ctx = new MyContext())
    {
        vm.Stuff = ctx.Stuff
            .Where(x => x.Id == stuffId)
            .Select(x => new
            {
                Foo = x.Foo,
                Bar = x.Bar
            }).SingleOrDefault().ToExpando();
    }

    // once I know what vm looks like, I'll want to do this to easily create a new class
    // string stronglyType = GenerateStronglyTypeClass(vm);

    return View(vm); 
}

public string GenerateStronglyTypedClass(ExpandoObject object)
{
    // what goes here??
}
4

2 に答える 2

2

最初にビューを ExpandoObject にバインドして、ビューモデルの形状をすばやく把握できるようにします。厳密に型指定されたビューモデルで実際のプロパティを追加/変更/削除するのに時間を費やす必要はありません。

まあ、あなたのしていることは非常に悪いです。申し訳ありませんが、強力なタイピングが失われています。プロジェクトCtrl+Aのフォルダーで、で終わる名前を入力し、いくつかを入力して、実際の厳密に型指定されたビューモデルを定義しているときに、人々が実際にそれを使用するのが非常に難しいと思うとは信じられません。ModelsViewModelprop+Tab+Tab

代わりに、expandos、dynamics、ViewDatas、ViewBags、CrapBags などを使用しようとします。

そこで、私があなたに提案したいのは、実際のビュー モデルを使用して、その 1 週間のタイピングを忘れることです。そうしないと、ASP.NET MVC に苦労し続けることになります。私を信じてください。その通りです:-)

また、AutoMapperを使用してドメイン モデルとビュー モデルを自動的にバインドすると、私のようにビールを飲む時間が増えます。

public ActionResult DoStuff(int stuffId)
{
    using (var ctx = new MyContext())
    {
        var model = ctx.Stuff.Where(x => x.Id == stuffId);
        var vm = Mapper.Map<IEnumerable<MyDomainModel>, IEnumerable<MyViewModel>>(model);
        return View(vm);
    }
}

これがどれほど楽しいか見てください。

明らかに、コントローラーのアクションを単体テストする機会が必要な場合は、次のように、コントローラーで dome Linq-To-I-Don't-Know-What コンテキストをハードコーディングする代わりに、リポジトリを使用する必要があります。

public ActionResult DoStuff(int stuffId)
{
    var model = _stuffRepository.GetStuffs(stuffId);
    var vm = Mapper.Map<IEnumerable<MyDomainModel>, IEnumerable<MyViewModel>>(model);
    return View(vm);
}

そんなに大変ですか?

カスタム アクション オートマッパー属性を記述して、アクションを次のようにすることもできます。

[AutoMap(typeof(IEnumerable<MyDomainModel>), typeof(IEnumerable<MyViewModel>))]
public ActionResult DoStuff(int stuffId)
{
    var model = _stuffRepository.GetStuffs(stuffId);
    return View(model);
}

OK、私たちは短く、薄く、軽くなっています。まさにコントローラーのアクションがどうあるべきか。ダイエット中

于 2011-07-11T18:32:40.030 に答える
1

実行時に生成されたクラスの任意のタイプ (たとえば、emit を使用) は、あまりメリットがありません。コンパイル タイプでタイプがわからない場合でも、dynamic を呼び出すことになり、expando が実際に私の poco クラスを打ち負かすためです。テスト。生成クラスが動作する可能性のある ac# ファイルを作成しようとしている場合、ファイルをインクルードしてコードを置き換え、再コンパイルする必要がありますが、動作する可能性があります。

オープンソース フレームワークには、 ImpromptuInterfaceに含まれるビルダー構文があり、いくつかの型を変更するだけで、型が何であれ (expando または poco)、同じ方法でプロパティを割り当てたり、オブジェクト グラフを作成したりできます。

 dynamic New = Builder.New<ExpandoObject>();

  var person = New.Person(
      FirstName: "George",
      LastName: "Washington"
  );

その後、開発プロセスの後半で、静的型を定義できます

  public class Person{
      public string FirstName{get;set;}
      public string LastName{get;set;}
  }


  dynamic New = Builder.New<Person>();

  Person person = New.Person(   //we are static typing after this point
      FirstName: "George",
      LastName: "Washington"
  );

また、実行時に静的インターフェイスをラップするなど、役立つ他の機能もいくつかあります。

于 2011-07-18T14:18:07.743 に答える