【发布时间】:2014-03-03 01:27:06
【问题描述】:
这是一个场景,我需要从多个 Web 服务调用返回的多个域对象中加载一个视图模型对象。将域模型对象转换为可理解的视图模型对象的代码是一些相当复杂的代码。我想过放的三个地方是:
- 控制器内部用于加载实例视图模型的内部方法。
- 视图模型类本身的静态 get 方法或属性,它返回已加载的视图模型实例。
- 完全独立的构建器或帮助器类,具有静态 get 方法、属性或重载构造函数,可返回加载的视图模型实例。
明确地说,我不想使用 AutoMapper 或类似的工具。从最佳实践的角度来看,我想知道这个逻辑应该去哪里,以及为什么。
编辑
这就是我目前所拥有的,这确实给了我“瘦”的控制器逻辑和关注点分离。我怎样才能让它变得更好呢?
// ** Controller **
public ActionResult Default()
{
var viewModel = MyViewModelBuilder.BuildViewModel(MarketType.Spot);
return View(SpotViewUrl, viewModel);
}
// ** Builder **
// Lives in MVC project under ViewModelBuilders folder
public class MyViewModelBuilder
{
public static ChartsModel BuildViewModel(MarketType rateMarket)
{
var result = new ChartsModel
{
RateMarket = rateMarket,
DateRange = new DateRange()
};
LoadGroupedRateLists(result, rateMarket);
LoadCoorespondingRates(result);
return result;
}
private static void LoadGroupedRateLists(ChartsModel model, RateMarket rateMarket)
{
var rateHistSvc = new RateHistoryService(RatesPrincipal.Current.Session.Token);
var serviceResult = (rateMarket == RateMarket.Spot)
? rateHistSvc.GetSpotNationalRateHistory()
: rateHistSvc.GetContractNationalRateHistory();
// Break lists apart by category, and re-sort and trim.
model.Cat1Rates = CategorizeTrimAndSort("cat1", false, serviceResult);
model.Cat2Rates = CategorizeTrimAndSort("cat2", true, serviceResult);
model.Cat3Rates = CategorizeTrimAndSort("cat3", false, serviceResult);
model.Cat4Rates = CategorizeTrimAndSort("cat4", true, serviceResult);
model.Cat5Rates = CategorizeTrimAndSort("cat5", false, serviceResult);
model.Cat6Rates = CategorizeTrimAndSort("cat6", true, serviceResult);
// Get Date range from results.
var sortedRateMonths = serviceResultNational
.Select(rate => rate.YearMonth)
.OrderBy(ym => ym.Year)
.ThenBy(ym => ym.Month);
model.DateRange.Start = sortedRateMonths.First();
model.DateRange.End = sortedRateMonths.Last();
}
...
}
【问题讨论】:
-
你看过类似automapper 这样的东西吗?这将允许你构建你正在远离控制器的映射,还允许将自动映射器注入控制器以实现可测试性。
-
如上所述,我不想在这里使用 Automapper,因为它不适用于这种情况,在这种情况下有几个域对象被分割以进行展示。
-
Automapper 绝对适用于这种情况。您可以从多个对象映射到单个对象。
-
可能是这样,但我真的很想为
custom表示转换代码找到最佳模式,因为实际上Automapper 无法解决每个转换/映射问题。 -
我还没有遇到过 AM 无法解决的自定义转换/映射问题。不是试图说服你使用它,只是说它是使用 fluent API(.ForMember、.ConstructUsing 等)高度可定制的。
标签: asp.net-mvc transform viewmodel code-organization