簡體   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