2012-03-20 11 views
14

Jak omówiono here, C# nie obsługuje ogólnej deklaracji atrybutu. Więc nie wolno mi zrobić coś takiego:Obejście ograniczania atrybutów ogólnych C#

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

że będzie pasował jak czar w moim atrybutu klasy IMPL, bo trzeba wywołać metodę z rodzajowe repozytorium:

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

Próbowałem użyć rozwiązania this bez powodzenia. Mogę przekazać coś w stylu: typeOf(User), ale jak mogę zadzwonić pod numer LoadById tylko za pomocą typu lub magicznego ciągu?

* Zarówno T, jak i Użytkownik rozszerzają klasę podstawową o nazwie Entity.

+1

można napisać różne atrybuty dla każdego rodzaju? –

+0

Czy potrzebujesz określonej klasy, czy też wystarczy Ci Jednostka? – Bas

+0

@Daniel, tak ... ale ja wolę centralnie wszystkie procesy dźwiękowe i unikać maksymalnego możliwego przyszłego kodu w tym kontekście. – Custodio

Odpowiedz

16

Można użyć refleksji do załadowania przez 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

mieć co najmniej te trzy możliwości:

  1. można użyć refleksji zadzwonić LoadById
  2. Można utworzyć drzewa wyrażenie, które wywołuje LoadById
  3. Można zapewnić LoadById metodę w swoim repozytorium nie jest generyczny.
Powiązane problemy