将DTO传递给我的ViewModels构造函数以映射属性

在我的解决方案中,我有两个项目。

项目1(核心)使用Dapper将SQL映射到DTO

项目2(WebUI – ASP.NET MVC 4)这里我使用每个View的ViewModel。

控制器的示例

[HttpGet] public ActionResult Edit(int id) { // Get my ProductDto in Core var product = Using().Single(id); var vm = new ProductFormModel(product); return View(vm); } 

ViewModel的示例

 public class ProductFormModel : BaseViewModel, ICreateProductCommand { public int ProductId { get; set; } public int ProductGroupId { get; set; } public string ArtNo { get; set; } public bool IsDefault { get; set; } public string Description { get; set; } public string Specification { get; set; } public string Unit { get; set; } public string Account { get; set; } public decimal NetPrice { get; set; } public ProductFormModel(int productGroupId) { this.ProductGroupId = productGroupId; } public ProductFormModel(ProductDto dto) { this.ProductId = dto.ProductId; this.ProductGroupId = dto.ProductGroupId; this.ArtNo = dto.ArtNo; this.IsDefault = dto.IsDefault; this.Description = dto.Description; this.Specification = dto.Specification; this.Unit = dto.Unit; this.Account = dto.Account; this.NetPrice = dto.NetPrice; } public ProductFormModel() { } } 

说明:我将使用项目中的服务类(Core)在我的控制器中获取我的DTO。 然后我创建我的ViewModel并将DTO传递给ViewModel中的构造函数。 我也可以使用此视图添加新产品,因为我的ViewModel可以采用空构造函数。

有没有人有这方面的经验。 我想知道如果项目变得更大,我将来是否会有这样的问题?

我知道这与Dapper无关。 但我仍然想要一个解释我的解决方案的好方法。

我认为使用您当前的方法会很好。 更重要的是,如果您开始遇到与对象映射代码相关的问题(而不是事先考虑太多),请从这样开始并重构

我有时使用的组织映射逻辑的另一种方法是使用扩展方法。 这样,映射代码与视图模型本身保持独立。 就像是:

 public static class ProductMappingExtensions { public static ProductFormModel ToViewModel(this ProductDto dto) { // Mapping code goes here } } // Usage: var viewModel = dto.ToViewModel(); 

另一种方法是使用像AutoMapper这样的映射框架 – 如果你的映射逻辑很简单(属性之间有很多1:1的映射),这是一个很好的选择。

但是,再次, 在需要时开始简单和重构

我意识到这是一个有点迟到的答案,但也许它会帮助将来的某个人。

这种在对象之间进行映射的方式打破了SOLID原则的’S’,因为ViewModel的职责是在其属性中准备数据以供视图使用,而不是其他任何东西,因此,映射对象不应该在这是责任。

这种方式的另一个缺点是它也打破了’松散耦合’OO原则,因为ViewModel与您的DTO强烈耦合。

我认为,即使我们处于项目的第一步,也有一些重要的OO原则,我们永远不应该破坏,所以使用mapper类,auto(AutoMapper,ValueInjecter …)或手动,肯定更好。