我正在嘗試構建一個實用方法,它將使用反射一般地加載實體集合。這個想法是,使用該實用程序的程序員可以指定任何類型的實體,並且此方法將發現正確的EntityQuery,並根據他們請求的內容加載上下文。所以,我從用戶那裏收集了Entity類型和Where子句,現在我正試圖弄清楚如何調用該方法。以下是我有:如何使用反射來調用DomainService.Load方法?
public void Handle(LoadEntityQuery loadQuery, Action<LoadEntityQueryResult> reply)
{
foreach (var entry in loadQuery.Entities)
{
Type entityType = entry.Key;
Type _contextType = EmployeeJobsContext.Instance.GetType();
MethodInfo _methodInfo = (from x in _contextType.GetMethods()
where x.ReturnType.BaseType == typeof(EntityQuery)
from y in x.ReturnType.GetGenericArguments()
where y == entityType
select x).FirstOrDefault();
if (_methodInfo != null)
{
var query = _methodInfo.Invoke(EmployeeJobsContext.Instance, null);
var _loadMethods = from x in _contextType.GetMethods()
where x.Name == "Load" &&
x.GetParameters().Length == 3
select x;
MethodInfo _loadMethod = null;
if (_loadMethods != null)
{
foreach (MethodInfo item in _loadMethods)
{
ParameterInfo[] _paramInfo = item.GetParameters();
if (_paramInfo[0].ParameterType.BaseType == typeof(EntityQuery) &&
_paramInfo[1].ParameterType.IsGenericType &&
_paramInfo[1].ParameterType.GetGenericArguments().Length == 1 &&
_paramInfo[1].ParameterType.GetGenericArguments()[0].BaseType == typeof(LoadOperation) &&
_paramInfo[2].ParameterType == typeof(object))
{
_loadMethod = item;
break;
}
}
}
MethodInfo _loadOpMethod = this.GetType().GetMethod("LoadOperationResult");
Delegate d = Delegate.CreateDelegate(typeof(LoadOpDel), _loadOpMethod);
if (_loadMethod != null)
{
object [] _params = new object[3];
_params[0] = query;
_params[1] = d;
_params[2] = null;
_loadMethod = _loadMethod.MakeGenericMethod(entityType);
_loadMethod.Invoke(_context, _params);
}
}
}
}
public delegate void LoadOpDel(LoadOperation loadOp);
public void LoadOperationResult (LoadOperation loadOp)
{
if (loadOp.HasError == true)
{
//reply(new LoadEntityQueryResult { Error = loadOp.Error.Message });
loadOp.MarkErrorAsHandled();
}
}
foreach循環迭代是一個字典>>,其中關鍵是實體類型和值是Where子句。代碼的第一部分是找到正確的EntityQuery方法並調用它來獲取實際查詢。然後它發現正確的負載超載(我知道,可能有更好的方法來找到方法:))這部分的代碼工作正常,我能夠發現正確的EntityQuery和Load方法。
對於LoadOperation,我想使用LoadOperationResult作爲我的委託方法。但是,當我嘗試運行此代碼時,我收到一個異常,指出委託類型和方法類型簽名不匹配。我很確定我的簽名是正確的,因爲如果我要直接調用Load並正常傳遞函數名稱作爲回調,則此代碼將正確執行。我對反射式編程非常熟悉,但是將泛型和動作回調投入到混合中,在這一點上略高於我的水平。我不知道我做錯了什麼,有沒有人對我有任何指點?我離開嗎?謝謝你的幫助!! Jason
所以'_loadMethod.Invoke(_context,_params);'引發異常或者當你創建委託?我也可能會對此產生困惑,但是你不想在循環之外創建委託嗎? – 2011-05-25 01:28:44
對不起,我沒有具體說明何時發生。當我創建委託時,我得到異常。另外,我需要在循環中創建委託,因爲集合中的每個實體都會調用加載操作。 – Rockdocta 2011-05-25 02:07:18