views:

787

answers:

2

I have a 4 layered web application programmed in C#... .Net 4.0:

  • UI Layer
  • Business Layer
  • Data access Layer
  • Entities layer

My data layer contains an edmx My entities layer contains my POCO objects (generated by a t4 script), and that layer is referenced in all other layers.

When creating an MVC form to create a new customer, for example.... I already have the customer class with fields for first name, last name, etc in my entities layer, but that auto-generated POCO class does not have data annotations for validation... I.E. [Required], etc. for when the form is submitted

My solution right now is to create new model classes that are pretty much the same as my poco classes but also have these additional validation annotations.

What I want to know is if theres an easy way to use certain POCO objects in the MVC model (in the UI layer) without having to almost rewrite the class... and also without modifying the t4 that generates these POCO classes (since I'm not up to speed on t4).

I saw this from another post on stackoverflow http://automapper.codeplex.com/ ... not sure if this will do it or is the best solution.

+2  A: 

Modifying a T4 template is not very hard at all. I recently faced the same issue and decided to read up on T4 a bit and then modify the template to create the generated properties the way I need them (annotations, and in my case with NotifyPropertyChange etc. as I use the same POCO objects in an MVC UI and in a Silverlight UI).

Even though you're looking for a solution that doesn't require modifying T4, I hope this is useful.

Eric J.
I'm all about learning new things... if thats a good solution then I'll learn it, but what I'm concerned about is if these annotations will affect other areas of the program that do not need them.
Chris Klepeis
@Chris: Annotations should not affect other parts of the program at all. They are just attributes (meta data attached to a class/method/etc) that the program can optionally read if it wants to. The only exception I can think of is if you target a limited runtime (e.g. the Silverlight CLR) that is missing some methods. In that case you can use `#if !SILVERLIGHT` to hide those attributes from Silverlight.
Eric J.
+2  A: 

If your POCO class is declared as such:

public class Person {
    public string FirstName { get; set; }
    public string LastName  { get; set; }
}

then if you just change the T4 to make it a partial class, you can then define in a separate file:

[MetadataType(typeof(PersonMetadata))]
public partial class Person {

    internal class PersonMetadata {

        [Required]
        // insert other metadata here
        public string FirstName { get; set; }

        // and if you don't want metadata for lastname, you can leave it out
    }
}

Two extra points - the metadata class doesn't have to be nested in the partial you define, I think it's neater though. Also, the types don't have to match in the metadata class, so you could make them all object if you wanted to (and you might see some examples on the web with it like this)

Jon
Do these partial classes have to go in my "Models" folder in the UI layer, or can I reference them from my Entities layer?
Chris Klepeis
@Chris: This is an elegant solution to adding custom metadata. If you need to affect the body of the method as I did, it would not work though (I had to add NotifyPropertyChange).
Eric J.