简体   繁体   English

动态确定要调用的静态方法

[英]determine dynamically which static method to invoke

In my domain model, I have a base entity class from which all classes derive. 在我的域模型中,我有一个基础实体类,所有类都派生自该实体类。
I'd like to be able to create filters dynamically based on current user's permissions. 我希望能够根据当前用户的权限动态创建过滤器。
For example- For the Employee class, I would define that an employee can see himself, and his department. 例如-对于Employee类,我将定义一个雇员可以看到他自己和他的部门。
My method would go something like this: 我的方法是这样的:

 public static IQueryable<Employee> CreateLinqFilter(IQueryable<Employee> query, User user)
    {
        return query.Where(e => e.Id == user.Id || e.Department.Manager.Id == user.Id);
    }

and then, in my repository base class, I'd like to determine the type dynamically and call the correct CreateLinqFilter method: 然后,在我的存储库基类中,我想动态确定类型并调用正确的CreateLinqFilter方法:

protected IQueryable CreateLinq<T>(User user)
    {
        var query = Session.Linq<T>();
        Type t = typeof(T);
        //if not an entity- do not perform filter
        if (!t.IsAssignableFrom(typeof(Entity)))
        {
            return query;
        }
        //now we know that T is a sub-class of Entity. 
        return CreateLinqFilter<T>(query,user);
    }

protected IQueryable CreateLinqFilter<T>(IQueryable<T> query, User user)
        //the following line won't compile:
        //where T: Entity
    {
        //i'd like to be able to do:
        //T.CreateFilter(query);

        //instead, I have to do this?
        if (typeof(T) == Employee)
        {
            return Employee.CreateLinqFilter(query,user);
        }
        if (typeof(T) == Department)
        {
            return Department.CreateLinqFilter(query,user);
        }
        //etc...
    }

The only solution I've got so far is lots of if-else blocks, which are quite unsightly. 到目前为止,我唯一的解决方案是许多if-else块,这非常难看。
anyone got a better idea? 有人有更好的主意吗?
thanks 谢谢
Jhonny 的Jhonny

Try something like: 尝试类似:

return (IQueryable)typeof(T).GetMethod("CreateLinqFilter").Invoke(null, new object[]{query, user});

This uses reflection to find the method at runtime; 这使用反射在运行时查找方法。 if this is too slow you may want to consider caching the result of GetMethod somewhere. 如果太慢,则可能需要考虑将GetMethod的结果缓存在某个地方。 Note that this method is not restricted to static method; 注意,该方法不限于静态方法。 replace the null with a pointer to an object of type T and you can use it on normal instance methods as well. 用指向T类型对象的指针替换null,您也可以在普通实例方法上使用它。

For more information, consult the MSDN documentation for the reflection classes ; 有关更多信息,请参见MSDN文档中的反射类 you can find a nice example in the documentation for Invoke . 您可以在Invoke文档中找到一个不错的示例。

在c#4.0中,您可以使用动态a = T t,否则,也许只能使用第一个答案

好吧,首先,不要使用很多if..else块,而要使用开关。

The really good solution, IMO is simply calling the method in the derived repository class and not in your base repository. 真正的好解决方案,IMO只是在派生的存储库类中而不是在您的基本存储库中调用该方法。 Then you have no problem because the derived class knows what it is querying, so EmployeesRepository will explicitly call Employee.GetFilter. 这样就没有问题,因为派生类知道它在查询什么,因此EmployeesRepository将显式调用Employee.GetFilter。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM