Silky Microservice FrameworkSilky Microservice Framework
Home
Docs
Config
Source
github
gitee
  • 简体中文
  • English
Home
Docs
Config
Source
github
gitee
  • 简体中文
  • English
  • Startup

    • Silky Framework Source Code Analysis
    • Host Construction
    • Service Engine
    • Module System
    • Service & Service Entry Resolution
    • Service Registration
    • Dependency Injection Conventions
    • RPC Service Proxy
  • Runtime

    • Endpoints & Routing
    • Executor Dispatch System
    • Local Executor & Server-Side Filters
    • Remote Executor & RPC Call Chain
    • RPC Server Message Handling
    • Service Governance
    • Cache Interceptor
    • Distributed Transactions (TCC)
    • HTTP Gateway Pipeline
    • Filter Pipeline
    • Polly Resilience Pipeline
    • Endpoint Health Monitor

Overview

When a service entry is determined to execute locally (IsLocal = true), the framework uses ILocalExecutor to invoke the actual business method. Key characteristics:

  • A server-side filter pipeline runs before and after the business method call
  • Filters support both async and sync interfaces; the framework drives the pipeline through a state machine (similar to ASP.NET Core's ActionFilter mechanism)
  • Built-in filter types: authorization, action, exception, and result filters

DefaultLocalExecutor — Local Execution Entry

public class DefaultLocalExecutor : ILocalExecutor
{
    private readonly IServerLocalInvokerFactory _serverLocalInvokerFactory;

    public async Task<object> Execute(ServiceEntry serviceEntry, object[] parameters, string? serviceKey = null)
    {
        // 1. Resolve implementation instance by serviceKey (supports multi-impl routing)
        var instance = EngineContext.Current.ResolveServiceInstance(serviceKey, serviceEntry.ServiceType);

        // 2. Build ServiceEntryContext (wraps ServiceEntry, parameters, instance)
        // 3. Create LocalInvoker with filter chain from factory
        var localInvoker = _serverLocalInvokerFactory.CreateInvoker(
            new ServiceEntryContext(serviceEntry, parameters, serviceKey, instance));

        // 4. Run filter pipeline + business method
        await localInvoker.InvokeAsync().ConfigureAwait(false);

        // 5. Return result
        return localInvoker.Result;
    }
}

ServiceKey Multi-Implementation Routing

ResolveServiceInstance(serviceKey, serviceType) resolves the correct implementation from the IoC container based on serviceKey. When multiple implementations of the same interface exist (e.g., different tenant implementations), each is registered with a different [InjectNamed] key matching the ServiceKey.


ServiceEntryContext — Call Context

ServiceEntryContext is the "session" object that flows through the entire filter pipeline:

PropertyTypeDescription
ServiceEntryServiceEntryCurrent service entry metadata (routes, parameter descriptors, governance options)
Parametersobject[]Resolved parameter array (matching method signature order)
ServiceKeystring?Service key for this call (multi-impl routing)
InstanceobjectThe business implementation instance
ResultobjectReturn value after execution

IServiceEntryContextAccessor (backed by AsyncLocal<T>) allows filters and business code to access the current call context from anywhere in the call stack.


Server-Side Filter Types

1. Authorization Filters

public interface IAsyncServerAuthorizationFilter : IServerFilterMetadata
{
    Task OnAuthorizationAsync(ServerAuthorizationFilterContext context);
}
  • Execute first, before all Action filters
  • Setting context.Result to a non-null value short-circuits the entire pipeline
  • Built-in authorization filter validates [Authorize] and JWT claims

2. Action Filters (IServerFilter / IAsyncServerFilter)

public interface IAsyncServerFilter : IServerFilterMetadata
{
    Task OnActionExecutionAsync(ServerInvokeExecutingContext context, ServerExecutionDelegate next);
}
  • Execute before (OnActionExecuting) and after (OnActionExecuted) the business method
  • Can short-circuit by not calling next()
  • Use context.Exception in OnActionExecuted to inspect exceptions

3. Exception Filters

Catch unhandled exceptions from Action filters or the business method. Setting context.ExceptionHandled = true prevents the exception from propagating.

4. Result Filters

Execute before (OnResultExecuting) and after (OnResultExecuted) the result is written. Can modify or replace context.Result.

5. IAlwaysRunServerResultFilter

Always executes regardless of short-circuiting — useful for cleanup operations that must run.


Filter State Machine

The LocalInvoker drives execution through a state machine with these states:

ActionBegin
    │  → Run Authorization filters (can short-circuit)
    ▼
AuthorizationBegin
    │  → Run Action filters (OnActionExecuting)
    ▼
ActionInside
    │  → ObjectMethodExecutor invokes the business method
    ▼
ResultBegin
    │  → Run Result filters (OnResultExecuting → OnResultExecuted)
    ▼
InvokeEnd
    │  → Execution complete, result available in LocalInvoker.Result

On exception, the state machine switches to Exception filter execution before completing.


ObjectMethodExecutor

ObjectMethodExecutor uniformly handles all .NET method return types:

Return TypeHandling
voidExecutes synchronously, result is null
T (non-Task)Executes synchronously, wraps result
Taskawait task
Task<T>await task, extracts T
ValueTaskawait valueTask.AsTask()
ValueTask<T>await valueTask.AsTask(), extracts T

This ensures business methods can use any async return style without impacting the framework's execution pipeline.

Edit this page
Prev
Executor Dispatch System
Next
Remote Executor & RPC Call Chain