3
\$\begingroup\$

After several attempts to follow my intuition that this code can be refactored to something more DRY, I keep hitting road blocks.

Hoping someone can see a refactor that might get me going in a nicer direction.

I'm trying not to break anything out of this one code file, although, I suppose helper types could be placed in a top level code block if they help.

This razor view essentially presents all string string types in an arbitrarily complex type as a single form:

Member.cshtml

@model Tuple<object, Type, string>
@{
    var targetObj = Model.Item1;
    var targetType = Model.Item2;
    var path = Model.Item3;
}
<ul class="list-group" style="list-style-type: none">
    @foreach (var prop in
        from p in targetType.GetProperties()
        where p.Name != "SyncRoot"
        orderby p.Name
        select p)
    {
        var name = (path + "." + prop.Name).TrimStart('.');
        if (prop.PropertyType == typeof (string))
        {                    
            var value = "";
            if (targetObj != null)
            {
                var propValue = prop.GetValue(targetObj);
                if (propValue != null)
                {
                    value = propValue.ToString();
                }
            }
            <li class="list-group-item">
                <label>@prop.Name</label>
                <input class="form-control" value="@value" name="@name"/>
            </li>
        }
        else if (prop.PropertyType.IsArray && prop.PropertyType.GetElementType() == typeof (string))
        {
            var value = "";
            if (targetObj != null)
            {
                var propValue = prop.GetValue(targetObj) as string[];
                if (propValue != null)
                {
                    value = propValue[0];
                }
            }
            <li class="list-group-item">
                <label class="control-label col-md-2">@(prop.Name)[]</label>
                <input class="form-control" value="@value" name="@(name)[0]"/>
            </li>
        }
        else if (prop.PropertyType.IsArray)
        {
            object value = null;
            if (targetObj != null)
            {
                value = prop.GetValue(targetObj);
            }
            <li class="list-group-item">
                <fieldset>
                    <legend>@(prop.Name)[]</legend>
                    @Html.Partial("Member", Tuple.Create(value, prop.PropertyType.GetElementType(), name))
                </fieldset>
            </li>
        }
        else if (!prop.PropertyType.Name.StartsWith("System."))
        {
            object value = null;
            if (targetObj != null)
            {
                value = prop.GetValue(targetObj);
            }
            <li class="list-group-item">
                <fieldset>
                    <legend>@prop.Name</legend>
                    @Html.Partial("Member", Tuple.Create(value, prop.PropertyType, name))
                </fieldset>
            </li>
        }
    }
</ul>
\$\endgroup\$
0

1 Answer 1

3
\$\begingroup\$

Having a chain of if...elseif s it is a good place to start having a registry/resolver container instead.

Please take a look at my answer here.

After refactoring the code and removing the nested if....else s you will have all the logic and actions in one place to look at and you can refactor them in order to be DRY.

\$\endgroup\$

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .