2

Here's a sample of how it works now:

[MetadataType(typeof(PersonMetadata))]
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

public class PersonMetadata
{
    [Required]
    public string Name { get; set; }
    [Range(0,150]
    public int Age { get; set; }
}

However I don't want the MetadataAttribute to be put on the Person class, instead I want some way of telling the MVC framework "hey if you encounter Person class the metadate is in the PersonMetadata class".

It's just reversing the direction which for me feels more compositional and following the Open-Close Principle since I don't have to touch the Person class to "extend" it with metadata.
I know this creates a problem of possible multiple and conflicting metadatas being attached, also increases complexity but flexibility always comes at a price.

I want either a programmatic or declarative way or preferably both :)

So one could be something like :

MetadataTypeMappings.Add(typeof(Person), typeof(PersonMetadata));

Another could be:

[MetadataFor(typeof(Person)]
public class PersonMetadata
{
    [Required]
    public string Name { get; set; }
    [Range(0,150]
    public int Age { get; set; }
}
Piotr Owsiak
  • 6,081
  • 8
  • 39
  • 42
  • Good quetsion. I imagine you could also take a convention based approach. Probably a custom model binder is the way to go, but maybe someone else whose dealt with this before can fill in the details. – UpTheCreek Sep 28 '10 at 11:01

1 Answers1

3

I'm using MvcExtensions. One of the features is a nice way to describe metadata like this:

public class ProductEditModelConfiguration : 
  ModelMetadataConfiguration<ProductEditModel>
{
  public ProductEditModelConfiguration()
  {
    Configure(model => model.Id).Hide();
    Configure(model => model.Name)
      .DisplayName(() => LocalizedTexts.Name)
      .Required(() => LocalizedTexts.NameCannotBeBlank)
      .MaximumLength(64, () => 
        LocalizedTexts.NameCannotBeMoreThanSixtyFourCharacters);
  }
}

Neat thing is - this allows to use resources for localization in strongly typed fashion.

Drawback for using this - there's bunch of other things bundled which You might not want to use.

Arnis Lapsa
  • 45,880
  • 29
  • 115
  • 195
  • I gotta look at it and even if I don't use MvcExtensions directly I might find out how to do it myself. – Piotr Owsiak Sep 30 '10 at 15:53
  • @Piotr Those things are called custom model metadata providers. But I do think that it's quite an overhead to write them by Yourself. Quite tricky. But yeah, MvcExtensions would show You how to do that if You want to go that way: http://bit.ly/aIlaLh. And You might find useful this presentation: http://bit.ly/aFOMJH. – Arnis Lapsa Sep 30 '10 at 16:06
  • Thanks for your extensive answer, much appreciated :) – Piotr Owsiak Sep 30 '10 at 22:57