繁体   English   中英

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

[英]determine dynamically which static method to invoke

在我的域模型中,我有一个基础实体类,所有类都派生自该实体类。
我希望能够根据当前用户的权限动态创建过滤器。
例如-对于Employee类,我将定义一个雇员可以看到他自己和他的部门。
我的方法是这样的:

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

然后,在我的存储库基类中,我想动态确定类型并调用正确的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...
    }

到目前为止,我唯一的解决方案是许多if-else块,这非常难看。
有人有更好的主意吗?
谢谢
的Jhonny

尝试类似:

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

这使用反射在运行时查找方法。 如果太慢,则可能需要考虑将GetMethod的结果缓存在某个地方。 注意,该方法不限于静态方法。 用指向T类型对象的指针替换null,您也可以在普通实例方法上使用它。

有关更多信息,请参见MSDN文档中的反射类 您可以在Invoke文档中找到一个不错的示例。

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

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

真正的好解决方案,IMO只是在派生的存储库类中而不是在您的基本存储库中调用该方法。 这样就没有问题,因为派生类知道它在查询什么,因此EmployeesRepository将显式调用Employee.GetFilter。

暂无
暂无

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

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