2012-03-20 7 views
14

Como se indica en here, C# no admite la declaración de atributo genérico. Por lo tanto, no se me permite hacer algo como:Solución alternativa para la limitación de atributo genérico de C#

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

que encajaría como un encanto en mi clase impl atributo, porque necesito llamar a un método de un repositorio genérico:

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

Intenté usar la solución this sin éxito. Puedo pasar algo como typeOf(User), pero ¿cómo puedo llamar al LoadById solo con el tipo o cadena mágica?

* Ambos, T y Usuario, extienden una clase base llamada Entidad.

+1

podría escribir diferentes atributos para cada tipo? –

+0

¿Necesita una clase específica o es suficiente Entidad para trabajar? – Bas

+0

@Daniel, sí ... pero en realidad prefiero centrar todo el proceso auditivo y evitar el máximo código posible en el futuro en este contexto. – Custodio

Respuesta

16

Se podría utilizar la reflexión para cargar por 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

de tener al menos estas tres posibilidades:

  1. Se podría utilizar la reflexión para llamar LoadById
  2. Se puede crear un árbol de expresión que llama LoadById
  3. Se podría proporcionar un método LoadById en su repositorio que no es genérico
Cuestiones relacionadas