Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I add my attributes to Code-Generated Linq2Sql classes properties?

Tags:

I would like to add attributes to Linq 2 Sql classes properties. Such as this Column is browsable in the UI or ReadOnly in the UI and so far.

I've thought about using templates, anybody knows how to use it? or something different?

Generally speaking, would do you do to address this issue with classes being code-generated?

like image 262
ArielBH Avatar asked Dec 26 '08 11:12

ArielBH


2 Answers

You can take advantage of the new Metadata functionality in the System.ComponentModel.DataAnnotations which will allow us to separate the MetaData from the existing domain model.

For example:

[MetadataType (typeof (BookingMetadata))] public partial class Booking {  // This is your custom partial class      }  public class BookingMetadata {  [Required] [StringLength(15)]  public object ClientName { get; set; }   [Range(1, 20)]  public object NumberOfGuests { get; set; }   [Required] [DataType(DataType.Date)]  public object ArrivalDate { get; set; } } 
like image 100
Jason Wicker Avatar answered Oct 22 '22 09:10

Jason Wicker


As requested, here's an approach using a CustomTypeDescriptor to edit the attributes at run-time; the example here is win-forms, but it should be pretty simple to swap it into WPF to see if it works...

using System; using System.Collections.Generic; using System.ComponentModel; using System.Windows.Forms; // example POCO class Foo {     static Foo()     {   // initializes the custom provider (the attribute-based approach doesn't allow         // access to the original provider)         TypeDescriptionProvider basic = TypeDescriptor.GetProvider(typeof(Foo));         FooTypeDescriptionProvider custom = new FooTypeDescriptionProvider(basic);         TypeDescriptor.AddProvider(custom, typeof(Foo));     }     public string Name { get; set; }     public DateTime DateOfBirth { get; set; } } // example form static class Program {     [STAThread]     static void Main() {         Application.EnableVisualStyles();         Application.Run( new Form {                 Controls = {                     new DataGridView {                         Dock = DockStyle.Fill,                         DataSource = new BindingList<Foo> {                             new Foo { Name = "Fred", DateOfBirth = DateTime.Today.AddYears(-20) }                         }                     }                 }             });     } }  class FooTypeDescriptionProvider : TypeDescriptionProvider {     ICustomTypeDescriptor descriptor;     public FooTypeDescriptionProvider(TypeDescriptionProvider parent) : base(parent) { }     public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)     {   // swap regular descriptor for bespoke (Foo) descriptor         if (descriptor == null)         {             ICustomTypeDescriptor desc = base.GetTypeDescriptor(typeof(Foo), null);             descriptor = new FooTypeDescriptor(desc);         }         return descriptor;     } } class FooTypeDescriptor : CustomTypeDescriptor {     internal FooTypeDescriptor(ICustomTypeDescriptor parent) : base(parent) { }     public override PropertyDescriptorCollection GetProperties()     {   // wrap the properties         return Wrap(base.GetProperties());     }     public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)     {   // wrap the properties         return Wrap(base.GetProperties(attributes));     }      static PropertyDescriptorCollection Wrap(PropertyDescriptorCollection properties)     {         // here's where we have an opportunity to swap/add/remove properties         // at runtime; we'll swap them for pass-thru properties with         // edited atttibutes         List<PropertyDescriptor> list = new List<PropertyDescriptor>(properties.Count);         foreach (PropertyDescriptor prop in properties)         {             // add custom attributes here...             string displayName = prop.DisplayName;             if (string.IsNullOrEmpty(displayName)) displayName = prop.Name;              list.Add(new ChainedPropertyDescriptor(prop, new DisplayNameAttribute("Foo:" + displayName)));         }         return new PropertyDescriptorCollection(list.ToArray(), true);     } }   class ChainedPropertyDescriptor : PropertyDescriptor {     // this passes all requests through to the underlying (parent)     // descriptor, but has custom attributes etc;     // we could also override properties here...     private readonly PropertyDescriptor parent;     public ChainedPropertyDescriptor(PropertyDescriptor parent, params Attribute[] attributes)         : base(parent, attributes)     {         this.parent = parent;     }     public override bool ShouldSerializeValue(object component) { return parent.ShouldSerializeValue(component); }     public override void SetValue(object component, object value) { parent.SetValue(component, value); }     public override object GetValue(object component) { return parent.GetValue(component); }     public override void ResetValue(object component) { parent.ResetValue(component); }     public override Type PropertyType {get { return parent.PropertyType; } }     public override bool IsReadOnly { get { return parent.IsReadOnly; } }     public override bool CanResetValue(object component) {return parent.CanResetValue(component);}     public override Type ComponentType { get { return parent.ComponentType; } }     public override void AddValueChanged(object component, EventHandler handler) {parent.AddValueChanged(component, handler);  }     public override void RemoveValueChanged(object component, EventHandler handler) { parent.RemoveValueChanged(component, handler); }     public override bool SupportsChangeEvents { get { return parent.SupportsChangeEvents; } } } 
like image 24
Marc Gravell Avatar answered Oct 22 '22 09:10

Marc Gravell