首页 > 解决方案 > 呼叫拦截 - 如何确定呼叫是否为系统调用

问题描述

我正在尝试创建一个只处理非系统调用的拦截方法。根据文档,系统和非系统调用都被拦截:

对grain的所有方法调用都会调用传出grain调用过滤器,这包括对Orleans进行的系统方法的调用。

但是,我找不到使用任何公共方法或属性来区分的方法。我错过了什么吗?

标签: orleans

解决方案


对于系统调用的含义,我可以想到两种解释:

  1. 任何呼叫ISystemTarget
  2. 对在奥尔良程序集中定义的接口的任何调用

在任一情况下,确定调用是否符合该标准的最简单方法是使用InterfaceMethod传递给调用过滤器的上下文属性来DeclaringType检查MethodInfo.

例如:

siloBuilder.AddOutgoingGrainCallFilter(async context =>
{
    var declaringType = context.InterfaceMethod?.DeclaringType;

    // Check if the type being called belongs to one of the Orleans assemblies
    // systemAssemblies here is a HashSet<Assembly> containing the Orleans assemblies
    var isSystemAssembly = declaringType != null
      && systemAssemblies.Contains(declaringType.Assembly);

    // Check if the type is an ISystemTarget
    var systemTarget = declaringType != null
      && typeof(ISystemTarget).IsAssignableFrom(declaringType);

    if (isSystemAssembly || systemTarget)
    {
        // This is a system call, so just continue invocation without any further action
        await context.Invoke();
    }
    else
    {
        // This is an application call

        // ... Inspect/modify the arguments here ...

        await context.Invoke();

        // ... inspect/modify return value here ...
    }
})

推荐阅读