15

As discussed here, C# doesn't support generic attribute declaration. So, I'm not allowed to do something like:

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

that would fit like a charm in my attribute impl class, cause I need to call a method from a generic repository:

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

I tried to use this solution without success. I can pass something like typeOf(User), but how can I call LoadById just with type or magic string?

*Both, T and User, extend a base class called Entity.

Community
  • 1
  • 1
Custodio
  • 8,594
  • 15
  • 80
  • 115

4 Answers4

17

You could use reflection to load by 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 });
    }
}
Bas
  • 26,772
  • 8
  • 53
  • 86
4

You have at least these three possibilities:

  1. You could use reflection to call LoadById
  2. You could create an expression tree that calls LoadById
  3. You could provide a LoadById method in your repository that is not generic.
Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
1

Since C# 11 there is no need for workarounds because generic attributes are supported:

public class AuditAttribute<T> : Attribute where T : Entity
{
   // ... 
}
halfer
  • 19,824
  • 17
  • 99
  • 186
Guru Stron
  • 102,774
  • 10
  • 95
  • 132
1

You could use reflection to invoke the LoadById method. The following msdn article should point you in the right direction:

http://msdn.microsoft.com/en-us/library/b8ytshk6(v=vs.100).aspx

Kev
  • 1,832
  • 1
  • 19
  • 24