我发现我在控制器中编写的代码很大程度上是重复的,更重要的是我为控制器编写的测试也非常重复。保存方法的一般模式如下......
获取一个实体和一些原始参数。将原始参数中的值写入我的实体上的相同命名参数。验证实体。如果实体有效,请保存该实体。
我已经有了一个模型绑定器,它将绑定从IDataEntity继承的任何东西(我们所有数据库持久化实体都实现的接口)。此模型绑定器找到适当的存储库,并使用传递的id查找实体。
我一直在考虑为此模型绑定添加扩展,该扩展还会从值提供程序中提取值并将其写入现有值。这将在我为我的实体分配值的操作中省去一些重复的代码。并且还允许我将实体传递给我的控制器测试而不是大量的值。
例如,目前看起来像这样的方法:
public ActionResult SaveCompanyAddress(Address address,
string address1,
string address2,
string address3,
string city,
string county,
Country country,
string postcode)
{
address.Address1 = address1;
address.Address2 = address2;
address.Address3 = address3;
address.City = city;
address.County = county;
address.Country = country;
address.Postcode = postcode;
Validate(address);
if (ModelState.IsValid)
{
using (var tran = TransactionFactory.CreateTransaction())
{
addressRepository.Save(entity);
tran.Commit();
}
return this.RedirectToAction(x => x.List(address.Company));
}
else
{
return View("Edit", address);
}
}
长度减半并且几乎删除了所有参数。这肯定听起来很吸引人,因为我们编写的代码量减少了,测试验证的测试可以通过模拟验证提供程序和默认地址,而不用担心设置所有这些参数。但是我担心幕后魔术可能会有一点太多让它成为一个好主意。
思考? Opnions?想法?
答案 0 :(得分:2)
您可能还会妥协并使用默认模型绑定器来绑定您的简单属性,并从值提供程序中获取复杂属性并将其“手动”填充。对于仅具有简单属性的模型,默认模型绑定器就足够了。对于具有一个或两个复杂属性的那些,即那些未由默认模型绑定器处理的属性,您仍然可以节省大量代码而无需编写自定义模型绑定器。可以使用类上的共享方法编写复杂的绑定代码。一旦控制器中的绑定代码需要跨越控制器边界或变得重要,请将其重构为自定义模型绑定器。