2016-08-08 61 views
0

Für Kartierungszwecke weitergeben Ich möchte einen Func<> in Attribut Konstruktor übergeben, so dass so etwas wie dies wäre möglich geworden:C# - Bibliothek Lambda in Attribut (aspect) Konstruktor

[Map<Foo>(foo=>foo.Name)] 
public string Name { get; set; } 

I erkennen, dass Attribute müssen kompilierungszeitkonstante sein, also wäre es unmöglich, dies mit reinem C# zu tun.

Ich frage mich, ob eine PostSharp-ähnliche Bibliothek existiert, etwas ähnliches zu tun (nach this post Ich denke, es gibt Möglichkeiten, dies in reinem IL zu implementieren).

Antwort

1

Kein Weg. Sie möchten zwei Dinge, die derzeit Attribute in C# nicht unterstützt:

  • Generische Typ Parameter.
  • Nicht konstante Argumente.
  • Denken Sie, dass Attribute nur Metadaten sind, Sie können nicht erwarten, während ihrer Verwendung nichts auszuführen (offensichtlich kann der Attributkonstruktor den Code ausführen, den Sie ihm hinzufügen).

    Während die anderen Q & A Sie verknüpft haben erwähnt, dass IL emittierende direkt sollten Sie in der Lage sein, es zu tun, ich bin auch ziemlich sicher, dass Sie eine fließend API vermeiden können, die Komplexität zu Ihrem Projekt hinzufügen Umsetzung:

    public class A : IMappingConfigurator 
    { 
        public string Name { get; set; } 
    
        public void Configure(IMappingConfiguration config) 
        { 
          config.Map<Foo>(foo => foo.Name); 
        } 
    } 
    

    und während der Konfigurationsphase können Sie alle Arten der Umsetzung der gesamten Schnittstelle erhalten und instanziiert sie nur, um die Konfiguration eines jeden:

    IEnumerable<IMappingConfigurator> configurators = Assembly.GetExecutingAssembly().GetTypes().Where 
    (
        t => t.GetInterfaces().Any(t => t == typeof(IMappingConfigurator)) 
    ).Select(t => (IMappingConfigurator)Activator.CreateInstance(t));