Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用反射调用DomainService.Load方法?_C#_Silverlight_Reflection_Ria - Fatal编程技术网

C# 如何使用反射调用DomainService.Load方法?

C# 如何使用反射调用DomainService.Load方法?,c#,silverlight,reflection,ria,C#,Silverlight,Reflection,Ria,我正在尝试构建一个实用方法,该方法将使用反射来加载entitycollections。其思想是,使用该实用程序的程序员可以指定任何类型的实体,该方法将发现正确的EntityQuery,并加载他们所请求的上下文。因此,我已经从用户那里收集了实体类型和Where子句,现在我试图找出如何调用该方法。以下是我所拥有的: public void Handle(LoadEntityQuery loadQuery, Action<LoadEntityQueryResult> reply) {

我正在尝试构建一个实用方法,该方法将使用反射来加载entitycollections。其思想是,使用该实用程序的程序员可以指定任何类型的实体,该方法将发现正确的EntityQuery,并加载他们所请求的上下文。因此,我已经从用户那里收集了实体类型和Where子句,现在我试图找出如何调用该方法。以下是我所拥有的:

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();
    }
} 
公共无效句柄(LoadEntityQuery loadQuery,操作回复)
{
foreach(loadQuery.Entities中的var条目)
{
Type entityType=entry.Key;
Type_contextType=EmployeeJobsContext.Instance.GetType();
MethodInfo _MethodInfo=(来自_contextType.GetMethods()中的x)
其中x.ReturnType.BaseType==typeof(EntityQuery)
从x.ReturnType.GetGenericArguments()中的y开始
其中y==entityType
选择x).FirstOrDefault();
如果(_methodInfo!=null)
{
var query=_methodInfo.Invoke(EmployeeJobsContext.Instance,null);
var_loadMethods=来自_contextType.GetMethods()中的x
其中x.Name==“加载”&&
x、 GetParameters()。长度==3
选择x;
MethodInfo\u loadMethod=null;
if(_loadMethods!=null)
{
foreach(加载方法中的MethodInfo项)
{
ParameterInfo[]_paramInfo=item.GetParameters();
if(_paramInfo[0].ParameterType.BaseType==typeof(EntityQuery)&&
_paramInfo[1]。ParameterType.IsGenericType&&
_paramInfo[1]。ParameterType.GetGenericArguments()。长度==1&&
_paramInfo[1]。ParameterType.GetGenericArguments()[0]。BaseType==typeof(LoadOperation)&&
_paramInfo[2]。ParameterType==typeof(对象))
{
_loadMethod=项目;
打破
}
}
}
MethodInfo_loadOpMethod=this.GetType().GetMethod(“LoadOperationResult”);
Delegate d=Delegate.CreateDelegate(typeof(LoadOpDel),\u loadOpMethod);
如果(_loadMethod!=null)
{
对象[]_参数=新对象[3];
_参数[0]=查询;
_参数[1]=d;
_params[2]=null;
_loadMethod=\u loadMethod.MakeGenericMethod(entityType);
_调用(_上下文,_参数);
}
}           
}
}
公共委托无效LoadOpDel(LoadOperation loadOp);
公共无效LoadOperationResult(LoadOperation loadOp)
{
if(loadOp.HasError==true)
{
//回复(新的LoadEntityQueryResult{Error=loadOp.Error.Message});
loadOp.MarkErrorAsHandled();
}
} 
foreach循环正在迭代Dictionary>>,其中键是实体类型,值是where子句。代码的第一部分是找到正确的EntityQuery方法并调用它以获得实际的查询。然后它会发现正确的加载重载(我知道,可能有更好的方法找到方法:)。这部分代码工作正常,我能够发现正确的EntityQuery和加载方法

对于LoadOperation,我想使用LoadOperationResult作为委托方法。但是,当我尝试运行此代码时,我收到一个异常,指出委托类型和方法类型签名不匹配。我非常确定我的签名是正确的,因为如果我直接调用Load并将函数名作为回调传递,那么这段代码将正常执行。我对反射式编程相当熟悉,但是在混合中使用泛型和动作回调在这一点上比我的水平略高。我不知道我做错了什么,有人能给我指点吗?我走远了吗?谢谢你的帮助!!
Jason

在不了解您正在使用的类的任何其他信息的情况下,我无法真正测试我的解决方案,但是当我将委托创建从for循环中取出时,我可以让它工作。我已将目标方法更改为静态:

public static void LoadOperationResult(LoadOperation loadOp)
委托的创建没有任何问题


比方说,我在这方面不是特别有能力,但我认为您希望创建一次委托,并在需要时简单地重复使用它。为什么要一次又一次地创建它?

即使
Action
LoadOpDel
具有相同的签名,但不能在它们之间进行隐式转换。在C#中,类型强制有时会使这看起来不真实,但如果使用反射类型强制显然不会发挥其神奇作用。

我发现我不需要使用反射来调用Load方法(不需要委托),而是通过创建基于实体类型的泛型方法来直接调用Load。以下是我为所有感兴趣的人提出的建议:

    /// <summary>
    /// The Action callback for the LoadEntityQuery handler. This callback is used to respond to the 
    /// LoadEntityQuery when all Load calls are complete. See the Handle method 
    /// </summary>
    private Action<LoadEntityQueryResult> _reply = null;

    /// <summary>
    /// Accumulator used to determine when the last entity has been loaded
    /// </summary>
    private int EntityCount { get; set; }

    /// <summary>
    /// Collective error container for Errors from the LoadOperation. This is value is returned via
    /// the _reply callback to the calling code.
    /// </summary>
    private List<Exception> Errors = null;

    public void Handle(LoadEntityQuery loadQuery, Action<LoadEntityQueryResult> reply)
    {
        _reply = reply;
        Errors = new List<Exception>();
        EntityCount = loadQuery.Entities.Count();

        MethodInfo _loadOpMethod = this.GetType().GetMethod("Load", BindingFlags.NonPublic | BindingFlags.Instance);
        int _entityCount = loadQuery.Entities.Count();

        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);
                MethodInfo _typedLoadOpMethod = _loadOpMethod.MakeGenericMethod(new Type[] { entityType });

                _typedLoadOpMethod.Invoke(this, new[] { query, entry.Value});
            }
        }
    }

    private void Load<T>(EntityQuery<T> query, Expression<Func<T, bool>> where) where T: Entity
    {
        if (where != null)
            query = query.Where(where);

        EmployeeJobsContext.Instance.Load(query, (loadOp) =>
            {
                EntityCount--;
                if (loadOp.HasError)
                {
                    Errors.Add(loadOp.Error);
                    loadOp.MarkErrorAsHandled();
                }

                if (EntityCount == 0)
                    _reply(new LoadEntityQueryResult { ErrorList = Errors });

            }, null);
    }
//
///LoadEntityQuery处理程序的操作回调。此回调用于响应
///所有加载调用完成时的LoadEntityQuery。参见Handle方法
/// 
私人行动_reply=null;
/// 
///累加器用于确定加载最后一个实体的时间
/// 
private int EntityCount{get;set;}
/// 
///LoadOperation错误的集合错误容器。这是通过返回的值
///对调用代码的_reply回调。
/// 
私有列表错误=null;
公共无效句柄(LoadEntityQuery loadQuery,操作回复)
{
_答复=答复;
错误=新列表();
EntityCount=loadQuery.Entities.Count();
MethodInfo _loadOpMethod=this.GetType().GetMethod(“加载”,BindingFlags.NonPublic |绑定