locked
Code First DataAnnotations in Interfaces RRS feed

  • Question

  • I'm building a code first object model and would like to describe some of my classes properties in interfaces.

    A good example is an IAuditable interface, where classes implementing this are forced to have timestamps and a user name added to their signature.

     public interface IAuditable {
    
       DateTime CreatedOn { get; set; }
    
       [MaxLength(9)]
       string CreatedByName { get; set; }
     }
    
    

    Currently, any data annotations placed on these interface properties are ignored... is there any scope for adding support for this?

    It seems that the structure of a db can be described in part for theses types of thing, ie you can enforce it to be a string but not how long it is.

    It would also be good for reuse of validation, or at least default validation which could be overridden by the concrete class


    Ant
    Sunday, January 16, 2011 1:09 PM

Answers

  • The product team does not want to implement this feature, for two main reasons:

    • Consistency with DataAnnotations.Validator

    • Consistency with validation behavior in ASP.Net MVC

    • tricky scenario: a class implements two interfaces that have the same property, but with conflicting attributes on them. Which attribute would take precedence?

    Does the previous suggestion about making IAuditable an abstract class work for you?

    • Proposed as answer by Rick Saling Thursday, January 20, 2011 8:56 PM
    • Marked as answer by Anthony Johnston Thursday, January 20, 2011 10:14 PM
    Thursday, January 20, 2011 8:54 PM

All replies

  • Just to be clear about your scenario, what I hear you saying is that you want to specify the attribute on the property in the interface, but not on the corresponding property in the class the implements the interface. Is that correct?

    So an example of what you want might be a class like this:

        public class Category : IAuditable
        {
            public int CategoryId { get; set; }
            public string Name { get; set; }

            public DateTime CreatedOn { get; set; }

            public string CreatedByName { get; set; }

            public virtual ICollection<Product> Products { get { return _products; } }
            private readonly ICollection<Product> _products = new BindingList<Product>();
        }

     

    Tuesday, January 18, 2011 11:26 PM
  • Yes, all implementers of IAuditable would pick up the Annotation on CreatedByName unless overridden by the class,

    and tables created would have a column length of 9 - or what ever


    Ant
    Wednesday, January 19, 2011 8:43 AM
  • I'm checking with the product team about this feature, "if" and "when" it might be implemented.

    However, would this be an adequate work-around for you? Define IAuditable as an abstract class, so that you could use inheritance instead of implementing an interface.

    Thursday, January 20, 2011 6:40 PM
  • The product team does not want to implement this feature, for two main reasons:

    • Consistency with DataAnnotations.Validator

    • Consistency with validation behavior in ASP.Net MVC

    • tricky scenario: a class implements two interfaces that have the same property, but with conflicting attributes on them. Which attribute would take precedence?

    Does the previous suggestion about making IAuditable an abstract class work for you?

    • Proposed as answer by Rick Saling Thursday, January 20, 2011 8:56 PM
    • Marked as answer by Anthony Johnston Thursday, January 20, 2011 10:14 PM
    Thursday, January 20, 2011 8:54 PM
  • Hi Rick,

    OK then, sadly came up with the same issues, didn't want to influence the outcome..

    The following is not intended as an argument against what you say just food for thought

    • Consistency with DataAnnotations.Validator

    • Consistency with validation behavior in ASP.Net MVC

      Perhaps the annotations in this case are to do with the building of a data structure, which would back a number of applications, some would have different requirements for validation anyway, so long as they stick to the data storage requirements - take a string length as an example, the Interface would describe the physical availability but a Model Validator may have different requirements which are governed by the application or even a preference of the client, where the data would be replicated to an older system with different storage restraints. I think there would be a case for a new set off attributes which do this rather than using the validation ones.


    • tricky scenario: a class implements two interfaces that have the same property, but with conflicting attributes on them. Which attribute would take precedence?

      this is the difficult one, but you could, raise an error at runtime for this being the case and tell developer to override (on implementing base or concrete class) or remove one of the attributes, there is plenty of precedence when using attributes for such a thing, especially in MVC (I'm not whispering here.. the editor has gone kookie)

    With regard to base classes instead, yes I suppose, but I was hoping to leave this POCO, so an implementer could do their own thing with regard to a base class.

    Anyhoo, thanks for your consideration of this request and bringing it to the team.

     


    Ant
    Thursday, January 20, 2011 10:34 PM
  • Thanks for the feedback! I've passed it on to the product team.
    Thursday, January 20, 2011 10:46 PM