title: Strongly Typed Generic Attribute alternatives
body: <p>Lets start with a simple view model:</p>
  
  <pre><code>public class MyViewModel
  {
    public string Value { get; set; }
    public IEnumerable&lt;SelectListItem&gt; Values { get; set; }
  }
  </code></pre>
  
  <p>A drop down list might look like:</p>
  
  <pre><code>@Html.DropDownListFor(m =&gt; m.Value, Model.Values)
  </code></pre>
  
  <p>However, because a drop down list requires two values it can't be used like:</p>
  
  <pre><code>public class MyViewModel
  {
    [UIHint("DropDownList")]
    public string Value { get; set; }
    public IEnumerable&lt;SelectListItem&gt; Values { get; set; }
  }
  </code></pre>
  
  <p>with a view containing:</p>
  
  <pre><code>@Html.EditForModel()
  </code></pre>
  
  <p>Because there is no inherent way for the drop down to know the source, until you derrive from UIHint:</p>
  
  <pre><code>public DropDownListAttribute : UIHintAttribute
  {
    public DropDownListAttribute (string valuesSource)
      : base("DropDownList", "MVC")
    {
    }
  }
  </code></pre>
  
  <p>Then one might use it like:</p>
  
  <pre><code>public class MyViewModel
  {
    [DropDownList("Planets")]
    public string PlanetId{ get; set; }
    public IEnumerable&lt;SelectListItem&gt; Planets { get; set; }
  
    [DropDownList("Cars")]
    public string CarId{ get; set; }
    public IEnumerable&lt;SelectListItem&gt; Cars { get; set; }
  }
  </code></pre>
  
  <p>However, this isn't really strongly typed, someone renames one of the <a href="http://en.wikipedia.org/wiki/Magic_number_(programming)#Unnamed_numerical_constants" rel="nofollow noreferrer">magic strings</a> or propery names without changing the other and it breaks at run-time.</p>
  
  <p>One theoretical solution is to create a generic attribute:</p>
  
  <pre><code>public DropDownListAttribute&lt;TModel, TValue&gt; : UIHintAttribute
  {
    public DropDownListAttribute (Expression&lt;Func&lt;TModel, TValue&gt; expression)
      : base("DropDownList", "MVC")
    {
    }
  }
  </code></pre>
  
  <p>and the usage would be:</p>
  
  <pre><code>public class MyViewModel
  {
    [DropDownList&lt;MyViewModel, IEnumerable&lt;SelectListItem&gt;&gt;( m =&gt; m.Planets)]
    public string PlanetId{ get; set; }
    public IEnumerable&lt;SelectListItem&gt; Planets { get; set; }
  }
  </code></pre>
  
  <p><a href="https://stackoverflow.com/questions/294216/why-does-c-sharp-forbid-generic-attribute-types">But (currently) Generic Attributes aren't allowed</a> :/</p>
  
  <p>Another option is to encapsulate the two into a single class that the ModelBinder can recreate on post-back:</p>
  
  <pre><code>public class DropDownListTemplate
  {
    public string SelectedValue { get; set; }
    public IEnumerable&lt;SelectListItem&gt; Values { get; set; }
  }
  
  public class MyViewModel
  {
    public DropDownListTemplate Planet { get; set; }
  }
  </code></pre>
  
  <p>This creates simplicity in the ViewModel, Binding and EditFor/DisplayFor templates but from my limited knowledge of AutoMapper it adds complexity when <a href="https://stackoverflow.com/questions/8944577/automapper-map-child-property-that-also-has-a-map-defined">AutoMapper Mapping to Properties of Class Properties</a>.  As far as I know I can't simply:</p>
  
  <pre><code>public class MyPlanets
  {
    public string SelectedPlanet { get; set; }
  }
  
  Mapper.CreateMap&lt;MyPlanets, MyViewModel&gt;();
  Mapper.CreateMap&lt;MyViewModel, MyPlanets&gt;();
  </code></pre>
  
  <p>Is there an easier way with automapper to map these values auto-magically or is there a way to create a strongly-typed non-generic attribute?</p>