Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Workaround for C# generic attribute limitation

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.

like image 338
Custodio Avatar asked Mar 20 '12 14:03

Custodio


People also ask

Where can I practice C problems?

CodeChef discussion forum allows programmers to discuss solutions and problems regarding C Programming Tutorials and other programming issues.

What does return 0 do in C?

These status codes will be just used as a convention for a long time in C language because the language does not support the objects and classes, and exceptions. return 0: A return 0 means that the program will execute successfully and did what it was intended to do.


1 Answers

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 });
    }
}
like image 103
Bas Avatar answered Oct 02 '22 09:10

Bas