views:

32

answers:

1

I believe that I'm going to need to use an html helper method that uses lambda expressions to accomplish this.

I was thinking of doing something along these lines:

    public static MvcHtmlString GetCategoryBreadCrumbs<T>(
        this HtmlHelper html,
        IEnumerable<T> currentCat,
        Func<T, T> parentProperty,
        Func<T, string> itemContent)
    {
        var sb = new StringBuilder();
        sb.AppendLine(itemContent(currentCat));
        if (currentCat.parentProperty.Count() > 0)
            sb.AppendLine(GetCategoryBreadCrumbs(html, currentCat.parentProperty, itemContent);

        return MvcHtmlString.Create(sb.ToString());
    }

And then I would want to call it similar to this:

<%: Html.GetCategoryBreadCrumbs(
Model, l => l.parentCategories, 
    l => l.catID, 
    l => l.catName)%>

Obviously, what I have above is horrible even at a pseudo-code level.

How do Lamba/Generic methods work?

+1  A: 

Well, I think you should consider separating the recursive traversal of the "categories" from the creation of the breadcrumb string. Mixing them together, as you do, makes the code harder to understand and maintain. By separating the parts of the implementation that are likely to change, you make the end result easier to understand, less fragile, and less ugly.

IEnumerable<T> GetHierarchy<T>( this T item, Func<T,T> getParent )
{
    while( item != null )
    {
        yield return item;
        item = getParent( item );
    }        
}

Now you can use String.Join() to do the rest:

<%: MvcHtmlString.Create(
      string.Join( " >> ", Model.GetHierarchy( item => item.GetParent() )
                                .Select( item => item.catName ) ) %>

In the code above, I assume that GetParent() provides a simple means of navigating to the parent of a given object instance. If this code varies at runtime, you could either use another lambda, or create an interface to unify the different types of classes that have "parents".

Obviously, if you're going to be generating bread-crumb string in multiple views, you should consider wrapping this in a helper.

LBushkin
Wow... I was making this wayyyy too complicated.
quakkels
@quakkels: Glad I could help. Sometimes when you stare at a problem for too long, you end up not seeing the simpler alternatives. Believe me, I've been in the same spot. :D
LBushkin
Quick question - is the function declaration supposed to be `IEnumerable<T> GetHierarchy<T>(etc.etc.)`? I'm new to working with generics in general. When i don't include the `<T>` after the function name then it tells me that I don't have 'T' defined.
quakkels
@quakkels: Yes, it is. That was a typo ... I'll fix it up.
LBushkin