2

鉴于以下代码(高度简化以直截了当),必须遵循模式是否是一种代码味道?

型号:

class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Category Cat { get; set; }
}

class Category
{
    public int Id { get; set; }
    public string Label { get; set; }
}

编辑产品的视图:

<% =Html.EditorFor( x => x.Name ) %>
<% =Html.EditorFor( x => x.Category ) %>

类别的 EditorTemplate

<% =Html.DropDownList<Category>() %>

HtmlHelper 方法

public static MvcHtmlString DropDownList<TEntity>(this HtmlHelper helper)
    where TEntity : Entity
{
    var selectList = new SelectList(
        ServiceLocator.GetInstance<SomethingGivingMe<TEntity>>().GetAll(), 
        "Id", "Label");

    return SelectExtensions.DropDownList(helper, "List", selectList, null, null);
}

作为参考,helper 方法的真正实现需要一些 lambdas 来获取 DataTextField 和 DataValueField 名称、所选值等。

困扰我的一点是在 HtmlHelper 中使用服务定位器。我认为我的 Product 模型中应该有一个 AllCategories 属性,但是每次需要时都需要在控制器中填充它。

所以我认为我使用的解决方案更简单,因为辅助方法是通用的(modelbinder 也是通用的,这里不包括在内)。所以我只需要为需要 DropDownList 的每种类型创建一个 EditorTemplate。

有什么建议吗?

4

2 回答 2

0

恕我直言,我会保持原样,在另一个项目中拥有相同的东西。

但是服务位置也困扰着我,所以对于另一个项目,我制作了 ActionFilter 的这一部分,它扫描模型,找到所有预期的下拉菜单并将批量加载到 ViewData 中。由于 ServiceLocator 或 Repository/Context/whatever 已经注入到控制器中,因此您不必将服务位置分布在各处。

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
    foreach( var anticipated in SomeDetectionMethod() )
    {
          var selectList = new SelectList(
    ServiceLocator.GetInstance<SomethingGivingMe<TEntity>>().GetAll(), 
    "Id", "Label");

         ViewData["SelectList." + anticipated.Label/Name/Description"] = selectList;
    }
}

然后,您可以在视图中创建一个助手,通过自定义编辑器模板或其他方法加载这些下拉列表。

于 2010-08-05T20:13:12.853 回答
-1

建议:从这里查看 asp.net mvc 示例应用程序:http: //valueinjecter.codeplex.com/ 祝你好运;)

这就是 ValueInjecter 的示例应用程序如何获得下拉菜单的方式:(但现在不行,因为我对 Resolve 没问题)

public class CountryToLookup : LoopValueInjection<Country, object>
{
    ICountryRepo _repo;

    public CountryToLookup(ICountryRepository repo)
    {
        _repo = repo;
    }

    protected override object SetValue(Country sourcePropertyValue)
    {
        var value = sourcePropertyValue ?? new Country();
        var countries = _repo.GetAll().ToArray();
        return
            countries.Select(
                o => new SelectListItem
                         {
                             Text = o.Name,
                             Value = o.Id.ToString(),
                             Selected = value.Id == o.Id
                         });
    }
}
于 2010-08-05T20:05:50.110 回答