Modification de l’atsortingbut de classe à l’exécution

Je ne sais pas s’il est possible que j’ai vu:
Changer le paramètre d’atsortingbut à l’exécution.
Mon cas est très similaire mais j’essaye de changer l’atsortingbut d’une classe dans Runtime:

[Category("Change me")] public class Classic { public ssortingng Name { get; set; } } 

Une des réponses était:

 Dim prop As PropertyDescriptor = TypeDescriptor .GetProperties(GetType(UserInfo))("Age") Dim att As CategoryAtsortingbute = DirectCast( prop.Atsortingbutes(GetType(CategoryAtsortingbute)), CategoryAtsortingbute) Dim cat As FieldInfo = att.GetType.GetField( "categoryValue", BindingFlags.NonPublic Or BindingFlags.Instance) cat.SetValue(att, "A better description") 

Passé à un format plus lisible, grâce à Marc Gravell:

 TypeDescriptor.AddAtsortingbutes(table, new Category{ Name = "Changed" }); 

Tout va bien lorsque vous utilisez TypeDescriptor, mais lorsque vous utilisez:

 var attrs = (Category[])typeof(Classic).GetCustomAtsortingbutes( typeof(Category), true); attrs[0].Name 

Name a le texte “Change me”.
Est-il possible de modifier cet atsortingbut au moment de l’exécution?

Modifier:
J’ai besoin de cela pour Linq2Sql dans le concepteur le code généré a le schéma de firebase database. Je souhaite utiliser le schéma par défaut de l’utilisateur sans utiliser de mappage XML ni modifier le code généré (la table est toujours en phase de développement et change fréquemment).

Le code du designer est:

 [global::System.Data.Linq.Mapping.TableAtsortingbute(Name="DbSchema.MyTable")] public partial class MyTable 

Je veux que l’atsortingbut soit:

 [TableAtsortingbute(Name="MyTable")] 

Maintenant, j’ai creusé dans le code Framework et je pense que linq2sql utilise:

 TableAtsortingbute[] attrs = (TableAtsortingbute[])typeof(MyTable) .GetCustomAtsortingbutes(typeof(TableAtsortingbute), true); 

Lorsque j’utilise TypeDescriptor pour modifier l’atsortingbut, la valeur n’est pas modifiée dans GetCustomAtsortingbutes.

    En évitant toute reflection, vous pouvez le faire via TypeDescriptor :

     using System; using System.ComponentModel; using System.Linq; [Category("nice")] class Foo { } static class Program { static void Main() { var ca = TypeDescriptor.GetAtsortingbutes(typeof(Foo)) .OfType().FirstOrDefault(); Console.WriteLine(ca.Category); // <=== nice TypeDescriptor.AddAttributes(typeof(Foo),new CategoryAttribute("naughty")); ca = TypeDescriptor.GetAttributes(typeof(Foo)) .OfType().FirstOrDefault(); Console.WriteLine(ca.Category); // <=== naughty } } 

    Si vous utilisez la reflection , ce n’est pas tout à fait comme cela – les atsortingbuts de reflection ne peuvent pas être remplacés – seule la vue composant-modèle est affectée par TypeDescriptor . Cependant, vous pouvez sous-classer CategoryAtsortingbute à vos objectives. Particulièrement utile pour i18n.

     using System.ComponentModel; using System; [MyCategory("Fred")] class Foo { } static class Program { static void Main() { var ca = (CategoryAtsortingbute)Atsortingbute.GetCustomAtsortingbute(typeof(Foo), typeof(CategoryAtsortingbute)); Console.WriteLine(ca.Category); // ^^^ writes "I was Fred, but not I'm EVIL Fred" } } class MyCategoryAtsortingbute : CategoryAtsortingbute { public MyCategoryAtsortingbute(ssortingng category) : base(category) { } protected override ssortingng GetLocalizedSsortingng(ssortingng value) { return "I was " + value + ", but not I'm EVIL " + value; } } 

    Vous devez coder votre atsortingbut pour qu’il prenne en charge les valeurs d’exécution. Par exemple, les atsortingbuts de validation prennent en charge l’internationalisation des messages en définissant un type de ressource et une chaîne de ressources, par opposition à la chaîne statique de Message.

    Une autre approche consiste à utiliser un conteneur IOC tel que StructureMap ou Unity pour fournir un object / service fournissant les valeurs.

    Si vous ne voulez pas coupler votre atsortingbut à un conteneur particulier, utilisez l’encapsuleur Common ServiceLocator fourni par le groupe Patterns and Practices.