[.NET] Dynamisch toevoegen van een aantal class Attributes

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 27-09 13:36
In mijn (WPF) applicatie gebruik ik de Xceed Property Grid control die properties laat zien van een geselecteerd object. De properties kan ik in mijn code een Category geven (alsook naam en description etc).

C#:
1
2
3
4
5
6
7
8
9
10
11
public class SomeObject
{
    [Category("General")]
    public string Name {get;set;}
    
    [Category("Font")]
    public string FontName {get;set;}
    
    [Category("Font")]
    public int FontSize {get;set;}  
}


Ik wil deze Categories graag op een bepaalde manier rangschikken, en dat kan met een CategoryOrder attribute voor elke category, op de class geplaatst:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
[CategoryOrder("General", 1)]
[CategoryOrder("Font", 2)]
public class SomeObject
{
    [Category("General")]
    public string Name {get;set;}
    
    [Category("Font")]
    public string FontName {get;set;}
    
    [Category("Font")]
    public int FontSize {get;set;}  
}


Nu heb ik niet alleen maar een 'SomeObject' class, maar heb ik een hele waslijst van misschien wel 20 classes die allemaal in de property grid getoond kunnen worden. Het type properties is echter vaak vergelijkbaar en de Categories dus ook.

Dat betekend dus dat ik op elke class een hele waslijst met CategoryOrder attributes moet plaatsen. En als ik er ooit een toevoeg, of de volgorde wil veranderen, moet ik dat ook op elke class apart gaan doen (om het netjes consequent te houden).
C#:
1
2
3
4
5
6
7
[CategoryOrder("General", 1)]
[CategoryOrder("Font", 2)]
[CategoryOrder("Size", 3)]
[CategoryOrder("Layout", 4)]
[CategoryOrder("Background", 5)]
... etc ...
public class SomeObject



Ik vroeg me af of dit niet makkelijker kan, door bijvoorbeeld een custom attribute te maken die 'dynamisch' een lijst van CategoryOrder attributes toevoegt. Dan hoef ik op elke class alleen maar die ene custom attribute te gebruiken, en kan ik de volgorde op een plek aanpassen.
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[MyCategoryOrder]
public class SomeObject
{
    [Category("General")]
    public string Name {get;set;}
    
    [Category("Font")]
    public string FontName {get;set;}
    
    [Category("Font")]
    public int FontSize {get;set;}  
}

public class MyCategoryOrderAttribute : Attribute
{
    // ... ??
    // Injecteer een hele waslijst met 'CategoryOrder' attributes
}


Ik kom er echter niet achter of dit uberhaupt mogelijk is. Kan een attribute andere attributes "injecteren"? Waarschijnlijk zal dit niet tijdens runtime maar tijdens design time moeten gebeuren... Dus moet ik dan iets als PostSharp gebruiken wat tijdens design-time extra code kan genereren?

Heeft iemand hier ervaring mee?

Mijn iRacing profiel

Alle reacties


  • alwinuzz
  • Registratie: April 2008
  • Laatst online: 10-10 12:54
Je laatste codevoorbeeld kan volgens mij niet in .net. Je bent eigenlijk meer afhankelijk van de extension points in Xceed dan in het .net framework.

Wat nog zou kunnen werken is alle [CategoryOrder]s op een base class doen, en kijken of de attributes worden geinherit en of Xceed ze oppikt.

Daarna kijken hoe je het op kan lossen zonder attributes, zoals https://wpftoolkit.codepl...title=PropertyGrid%20Plus nummer 12

Als laatste gewoon 20x kopieren en plakken, zoveel werk is het nou ook weer niet :)

PostSharp gaat je denk ik veel tijd kosten als je het nog nooit gebruikt hebt. Is het een hobby project, go for it. Maar anders is het niet de moeite waard. Dan kan je nog beter iets met partial classes doen, voor elke class een extra bestand met daarin alleen de attributes op de partial class. En dit dan automatiseren met een powershell scriptje of T4.

  • jip_86
  • Registratie: Juli 2004
  • Laatst online: 17:11
Kan je geen basis klasse gebruiken voor al die objecten waar je dat op wilt zetten?

Acties:
  • 0 Henk 'm!

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 27-09 13:36
Een basis klasse is geen ideale optie, maar wel de beste op dit moment denk ik inderdaad. De classes zijn weer subclasses van een heel andere library en ik kan ze dus niet allemaal dezelfde base class geven, maar ik kan het aantal wel flink terugbrengen zo.

PostSharp heb ik heel klein beetje ervaring mee, er is een standaard plugin (ofzoiets) om INotifyPropertyChanged automatisch te laten implementeren. Maar het zal vast wat lastiger zijn om zelf iets vergelijkbaars te gaan bouwen...

Mijn iRacing profiel


Acties:
  • +2 Henk 'm!

  • Alex)
  • Registratie: Juni 2003
  • Laatst online: 21-08 11:20
Attributes zijn juist iets wat bij het compilen wordt meegenomen, dat is dus statisch.

Wat je in ieder geval kan doen: je order-property ophogen in tientallen. Als er dan eens eentje toegevoegd moet worden, kun je hem toevoegen met Order = 15, zonder dat je 20 andere dingen moet gaan updaten.

Daarnaast zou je kunnen kijken naar PostSharp (niet gratis) of Fody (gratis). Dit zijn tools die meedraaien tijdens het buildproces, en die aanpassingen kunnen doen in de IL-code die wordt gegenereerd. Zo kun je bijvoorbeeld automatisch INotifyPropertyChanged laten implementeren, al je String.Equals()-calls laten vervangen door eentje die de vergelijking case insensitive doet, en nog veel meer.

Je zou een plugin voor Fody kunnen schrijven die automatisch de attributen toevoegt zoals jij dat wilt.

We are shaping the future