2012-03-20 12 views
14

Come discusso here, C# non supporta la dichiarazione di attributo generico. Quindi, io non sono autorizzato a fare qualcosa di simile:Soluzione temporanea per la limitazione di attributi generici C#

[Audit<User> (UserAction.Update)] 
public ActionResult SomeMethod(int id){ ... 

che si adatterebbe a meraviglia nel mio attributo di classe impl, perché ho bisogno di chiamare un metodo da un repository generico:

User fuuObj = (User) repository.LoadById<T>(_id); 

Ho provato a utilizzare la soluzione this senza successo. Posso passare qualcosa come typeOf(User), ma come posso chiamare LoadById solo con tipo o stringa magica?

* Sia, T che Utente, estendono una classe base chiamata Entità.

+1

si potrebbe scrivere attributi diversi per ogni tipo? –

+0

Hai bisogno di una classe specifica o Entity è abbastanza per lavorare? – Bas

+0

@Daniel, sì ... ma in realtà preferisco centrare tutto il processo uditivo ed evitare il massimo possibile codice futuro in questo contesto. – Custodio

risposta

16

Si potrebbe utilizzare la reflection per caricare da ID:

public class AuditAttribute : Attribute 
{ 
    public AuditAttribute(Type t) 
    { 
     this.Type = t; 
    } 

    public Type Type { get; set; } 

    public void DoSomething() 
    { 
     //type is not Entity 
     if (!typeof(Entity).IsAssignableFrom(Type)) 
      throw new Exception(); 

     int _id; 

     IRepository myRepository = new Repository(); 
     MethodInfo loadByIdMethod = myRepository.GetType().GetMethod("LoadById"); 
     MethodInfo methodWithTypeArgument = loadByIdMethod.MakeGenericMethod(this.Type); 
     Entity myEntity = (Entity)methodWithTypeArgument.Invoke(myRepository, new object[] { _id }); 
    } 
} 
4

avete almeno queste tre possibilità:

  1. Si potrebbe utilizzare la reflection per chiamare LoadById
  2. Si potrebbe creare un albero di espressione che chiama LoadById
  3. Si potrebbe fornire un metodo LoadById nel repository che non è generico
Problemi correlati