调用拦截——如何判断调用是否为系统调用

Call interception - How to determine wether a call is a system call

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

Outgoing grain call filters are invoked for all method calls to a grain and this includes calls to system methods made by Orleans.

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

我可以想到系统调用的两种解释:

  1. ISystemTarget
  2. 的任何调用
  3. 对在其中一个 Orleans 程序集中定义的接口的任何调用

在任何一种情况下,确定调用是否符合该标准的最简单方法是使用传递给调用过滤器的上下文的 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 ...
    }
})