字符串GenerateStronglyTypedClass(ExpandoObject object)是什么样的?
通常,当我创建 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??
}
Often when I'm creating MVC views, I first bind my view to an ExpandoObject
so I can quickly figure out the shape of my viewmodel, without having to spend time adding/modifying/removing real properties in a strongly-typed viewmodel.
But once I have a pretty good feel for what my viewmodel should look like, I prefer to create an actual class for it. It'd be great if I could automatically generate the viewmodel from the ExpandoObject. Is that possible?
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??
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
嗯,你所做的事情非常糟糕。很抱歉这么说,但您正在失去强类型。我不敢相信人们实际上发现在项目的
Models
文件夹中使用 Ctrl+A 是如此困难,输入一些以ViewModel
结尾的名称code> 然后输入几个 prop+Tab+Tab 并定义一个真正的强类型视图模型。相反,人们会尝试使用一些 Expandos、Dynamics、ViewDatas、ViewBags、CrapBags...
所以我建议您:使用真实的视图模型并忘记那一周的打字,否则您将继续与 ASP.NET MVC 作斗争。相信我。事情就是这样:-)
当您使用 AutoMapper 在域模型和视图模型之间自动绑定时,您将拥有更多时间喝啤酒,像我一样:
看看这有多有趣?
显然,如果您想有机会对控制器操作进行单元测试,您应该使用存储库,而不是在控制器中硬编码 dome Linq-To-I-Don't-Know-What 上下文,如下所示:
有那么难吗?
您甚至可以编写 自定义操作自动映射器 归因于你的行为甚至可能看起来像这样:
好吧,我们变得更矮、更薄、更轻。控制器的动作应该是这样的。 节食。
Well, what you are doing is very bad. Sorry to say it but you are loosing strong typing. I can't believe people actually find it so hard to use Ctrl+A while on the
Models
folder in their project, type some name ending withViewModel
and then type a couple of prop+Tab+Tab and define a real strongly typed view model.Instead people try to use some expandos, dynamics, ViewDatas, ViewBags, CrapBags, ...
So here's what I would suggest you: use real view models and forget about those week typing or you will continue struggling with ASP.NET MVC. Believe me. It's how it is :-)
And when you use AutoMapper to automatically bind between your domain models and view models you will have more time to drink beer, like me:
See how much more fun this is?
Obviously if you ever want to have any chance to unit test your controller actions you should be using repositories instead of hardcoding dome Linq-To-I-Don't-Know-What contexts in your controllers, like this:
Is it so hard?
You could even write a custom action automapper attribute your action might even look like this:
OK, we are getting shorter, thinner, lighter. Exactly how controller actions should be. On a diet.
在运行时生成的任何类型的类(比如emit)都不会带来太大的好处,因为如果你不知道编译类型的类型,你仍然会调用dynamic,并且expando实际上会击败我的poco类测试。如果您的生成类要创建可以工作的 ac# 文件,但您必须包含该文件并替换代码,重新编译,有点呃,但可以工作。
开源框架有 ImpromptuInterface 有一个 构建器语法,让您可以以相同的方式分配属性或创建对象图,无论类型是什么(expando 或poco)只需进行一些类型更改。
然后在稍后的开发过程中,您可以定义静态类型。
它还有一些其他功能,例如在运行时包装静态接口,这些功能可能对您有用。
Any type of generated class at runtime (with say emit), won't give much of a benefit because if you don't know the type at compile type your are still going to be calling dynamic and expando will actually beat poco class in my tests. If your generate class is going to create a c# file that could work but you'll have to include the file and replace the code, recompile, kind of eh, but could work.
The opensource framework has ImpromptuInterface has a builder syntax that lets you assign properties or create objects graphs in the same manner no matter what the type is (expando or poco) with just a couple type changes.
and then later in your development process you could define your static type
It also has some other features like wrapping an static interface at runtime too that might be of use to you.