An der folgenden Methode bin ich heute ne Weile gesessen, daher ist sie einen Blogbeitrag wert 🙂
Mit diesem Beispiel ist es möglich einer Klasse ein custom Attribut zu geben und diesem Attribut via Typübergabe zu sagen wie gewisse Properties der Klasse befüllt werden sollen. Die Properties die befüllt werden sind via Interface beziehungsweise Basisklasse erzwungen/vorhanden.
Die Methode holt sich alle Klassen die eine Subklasse der Base Klasse „ClassWithAttributeBase“ (mit dem Interface IClassWithAttributeBase) und „FilterAttribute“ als Attribut/Annotation haben. Dann instanziert sie die SubKlasse und instanziert auch die mittels typeof als Parameter angegebenen Properties und weist diese der Klasse zu. Dann wird noch eine Methode auf der (Sub-)Klasse aufgerufen.
Das konkrete Anwendungsbeispiel ist eine generische Filterklasse dessen Datenquelle und angewendeter Filter via Attribut gesetzt werden kann.
Auflösung des Filter Attributes und Zuweisung zu den Properties der Klasse via Reflection
private void ResolveAtts() { var assembly = Assembly.GetExecutingAssembly(); foreach (Type type in assembly.GetTypes().Where(x=>x.IsSubclassOf(typeof(ClassWithAttributeBase)))) { //all classes inheriting from ClassWithAttributeBase var attributes = type.GetCustomAttributes(typeof(FilterAttribute), true); if (attributes.Any()) { foreach (FilterAttribute customAttribute in attributes.Where(x=>x is FilterAttribute)) { //instanciate generic class and assign datasource and filter as requested via attribute IClassWithAttributeBase instance = (IClassWithAttributeBase)Activator.CreateInstance(type); instance.DemoDataSource = (IDataSource)Activator.CreateInstance(customAttribute.DataSourceType); instance.Filter = (IFilter)Activator.CreateInstance(customAttribute.FilterType); instance.Filter.ApplyFilter(instance.DemoDataSource); //generic call of ApplyFilter from base class instance.Update(); //generic call of Update method from base class } } } }
Beispiel Verwendung einer spezialisierten Subklasse (Properies mittels typeof im Attribut befüllt)
[FilterAttribute(typeof(SpecialFilter1), typeof(SpecialDataSource1))] //IFilter will become SpecialFilter1 etc. public class SpecialClassWithAttribute : ClassWithAttributeBase { public SpecialClassWithAttribute() { //the DemoDataSource is in base class } public override void Update() { //here you can e.g. override the Update behaviour } }
Hier noch das verwendete Interface für die Basisklasse zum besseren Verständnis
namespace DemoClassLibrary.Interfaces { public interface IClassWithAttributeBase { IDataSource DemoDataSource { get; set; } IFilter Filter { get; set; } void Update(); } }
Schreibe einen Kommentar