Skip to content

Class ServerExtensionAttribute

Namespace: DotBoxD.Abstractions
Assembly: DotBoxD.Abstractions.dll

Marks a class as a server extension: a batch operation the plugin ships as verified IR and the server runs request/response in a single roundtrip, so a loop over many entities executes server-side (calling the host’s existing bindings) instead of one network call per entity. The generator lowers the class’s single public batch method — its body may use locals, a foreach over a list parameter, host bindings via ctx.Host<T>() or constructor-injected service fields, and may build and return complex objects (records/DTOs) and lists of them. For example:

[ServerExtension("monster-killer", typeof(IMonsterKillerService))]
public sealed partial class MonsterKillerKernel
{
    private readonly IGameWorld _world;
    public MonsterKillerKernel(IGameWorld world) => _world = world;

    public List<KillResult> KillMonsters(List<int> monsterIds, HookContext ctx)
    {
        var results = new List<KillResult>();
        foreach (var id in monsterIds)
            results.Add(new KillResult(id, _world.Kill(id)));
        return results;
    }
}
public readonly record struct KillResult(int MonsterId, bool Success);

The trailing DotBoxD.Abstractions.HookContext parameter is the lowering marker for host bindings (as in a kernel’s Handle) and is not part of the wire signature. Parameters, return type, and DTO fields must use supported scalar types, lists, or nested DTOs. Supplying the optional service interface type lets the analyzer emit a source-generated plugin-side client that marshals directly to compact server-extension value bytes instead of using a reflection proxy.

[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public sealed class ServerExtensionAttribute : Attribute

objectAttributeServerExtensionAttribute

Attribute.Equals(object?), Attribute.GetCustomAttribute(Assembly, Type), Attribute.GetCustomAttribute(Assembly, Type, bool), Attribute.GetCustomAttribute(MemberInfo, Type), Attribute.GetCustomAttribute(MemberInfo, Type, bool), Attribute.GetCustomAttribute(Module, Type), Attribute.GetCustomAttribute(Module, Type, bool), Attribute.GetCustomAttribute(ParameterInfo, Type), Attribute.GetCustomAttribute(ParameterInfo, Type, bool), Attribute.GetCustomAttributes(Assembly), Attribute.GetCustomAttributes(Assembly, bool), Attribute.GetCustomAttributes(Assembly, Type), Attribute.GetCustomAttributes(Assembly, Type, bool), Attribute.GetCustomAttributes(MemberInfo), Attribute.GetCustomAttributes(MemberInfo, bool), Attribute.GetCustomAttributes(MemberInfo, Type), Attribute.GetCustomAttributes(MemberInfo, Type, bool), Attribute.GetCustomAttributes(Module), Attribute.GetCustomAttributes(Module, bool), Attribute.GetCustomAttributes(Module, Type), Attribute.GetCustomAttributes(Module, Type, bool), Attribute.GetCustomAttributes(ParameterInfo), Attribute.GetCustomAttributes(ParameterInfo, bool), Attribute.GetCustomAttributes(ParameterInfo, Type), Attribute.GetCustomAttributes(ParameterInfo, Type, bool), Attribute.GetHashCode(), Attribute.IsDefaultAttribute(), Attribute.IsDefined(Assembly, Type), Attribute.IsDefined(Assembly, Type, bool), Attribute.IsDefined(MemberInfo, Type), Attribute.IsDefined(MemberInfo, Type, bool), Attribute.IsDefined(Module, Type), Attribute.IsDefined(Module, Type, bool), Attribute.IsDefined(ParameterInfo, Type), Attribute.IsDefined(ParameterInfo, Type, bool), Attribute.Match(object?), Attribute.TypeId, object.Equals(object?), object.Equals(object?, object?), object.GetHashCode(), object.GetType(), object.ReferenceEquals(object?, object?), object.ToString()

public ServerExtensionAttribute(string id)

id string

public ServerExtensionAttribute(string id, Type serviceType)

id string

serviceType Type

public ServerExtensionAttribute(Type grafts, string? id = null)

grafts Type

id string?

public Type? Grafts { get; }

Type?

public string? Id { get; }

string?

public Type? ServiceType { get; }

Type?