c#MVC3需要帮助使控制器方法更干燥
本文关键字:方法 控制器 帮助 c#MVC3 | 更新日期: 2023-09-27 18:22:41
我有一个模型类:
public class Service
{
public int ID { get; set; }
public string description { get; set; }
public decimal price { get; set; }
public decimal cost { get; set; }
public decimal manDay { get; set; }
public decimal FTE{ get; set; }
}
我还有一个简单的控制器,它将遍历整个Services
数据库表,并根据输入参数返回一个Service
属性的JSON表:
public JsonResult _columns(int attributeCode)
{
IQueryable<Service> services = db.Services.AsQueryable();
MyJSONContainer jcontainer = new MyJSONContainer();
switch(attributeCode)
{
case 0:
foreach(Service s in services)
jcontainer.addEntry(s.description, s.price);
return Json(jcontainer);
case 1:
foreach(Service s in services)
jcontainer.addEntry(s.description, s.cost);
return Json(jcontainer);
case 2:
foreach(Service s in services)
jcontainer.addEntry(s.description, s.manDay);
return Json(jcontainer);
default:
foreach(Service s in services)
jcontainer.addEntry(s.description, s.FTE);
return Json(jcontainer);
}
}
现在,这段代码工作得很好,但不是很DRY,尤其是因为我将来可能会在foreach
循环中给代码增加更多的复杂性。
我很想知道在DRY设计模式方面有更多专业知识的人会如何编写这个函数。
感谢
你可以在你的类中添加一个方法(或者作为助手类中的扩展方法,如果你不想在模型类中有"attributeCode"逻辑,只需做一些小的更改)
public decimal GetValueFor(int attributeCode) {
switch(attributeCode) {
case 0 : return price;
case 1 : return cost;
case 2 : return manDay;
default: return FTE;
}
}
然后在你的行动
public JsonResult _columns(int attributeCode)
{
var services = db.Services.AsQueryable();
var jcontainer = new MyJSONContainer();
foreach(var service in services)
jcontainer.addEntry(service.description, service.GetValueFor(attributeCode));
return Json(jcontainer);
}
如果您希望在未来对其进行扩展,那么我会将任务转移到它们自己的类中。
首先是一个通用的建设者:
static class JsonResultBuilder
{
public static JsonResult Build(Database db, int attributeCode)
{
var propertyRetriever = JsonServicePropertyRetrievers.Get(attributeCode);
IQueryable<Service> services = db.Services.AsQueryable();
MyJSONContainer jcontainer = new MyJSONContainer();
foreach(Service s in services)
jcontainer.addEntry(s.Description, propertyRetriever(s));
return Json(jcontainer);
}
}
然后是一个单独的类,您可以使用它轻松地添加更多的属性检索器:
static class JsonServicePropertyRetrievers
{
private static readonly Dictionary<int, Func<Service, object>> ServicePropertyRetrievers = new Dictionary<int, Func<Service, object>>();
private static readonly Func<Service, object> DefaultServicePropertyRetriever;
static JsonResultBuilder()
{
DefaultServicePropertyRetriever = s => s.FTE;
Register(0, s => s.price);
Register(1, s => s.cost);
Register(2, s => s.manDay);
}
public static void Register(int attributeCode, Func<Service, object> propertyRetriever)
{
ServicePropertyRetrievers[attributeCode] = propertyRetriever;
}
public static Func<Service, object> Get(int attributeCode)
{
Func<Service, object> propertyRetriever;
if (!ServicePropertyRetrievers.TryGetValue(attributeCode, out propertyRetriever))
propertyRetriever = DefaultServicePropertyRetriever;
return propertyRetriever;
}
}
这样就不会有越来越大的switch语句。如果您希望动态添加对代码的支持,那么可以很容易地使用JsonServicePropertyRetrievers.Register
方法。如果您不想公开对它的支持,只需将该方法设为私有方法即可。如果要删除检索方法,可以添加Remove
方法。
如果可能的话,我还建议为您的attributeCode
实现enum
。