title: MVC generic ViewModel
body: <p>In short I would like to be able to pass a generic ViewModel into my views</p>
  
  <p>Here is some simplified code of the gist of what I am trying to achieve</p>
  
  <pre><code>public interface IPerson
  {
      string FirstName {get;}
      string LastName {get;}
  }
  
  public class FakePerson : IPerson
  {
      public FakePerson()
      {
          FirstName = "Foo";
          LastName = "Bar";
      }
  
      public string FirstName {get; private set;} 
      public string LastName {get; private set;} 
  }
  
  public class HomeViewModel&lt;T&gt; 
      where T : IPerson, new()
  {
      public string SomeOtherProperty{ get; set;}
      public T Person { get; private set; }
  
      public HomeViewModel()
      {
          Person = new T();
      }
  }
  
  public class HomeController : Controller {
      public ViewResult Index() {
          return View(new HomeViewModel&lt;FakePerson&gt;());
      }
  }
  </code></pre>
  
  <p>If I create my view as follows all works as expected</p>
  
  <pre><code>&lt;%@ Page Language="C#" 
      MasterPageFile="~/Views/Shared/Site.Master"
      Inherits="System.Web.Mvc.ViewPage&lt;HomeViewModel&lt;FakePerson&gt;&gt;" %&gt;
  &lt;asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"&gt;
      &lt;%: Html.DisplayFor(m=&gt;m.Person.FirstName) %&gt;
      &lt;%: Html.DisplayFor(m=&gt;m.Person.LastName) %&gt;   
  &lt;/asp:Content&gt;
  </code></pre>
  
  <p>However I do not want to depend directly on FakePerson in the view in the event that I want to pass some other IPerson implementation, so I tried to change the page directive to </p>
  
  <pre><code>&lt;%@ Page Language="C#" 
      MasterPageFile="~/Views/Shared/Site.Master"
      Inherits="System.Web.Mvc.ViewPage&lt;HomeViewModel&lt;IPerson&gt;&gt;" %&gt;
  </code></pre>
  
  <p>But of course that does not work, so, after a whole day of mucking about, I have more grey hair and no clue what to do next.</p>
  
  <p>Can anybody help please.</p>
  
  <p>[UPDATE]</p>
  
  <p>Some advise has sugested that I should use a covariant interface; define a non-generic interface and use it in the View. Unfortuanetly I have tried this but there is one aditional implication. I would like the HtmlHelper function to be able to access any data annotation attributes that may be defined in the IPerson derived class</p>
  
  <pre><code> public class FakePerson : IPerson
   {
      public FakePerson()
      {
          FirstName = "Foo";
          LastName = "Bar";
      }
  
      [DisplayName("First Name")]
      public string FirstName {get; private set;}
  
      [DisplayName("Last Name")]
      public string LastName {get; private set;} 
  }
  </code></pre>
  
  <p>So while using a covariant interface this way does work, partly, to access the derived type through the ViewModel; since the view is typed to the interface, it appears the attributes are not accessible. </p>
  
  <p>Is there perhaps a way, in the view, to get access to these attributes, maybe with reflection.
  Or could there be anotherway to type the View to the generic.</p>