как выглядит строка GenerateStronglyTypedClass (объект ExpandoObject)? - PullRequest
0 голосов
/ 11 июля 2011

Часто, когда я создаю виды MVC, я сначала привязываю свой вид к ExpandoObject, чтобы я мог быстро выяснить форму моей модели вида, не тратя время на добавление / изменение / удаление реальных свойств в сильноТипизированная viewmodel.

Но как только я достаточно хорошо понимаю, как должна выглядеть моя view-модель, я предпочитаю создать для нее реальный класс.Было бы здорово, если бы я мог автоматически сгенерировать модель представления из 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??
}

Ответы [ 2 ]

2 голосов
/ 11 июля 2011

Сначала я связываю свой взгляд с ExpandoObject, чтобы я мог быстро выяснить, форма моей модели, без необходимости тратить время добавление / изменение / удаление реальных свойств в строго типизированных ViewModel.

Ну, то, что вы делаете, очень плохо. Извините, что сказал это, но вы теряете сильную типизацию. Я не могу поверить, что людям действительно трудно использовать Ctrl + A , находясь в папке Models в своем проекте, введите какое-нибудь имя, заканчивающееся ViewModel, а затем введите пару prop + Tab + Tab и определить реальную строго типизированную модель представления.

Вместо этого люди пытаются использовать некоторые расширения, динамику, ViewDatas, ViewBags, CrapBags, ...

Итак, вот что я бы вам порекомендовал: используйте реальные модели представлений и забудьте о набранных неделях, иначе вы продолжите бороться с 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);
    }
}

Посмотрите, насколько это веселее?

Очевидно, что если вы когда-нибудь захотите провести модульное тестирование действий вашего контроллера, вам следует использовать репозитории вместо жестко закодированных купольных контекстов 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);
}

ОК, мы становимся короче, тоньше, светлее. Как именно должны быть действия контроллера. На диете .

1 голос
/ 18 июля 2011

Любой тип сгенерированного класса во время выполнения (например, с помощью emit) не принесет большой пользы, потому что, если вы не знаете тип при типе компиляции, вы все равно будете вызывать динамический, а expando фактически превзойдет poco.класс в моих тестах.Если ваш генерирующий класс собирается создать ac # файл, который мог бы работать, но вам нужно будет включить файл и заменить код, перекомпилировать, да, но может работать.

Фреймворк opensource имеет 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"
  );

Он также имеет некоторые другие функции, такие как перенос статического интерфейса во время выполнения, которые могут быть вам полезны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...