Skip to content

Replace resource IL proxy generation with Castle.DynamicProxy - #1448

Open
dbeuchler wants to merge 12 commits into
devfrom
rework/resource-proxy-builder
Open

Replace resource IL proxy generation with Castle.DynamicProxy#1448
dbeuchler wants to merge 12 commits into
devfrom
rework/resource-proxy-builder

Conversation

@dbeuchler

@dbeuchler dbeuchler commented Aug 20, 2026

Copy link
Copy Markdown
Member

The resource proxy used hand-written IL emit code to generate proxy types at runtime. Probs to @Toxantron 👏 for this masterpiece (I remember the Saturdays debugging IL stuff 💻). This has been running for several years without any problems, but it has some limitations:

Changes:

  • Replaced ResourceProxyBuilder (IL emit) with a Castle.DynamicProxy-based implementation
  • ResourceProxy serves as mixin providing IResource base members
  • ResourceInterceptor handles all call forwarding, events, and resource reference conversion
  • Proxy type caching is handled by Castle internally — removed the manual cache
  • Explicit interface events now work correctly
  • Generic methods on target are now fully supported
  • Updated docs

All existing proxy tests pass unchanged. Added new tests for explicit interface implementations, detach behavior and other missing features.

Performance:

  • The old IL proxies compiled down to direct method calls, so per-call overhead was essentially zero. Castle uses IInterceptor which adds indirection through reflection on each call.
  • Proxy type generation itself is not an issue — it happens once per resource type and Castle caches the types internally.
  • With the MORYX-Benchmarker I cannot identify any performance impact.
    • IL proxies — average: 176 activities/second; Castle proxies — average: 197 activities/second; so the proxy overhead is negligible here
  • With 6.5M ops/sec (on an M4 MacbookPro) the Castle proxy is still bloody fast — a single property access takes ~150 nanoseconds, which is irrelevant for any real resource interaction that involves I/O, network, or database.
  • On direct call benchmark (loop and measure) I can identify that the IL proxy was around 9x faster
  • Possible optimization: Replace MethodInfo.Invoke with compiled delegates (like in PropertyAccessor), but this could be a later improvement. I think we can save 5%-10%, therefore is more mini-optimization.

The maintainability gain and new features far outweighs the nanoseconds lost per invocation.

close #768 #343

@andreniggemann FYI (or sec review)

@dbeuchler dbeuchler added this to the Framework 10.x milestone Aug 20, 2026
@dbeuchler dbeuchler self-assigned this Aug 20, 2026
@dbeuchler dbeuchler added the enhancement New feature or request label Aug 20, 2026
@dbeuchler
dbeuchler force-pushed the rework/resource-proxy-builder branch from da3a239 to ca4efa3 Compare August 20, 2026 10:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ResourceProxy does not support explicitly implemented interfaces with events

1 participant