Complexity
Complexity

Reputation: 5830

Is this the correct way to use an Expression<Func<string, string>>?

Currently, I'm in the process of writing custom controls for MVC, thus extending the HtmlHelper. I'm working with Expression<T> here, but I'm relatively new to it.

Altough my code is working, I just want to verify is this is correct.

I'm rendering a control, and I can add attributes to the rendered control in a fluent way. The way to add an attribute to my control is with the following code:

.Attributes(style => "width: 100%;")

When I want to use multiple attributes on my rendered control, this method can be called multiple times:

.Attributes(style => "width: 100%;")
.Attributes(id => "renderedControl")

In order to render the attributes, I'm looking in the expression containing the attribute.

Here's the method signature that I use for adding attributes:

public IGridConstructor<TModel> Attributes(Expression<Func<string, string>> expression)

So, I'm passing an Expression containing a Func<string, string>. The input parameter of the function is the name of the attribute while the output parameter is the value belonging to this attribute.

This does mean that the extression:

style => "width: 100%;"

Should render an attribute: style="width: 100%"

Now, I do have achieved that with the following code:

private void AddAttribute(Expression<Func<string, string>> expression)
{
    var propertyName = expression.Parameters[0].ToString();
    var propertyValue = expression.Compile()(string.Empty);

    GridAttributes.Add(propertyName, propertyValue);
}

Is this a correct approach to do so? I'm not happy with the [0] here.

Any help is highly appreciated.

Upvotes: 0

Views: 82

Answers (1)

DavidG
DavidG

Reputation: 119017

I would use an anonymous object, which would let you add multiple attributes rather than chaining your expressions.

private void AddAttributes(object attributes)
{
    foreach(var property in attributes.GetType().GetProperties())
    {
        GridAttributes.Add(
            property.Name, 
            property.GetValue(attributes));
    }
}

And call it like this:

AddAttributes(new { style = "width: 100%;", id = "renderedControl" });

Upvotes: 2

Related Questions