字符串GenerateStronglyTypedClass(ExpandoObject对象)是什么样的?

时间:2011-07-11 18:25:42

标签: asp.net-mvc viewmodel expandoobject

通常在我创建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??
}

2 个答案:

答案 0 :(得分:2)

  

我首先将我的视图绑定到ExpandoObject,这样我就能很快发现   我的viewmodel的形状,而不必花时间   在强类型中添加/修改/删除实际属性   视图模型。

嗯,你在做什么是非常糟糕的。很抱歉这样说但是你输了很多。我无法相信人们实际上发现在项目的Models文件夹中使用 Ctrl + A 这么难,键入一些以ViewModel结尾的名称,然后键入a几个 prop + Tab + Tab 并定义一个真正的强类型视图模型。

相反,人们尝试使用一些expandos,动态,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-DO-Know-What-What-c​​ontext,如下所示:

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

这么难吗?

你甚至可以写一个custom action automapper属性,你的行动甚至可能是这样的:

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

好的,我们越来越短,越来越轻。控制器动作究竟应该如何。 On a diet

答案 1 :(得分:1)

运行时生成的任何类型的类(带有发出)都不会带来很多好处,因为如果你不知道编译类型的类型,你仍然会调用动态,而expando实际上会击败poco在我的测试中上课。如果你的generate类要创建一个可以工作的c#文件,但你必须包含该文件并替换代码,重新编译,呃,但是可以工作。

开源框架ImpromptuInterface有一个builder syntax,它允许您以相同的方式分配属性或创建对象图形,无论类型是什么(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"
  );

它还有一些其他功能,比如在运行时包装静态接口,这对您来说也很有用。